@@ -1136,20 +1136,6 @@ typedef struct { | |||||
*/ | */ | ||||
uint8_t midiChannel; | uint8_t midiChannel; | ||||
#ifdef __cplusplus | |||||
/*! | |||||
* Clear data. | |||||
*/ | |||||
void clear() noexcept | |||||
{ | |||||
type = PARAMETER_UNKNOWN; | |||||
hints = 0x0; | |||||
index = PARAMETER_NULL; | |||||
rindex = -1; | |||||
midiCC =-1; | |||||
midiChannel = 0; | |||||
} | |||||
#endif | |||||
} ParameterData; | } ParameterData; | ||||
/*! | /*! | ||||
@@ -1187,19 +1173,6 @@ typedef struct { | |||||
float stepLarge; | float stepLarge; | ||||
#ifdef __cplusplus | #ifdef __cplusplus | ||||
/*! | |||||
* Clear data. | |||||
*/ | |||||
void clear() noexcept | |||||
{ | |||||
def = 0.0f; | |||||
min = 0.0f; | |||||
max = 1.0f; | |||||
step = 0.01f; | |||||
stepSmall = 0.0001f; | |||||
stepLarge = 0.1f; | |||||
} | |||||
/*! | /*! | ||||
* Fix default value within range. | * Fix default value within range. | ||||
*/ | */ | ||||
@@ -1294,17 +1267,6 @@ typedef struct { | |||||
*/ | */ | ||||
const char* name; | const char* name; | ||||
#ifdef __cplusplus | |||||
/*! | |||||
* Clear data. | |||||
*/ | |||||
void clear() noexcept | |||||
{ | |||||
bank = 0; | |||||
program = 0; | |||||
name = nullptr; | |||||
} | |||||
#endif | |||||
} MidiProgramData; | } MidiProgramData; | ||||
/*! | /*! | ||||
@@ -1328,17 +1290,6 @@ typedef struct { | |||||
*/ | */ | ||||
const char* value; | const char* value; | ||||
#ifdef __cplusplus | |||||
/*! | |||||
* Clear data. | |||||
*/ | |||||
void clear() noexcept | |||||
{ | |||||
type = nullptr; | |||||
key = nullptr; | |||||
value = nullptr; | |||||
} | |||||
#endif | |||||
} CustomData; | } CustomData; | ||||
/*! | /*! | ||||
@@ -167,39 +167,25 @@ struct EngineControlEvent { | |||||
EngineControlEventType type; //!< Control-Event type. | EngineControlEventType type; //!< Control-Event type. | ||||
uint16_t param; //!< Parameter Id, midi bank or midi program. | uint16_t param; //!< Parameter Id, midi bank or midi program. | ||||
float value; //!< Parameter value, normalized to 0.0f<->1.0f. | float value; //!< Parameter value, normalized to 0.0f<->1.0f. | ||||
/*! | |||||
* Clear data. | |||||
*/ | |||||
void clear() noexcept | |||||
{ | |||||
type = kEngineControlEventTypeNull; | |||||
param = 0; | |||||
value = 0.0f; | |||||
} | |||||
}; | }; | ||||
/*! | /*! | ||||
* Engine MIDI event. | * Engine MIDI event. | ||||
*/ | */ | ||||
struct EngineMidiEvent { | struct EngineMidiEvent { | ||||
static const uint8_t kDataSize = 4; //!< Size of data | |||||
static const uint8_t kDataSize = 4; //!< Size of internal data | |||||
uint8_t port; //!< Port offset (usually 0) | |||||
uint8_t size; //!< Number of bytes used | |||||
uint8_t data[kDataSize]; //!< MIDI data, without channel bit | |||||
uint8_t port; //!< Port offset (usually 0) | |||||
uint8_t size; //!< Number of bytes used | |||||
/*! | /*! | ||||
* Clear data. | |||||
* MIDI data, without channel bit. | |||||
* If size > kDataSize, dataExt is used. | |||||
*/ | */ | ||||
void clear() noexcept | |||||
{ | |||||
port = 0; | |||||
size = 0; | |||||
for (uint8_t i=0; i < kDataSize; ++i) | |||||
data[i] = 0; | |||||
} | |||||
union { | |||||
uint8_t data[kDataSize]; | |||||
uint8_t* dataExt; | |||||
}; | |||||
}; | }; | ||||
/*! | /*! | ||||
@@ -218,15 +204,7 @@ struct EngineEvent { | |||||
EngineMidiEvent midi; | EngineMidiEvent midi; | ||||
}; | }; | ||||
/*! | |||||
* Clear data. | |||||
*/ | |||||
void clear() noexcept | |||||
{ | |||||
type = kEngineEventTypeNull; | |||||
time = 0; | |||||
channel = 0; | |||||
} | |||||
void fillFromMidiData(const uint8_t size, uint8_t* const data); | |||||
}; | }; | ||||
/*! | /*! | ||||
@@ -313,14 +313,6 @@ typedef struct _CarlaPortCountInfo { | |||||
*/ | */ | ||||
uint32_t outs; | uint32_t outs; | ||||
#ifdef __cplusplus | |||||
/*! | |||||
* C++ constructor. | |||||
*/ | |||||
_CarlaPortCountInfo() noexcept | |||||
: ins(0), | |||||
outs(0) {} | |||||
#endif | |||||
} CarlaPortCountInfo; | } CarlaPortCountInfo; | ||||
/*! | /*! | ||||
@@ -50,7 +50,102 @@ CARLA_BACKEND_START_NAMESPACE | |||||
// ----------------------------------------------------------------------- | // ----------------------------------------------------------------------- | ||||
// Fallback data | // Fallback data | ||||
static EngineEvent kFallbackEngineEvent; | |||||
static const EngineEvent kFallbackEngineEvent = { kEngineEventTypeNull, 0, 0, { kEngineControlEventTypeNull, 0, 0.0f } }; | |||||
// ----------------------------------------------------------------------- | |||||
void EngineEvent::fillFromMidiData(const uint8_t size, uint8_t* const data) | |||||
{ | |||||
// get channel | |||||
channel = MIDI_GET_CHANNEL_FROM_DATA(data); | |||||
// get status | |||||
const uint8_t midiStatus(MIDI_GET_STATUS_FROM_DATA(data)); | |||||
// remove channel bit from data | |||||
data[0] = midiStatus; | |||||
if (midiStatus == MIDI_STATUS_CONTROL_CHANGE) | |||||
{ | |||||
type = kEngineEventTypeControl; | |||||
const uint8_t midiControl(data[1]); | |||||
if (MIDI_IS_CONTROL_BANK_SELECT(midiControl)) | |||||
{ | |||||
CARLA_SAFE_ASSERT_INT(size == 3, size); | |||||
const uint8_t midiBank(data[2]); | |||||
ctrl.type = kEngineControlEventTypeMidiBank; | |||||
ctrl.param = midiBank; | |||||
ctrl.value = 0.0f; | |||||
} | |||||
else if (midiControl == MIDI_CONTROL_ALL_SOUND_OFF) | |||||
{ | |||||
CARLA_SAFE_ASSERT_INT(size == 2, size); | |||||
ctrl.type = kEngineControlEventTypeAllSoundOff; | |||||
ctrl.param = 0; | |||||
ctrl.value = 0.0f; | |||||
} | |||||
else if (midiControl == MIDI_CONTROL_ALL_NOTES_OFF) | |||||
{ | |||||
CARLA_SAFE_ASSERT_INT(size == 2, size); | |||||
ctrl.type = kEngineControlEventTypeAllNotesOff; | |||||
ctrl.param = 0; | |||||
ctrl.value = 0.0f; | |||||
} | |||||
else | |||||
{ | |||||
CARLA_SAFE_ASSERT_INT2(size == 3, size, midiControl); | |||||
const uint8_t midiValue(data[2]); | |||||
ctrl.type = kEngineControlEventTypeParameter; | |||||
ctrl.param = midiControl; | |||||
ctrl.value = float(midiValue)/127.0f; | |||||
} | |||||
} | |||||
else if (midiStatus == MIDI_STATUS_PROGRAM_CHANGE) | |||||
{ | |||||
CARLA_SAFE_ASSERT_INT2(size == 2, size, data[1]); | |||||
type = kEngineEventTypeControl; | |||||
const uint8_t midiProgram(data[1]); | |||||
ctrl.type = kEngineControlEventTypeMidiProgram; | |||||
ctrl.param = midiProgram; | |||||
ctrl.value = 0.0f; | |||||
} | |||||
else | |||||
{ | |||||
type = kEngineEventTypeMidi; | |||||
midi.port = 0; | |||||
midi.size = size; | |||||
if (size > EngineMidiEvent::kDataSize) | |||||
{ | |||||
midi.dataExt = data; | |||||
std::memset(midi.data, 0, sizeof(uint8_t)*EngineMidiEvent::kDataSize); | |||||
} | |||||
else | |||||
{ | |||||
midi.data[0] = midiStatus; | |||||
uint8_t i=1; | |||||
for (; i < midi.size; ++i) | |||||
midi.data[i] = data[i]; | |||||
for (; i < EngineMidiEvent::kDataSize; ++i) | |||||
midi.data[i] = 0; | |||||
midi.dataExt = nullptr; | |||||
} | |||||
} | |||||
} | |||||
// ----------------------------------------------------------------------- | // ----------------------------------------------------------------------- | ||||
// Carla Engine port (Abstract) | // Carla Engine port (Abstract) | ||||
@@ -144,14 +239,6 @@ CarlaEngineEventPort::CarlaEngineEventPort(const CarlaEngine& engine, const bool | |||||
{ | { | ||||
carla_debug("CarlaEngineEventPort::CarlaEngineEventPort(%s)", bool2str(isInput)); | carla_debug("CarlaEngineEventPort::CarlaEngineEventPort(%s)", bool2str(isInput)); | ||||
static bool sFallbackEngineEventNeedsInit = true; | |||||
if (sFallbackEngineEventNeedsInit) | |||||
{ | |||||
kFallbackEngineEvent.clear(); | |||||
sFallbackEngineEventNeedsInit = false; | |||||
} | |||||
if (fProcessMode == ENGINE_PROCESS_MODE_PATCHBAY) | if (fProcessMode == ENGINE_PROCESS_MODE_PATCHBAY) | ||||
fBuffer = new EngineEvent[kEngineMaxInternalEventCount]; | fBuffer = new EngineEvent[kEngineMaxInternalEventCount]; | ||||
} | } | ||||
@@ -272,8 +359,11 @@ bool CarlaEngineEventPort::writeMidiEvent(const uint32_t time, const uint8_t cha | |||||
event.midi.data[0] = MIDI_GET_STATUS_FROM_DATA(data); | event.midi.data[0] = MIDI_GET_STATUS_FROM_DATA(data); | ||||
for (uint8_t j=1; j < size; ++j) | |||||
uint8_t j=1; | |||||
for (; j < size; ++j) | |||||
event.midi.data[j] = data[j]; | event.midi.data[j] = data[j]; | ||||
for (; j < EngineMidiEvent::kDataSize; ++j) | |||||
event.midi.data[j] = 0; | |||||
return true; | return true; | ||||
} | } | ||||
@@ -43,7 +43,7 @@ class CarlaEngineJack; | |||||
// ----------------------------------------------------------------------- | // ----------------------------------------------------------------------- | ||||
// Fallback data | // Fallback data | ||||
static EngineEvent kFallbackJackEngineEvent; | |||||
static const EngineEvent kFallbackJackEngineEvent = { kEngineEventTypeNull, 0, 0, { kEngineControlEventTypeNull, 0, 0.0f } }; | |||||
// ----------------------------------------------------------------------- | // ----------------------------------------------------------------------- | ||||
// Carla Engine JACK-Audio port | // Carla Engine JACK-Audio port | ||||
@@ -185,14 +185,6 @@ public: | |||||
{ | { | ||||
carla_debug("CarlaEngineJackEventPort::CarlaEngineJackEventPort(%s, %p, %p)", bool2str(isInput), client, port); | carla_debug("CarlaEngineJackEventPort::CarlaEngineJackEventPort(%s, %p, %p)", bool2str(isInput), client, port); | ||||
static bool sFallbackJackEngineEventNeedsInit = true; | |||||
if (sFallbackJackEngineEventNeedsInit) | |||||
{ | |||||
kFallbackJackEngineEvent.clear(); | |||||
sFallbackJackEngineEventNeedsInit = false; | |||||
} | |||||
if (fEngine.getProccessMode() == ENGINE_PROCESS_MODE_SINGLE_CLIENT || fEngine.getProccessMode() == ENGINE_PROCESS_MODE_MULTIPLE_CLIENTS) | if (fEngine.getProccessMode() == ENGINE_PROCESS_MODE_SINGLE_CLIENT || fEngine.getProccessMode() == ENGINE_PROCESS_MODE_MULTIPLE_CLIENTS) | ||||
{ | { | ||||
CARLA_ASSERT(client != nullptr && port != nullptr); | CARLA_ASSERT(client != nullptr && port != nullptr); | ||||
@@ -256,86 +248,8 @@ public: | |||||
if (! jackbridge_midi_event_get(&jackEvent, fJackBuffer, index)) | if (! jackbridge_midi_event_get(&jackEvent, fJackBuffer, index)) | ||||
return kFallbackJackEngineEvent; | return kFallbackJackEngineEvent; | ||||
CARLA_SAFE_ASSERT_RETURN(jackEvent.size > 0 && jackEvent.size <= EngineMidiEvent::kDataSize, kFallbackJackEngineEvent); | |||||
//if (jackEvent.size == 0 || jackEvent.size > EngineMidiEvent::kDataSize) | |||||
// return kFallbackJackEngineEvent; | |||||
const uint8_t midiStatus = MIDI_GET_STATUS_FROM_DATA(jackEvent.buffer); | |||||
const uint8_t midiChannel = MIDI_GET_CHANNEL_FROM_DATA(jackEvent.buffer); | |||||
fRetEvent.time = jackEvent.time; | |||||
fRetEvent.channel = midiChannel; | |||||
if (midiStatus == MIDI_STATUS_CONTROL_CHANGE) | |||||
{ | |||||
fRetEvent.type = kEngineEventTypeControl; | |||||
const uint8_t midiControl = jackEvent.buffer[1]; | |||||
if (MIDI_IS_CONTROL_BANK_SELECT(midiControl)) | |||||
{ | |||||
CARLA_SAFE_ASSERT_INT(jackEvent.size == 3, jackEvent.size); | |||||
const uint8_t midiBank = jackEvent.buffer[2]; | |||||
fRetEvent.ctrl.type = kEngineControlEventTypeMidiBank; | |||||
fRetEvent.ctrl.param = midiBank; | |||||
fRetEvent.ctrl.value = 0.0f; | |||||
} | |||||
else if (midiControl == MIDI_CONTROL_ALL_SOUND_OFF) | |||||
{ | |||||
CARLA_SAFE_ASSERT_INT(jackEvent.size == 2, jackEvent.size); | |||||
fRetEvent.ctrl.type = kEngineControlEventTypeAllSoundOff; | |||||
fRetEvent.ctrl.param = 0; | |||||
fRetEvent.ctrl.value = 0.0f; | |||||
} | |||||
else if (midiControl == MIDI_CONTROL_ALL_NOTES_OFF) | |||||
{ | |||||
CARLA_SAFE_ASSERT_INT(jackEvent.size == 2, jackEvent.size); | |||||
fRetEvent.ctrl.type = kEngineControlEventTypeAllNotesOff; | |||||
fRetEvent.ctrl.param = 0; | |||||
fRetEvent.ctrl.value = 0.0f; | |||||
} | |||||
else | |||||
{ | |||||
CARLA_SAFE_ASSERT_INT2(jackEvent.size == 3, jackEvent.size, midiControl); | |||||
const uint8_t midiValue = jackEvent.buffer[2]; | |||||
fRetEvent.ctrl.type = kEngineControlEventTypeParameter; | |||||
fRetEvent.ctrl.param = midiControl; | |||||
fRetEvent.ctrl.value = float(midiValue)/127.0f; | |||||
} | |||||
} | |||||
else if (midiStatus == MIDI_STATUS_PROGRAM_CHANGE) | |||||
{ | |||||
CARLA_SAFE_ASSERT_INT2(jackEvent.size == 2, jackEvent.size, jackEvent.buffer[1]); | |||||
fRetEvent.type = kEngineEventTypeControl; | |||||
const uint8_t midiProgram = jackEvent.buffer[1]; | |||||
fRetEvent.ctrl.type = kEngineControlEventTypeMidiProgram; | |||||
fRetEvent.ctrl.param = midiProgram; | |||||
fRetEvent.ctrl.value = 0.0f; | |||||
} | |||||
else | |||||
{ | |||||
fRetEvent.type = kEngineEventTypeMidi; | |||||
fRetEvent.midi.port = 0; | |||||
fRetEvent.midi.size = static_cast<uint8_t>(jackEvent.size); | |||||
fRetEvent.midi.data[0] = midiStatus; | |||||
uint8_t i=1; | |||||
for (; i < fRetEvent.midi.size; ++i) | |||||
fRetEvent.midi.data[i] = jackEvent.buffer[i]; | |||||
for (; i < EngineMidiEvent::kDataSize; ++i) | |||||
fRetEvent.midi.data[i] = 0; | |||||
} | |||||
fRetEvent.time = jackEvent.time; | |||||
fRetEvent.fillFromMidiData(jackEvent.size, jackEvent.buffer); | |||||
return fRetEvent; | return fRetEvent; | ||||
} | } | ||||
@@ -415,7 +329,6 @@ public: | |||||
CARLA_SAFE_ASSERT_RETURN(data != nullptr, false); | CARLA_SAFE_ASSERT_RETURN(data != nullptr, false); | ||||
jack_midi_data_t jdata[size]; | jack_midi_data_t jdata[size]; | ||||
std::memset(jdata, 0, sizeof(jack_midi_data_t)*size); | |||||
jdata[0] = MIDI_GET_STATUS_FROM_DATA(data); | jdata[0] = MIDI_GET_STATUS_FROM_DATA(data); | ||||
jdata[0] += channel; | jdata[0] += channel; | ||||
@@ -1259,74 +1172,10 @@ protected: | |||||
if (! jackbridge_midi_event_get(&jackEvent, eventIn, jackEventIndex)) | if (! jackbridge_midi_event_get(&jackEvent, eventIn, jackEventIndex)) | ||||
continue; | continue; | ||||
EngineEvent* const engineEvent(&pData->bufEvents.in[engineEventIndex++]); | |||||
engineEvent->clear(); | |||||
const uint8_t midiStatus = MIDI_GET_STATUS_FROM_DATA(jackEvent.buffer); | |||||
const uint8_t midiChannel = MIDI_GET_CHANNEL_FROM_DATA(jackEvent.buffer); | |||||
EngineEvent& engineEvent(pData->bufEvents.in[engineEventIndex++]); | |||||
engineEvent->time = jackEvent.time; | |||||
engineEvent->channel = midiChannel; | |||||
if (midiStatus == MIDI_STATUS_CONTROL_CHANGE) | |||||
{ | |||||
CARLA_ASSERT(jackEvent.size == 2 || jackEvent.size == 3); | |||||
const uint8_t midiControl = jackEvent.buffer[1]; | |||||
engineEvent->type = kEngineEventTypeControl; | |||||
if (MIDI_IS_CONTROL_BANK_SELECT(midiControl)) | |||||
{ | |||||
const uint8_t midiBank = jackEvent.buffer[2]; | |||||
engineEvent->ctrl.type = kEngineControlEventTypeMidiBank; | |||||
engineEvent->ctrl.param = midiBank; | |||||
engineEvent->ctrl.value = 0.0f; | |||||
} | |||||
else if (midiControl == MIDI_CONTROL_ALL_SOUND_OFF) | |||||
{ | |||||
engineEvent->ctrl.type = kEngineControlEventTypeAllSoundOff; | |||||
engineEvent->ctrl.param = 0; | |||||
engineEvent->ctrl.value = 0.0f; | |||||
} | |||||
else if (midiControl == MIDI_CONTROL_ALL_NOTES_OFF) | |||||
{ | |||||
engineEvent->ctrl.type = kEngineControlEventTypeAllNotesOff; | |||||
engineEvent->ctrl.param = 0; | |||||
engineEvent->ctrl.value = 0.0f; | |||||
} | |||||
else | |||||
{ | |||||
CARLA_ASSERT(jackEvent.size == 3); | |||||
const uint8_t midiValue = jackEvent.buffer[2]; | |||||
engineEvent->ctrl.type = kEngineControlEventTypeParameter; | |||||
engineEvent->ctrl.param = midiControl; | |||||
engineEvent->ctrl.value = float(midiValue)/127.0f; | |||||
} | |||||
} | |||||
else if (midiStatus == MIDI_STATUS_PROGRAM_CHANGE) | |||||
{ | |||||
CARLA_ASSERT(jackEvent.size == 2); | |||||
const uint8_t midiProgram = jackEvent.buffer[1]; | |||||
engineEvent->type = kEngineEventTypeControl; | |||||
engineEvent->ctrl.type = kEngineControlEventTypeMidiProgram; | |||||
engineEvent->ctrl.param = midiProgram; | |||||
engineEvent->ctrl.value = 0.0f; | |||||
} | |||||
else if (jackEvent.size <= 4) | |||||
{ | |||||
engineEvent->type = kEngineEventTypeMidi; | |||||
engineEvent->midi.data[0] = midiStatus; | |||||
engineEvent->midi.size = static_cast<uint8_t>(jackEvent.size); | |||||
if (jackEvent.size > 1) | |||||
carla_copy<uint8_t>(engineEvent->midi.data+1, jackEvent.buffer+1, jackEvent.size-1); | |||||
} | |||||
engineEvent.time = jackEvent.time; | |||||
engineEvent.fillFromMidiData(jackEvent.size, jackEvent.buffer); | |||||
if (engineEventIndex >= kEngineMaxInternalEventCount) | if (engineEventIndex >= kEngineMaxInternalEventCount) | ||||
break; | break; | ||||
@@ -1342,58 +1191,61 @@ protected: | |||||
for (unsigned short i=0; i < kEngineMaxInternalEventCount; ++i) | for (unsigned short i=0; i < kEngineMaxInternalEventCount; ++i) | ||||
{ | { | ||||
EngineEvent* const engineEvent = &pData->bufEvents.out[i]; | |||||
const EngineEvent& engineEvent(pData->bufEvents.out[i]); | |||||
uint8_t data[3] = { 0 }; | |||||
uint8_t size = 0; | |||||
uint8_t size = 0; | |||||
uint8_t data[3] = { 0, 0, 0 }; | |||||
uint8_t* dataPtr = data; | |||||
switch (engineEvent->type) | |||||
switch (engineEvent.type) | |||||
{ | { | ||||
case kEngineEventTypeNull: | case kEngineEventTypeNull: | ||||
break; | break; | ||||
case kEngineEventTypeControl: | case kEngineEventTypeControl: | ||||
{ | { | ||||
EngineControlEvent* const ctrlEvent = &engineEvent->ctrl; | |||||
const EngineControlEvent& ctrlEvent(engineEvent.ctrl); | |||||
if (ctrlEvent->type == kEngineControlEventTypeParameter && MIDI_IS_CONTROL_BANK_SELECT(ctrlEvent->param)) | |||||
{ | |||||
// FIXME? | |||||
ctrlEvent->type = kEngineControlEventTypeMidiBank; | |||||
ctrlEvent->param = ctrlEvent->value; | |||||
ctrlEvent->value = 0.0f; | |||||
} | |||||
switch (ctrlEvent->type) | |||||
switch (ctrlEvent.type) | |||||
{ | { | ||||
case kEngineControlEventTypeNull: | case kEngineControlEventTypeNull: | ||||
break; | break; | ||||
case kEngineControlEventTypeParameter: | case kEngineControlEventTypeParameter: | ||||
data[0] = MIDI_STATUS_CONTROL_CHANGE + engineEvent->channel; | |||||
data[1] = static_cast<uint8_t>(ctrlEvent->param); | |||||
data[2] = uint8_t(ctrlEvent->value * 127.0f); | |||||
size = 3; | |||||
if (MIDI_IS_CONTROL_BANK_SELECT(ctrlEvent.param)) | |||||
{ | |||||
size = 3; | |||||
data[0] = MIDI_STATUS_CONTROL_CHANGE + engineEvent.channel; | |||||
data[1] = MIDI_CONTROL_BANK_SELECT; | |||||
data[2] = static_cast<uint8_t>(ctrlEvent.value); | |||||
} | |||||
else | |||||
{ | |||||
size = 3; | |||||
data[0] = MIDI_STATUS_CONTROL_CHANGE + engineEvent.channel; | |||||
data[1] = static_cast<uint8_t>(ctrlEvent.param); | |||||
data[2] = uint8_t(ctrlEvent.value * 127.0f); | |||||
} | |||||
break; | break; | ||||
case kEngineControlEventTypeMidiBank: | case kEngineControlEventTypeMidiBank: | ||||
data[0] = MIDI_STATUS_CONTROL_CHANGE + engineEvent->channel; | |||||
data[1] = MIDI_CONTROL_BANK_SELECT; | |||||
data[2] = static_cast<uint8_t>(ctrlEvent->param); | |||||
size = 3; | size = 3; | ||||
data[0] = MIDI_STATUS_CONTROL_CHANGE + engineEvent.channel; | |||||
data[1] = MIDI_CONTROL_BANK_SELECT; | |||||
data[2] = static_cast<uint8_t>(ctrlEvent.param); | |||||
break; | break; | ||||
case kEngineControlEventTypeMidiProgram: | case kEngineControlEventTypeMidiProgram: | ||||
data[0] = MIDI_STATUS_PROGRAM_CHANGE + engineEvent->channel; | |||||
data[1] = static_cast<uint8_t>(ctrlEvent->param); | |||||
size = 2; | size = 2; | ||||
data[0] = MIDI_STATUS_PROGRAM_CHANGE + engineEvent.channel; | |||||
data[1] = static_cast<uint8_t>(ctrlEvent.param); | |||||
break; | break; | ||||
case kEngineControlEventTypeAllSoundOff: | case kEngineControlEventTypeAllSoundOff: | ||||
data[0] = MIDI_STATUS_CONTROL_CHANGE + engineEvent->channel; | |||||
data[1] = MIDI_CONTROL_ALL_SOUND_OFF; | |||||
size = 2; | size = 2; | ||||
data[0] = MIDI_STATUS_CONTROL_CHANGE + engineEvent.channel; | |||||
data[1] = MIDI_CONTROL_ALL_SOUND_OFF; | |||||
break; | break; | ||||
case kEngineControlEventTypeAllNotesOff: | case kEngineControlEventTypeAllNotesOff: | ||||
data[0] = MIDI_STATUS_CONTROL_CHANGE + engineEvent->channel; | |||||
data[1] = MIDI_CONTROL_ALL_NOTES_OFF; | |||||
size = 2; | size = 2; | ||||
data[0] = MIDI_STATUS_CONTROL_CHANGE + engineEvent.channel; | |||||
data[1] = MIDI_CONTROL_ALL_NOTES_OFF; | |||||
break; | break; | ||||
} | } | ||||
break; | break; | ||||
@@ -1401,18 +1253,21 @@ protected: | |||||
case kEngineEventTypeMidi: | case kEngineEventTypeMidi: | ||||
{ | { | ||||
EngineMidiEvent* const midiEvent = &engineEvent->midi; | |||||
const EngineMidiEvent& midiEvent(engineEvent.midi); | |||||
size = midiEvent.size; | |||||
if (size > EngineMidiEvent::kDataSize && midiEvent.dataExt != nullptr) | |||||
dataPtr = midiEvent.dataExt; | |||||
else | |||||
dataPtr = midiEvent.dataExt; | |||||
data[0] = midiEvent->data[0]; | |||||
data[1] = midiEvent->data[1]; | |||||
data[2] = midiEvent->data[2]; | |||||
size = midiEvent->size; | |||||
break; | break; | ||||
} | } | ||||
} | } | ||||
if (size > 0) | if (size > 0) | ||||
jackbridge_midi_event_write(eventOut, engineEvent->time, data, size); | |||||
jackbridge_midi_event_write(eventOut, engineEvent.time, dataPtr, size); | |||||
} | } | ||||
} | } | ||||
@@ -887,15 +887,8 @@ protected: | |||||
while (! fMidiInEvents.data.isEmpty()) | while (! fMidiInEvents.data.isEmpty()) | ||||
{ | { | ||||
const RtMidiEvent& midiEvent(fMidiInEvents.data.getFirst(true)); | |||||
RtMidiEvent& midiEvent(fMidiInEvents.data.getFirst(true)); | |||||
EngineEvent& engineEvent(pData->bufEvents.in[engineEventIndex++]); | EngineEvent& engineEvent(pData->bufEvents.in[engineEventIndex++]); | ||||
engineEvent.clear(); | |||||
const uint8_t midiStatus = MIDI_GET_STATUS_FROM_DATA(midiEvent.data); | |||||
const uint8_t midiChannel = MIDI_GET_CHANNEL_FROM_DATA(midiEvent.data); | |||||
engineEvent.channel = midiChannel; | |||||
if (midiEvent.time < pData->timeInfo.frame) | if (midiEvent.time < pData->timeInfo.frame) | ||||
{ | { | ||||
@@ -909,59 +902,7 @@ protected: | |||||
else | else | ||||
engineEvent.time = midiEvent.time - pData->timeInfo.frame; | engineEvent.time = midiEvent.time - pData->timeInfo.frame; | ||||
if (MIDI_IS_STATUS_CONTROL_CHANGE(midiStatus)) | |||||
{ | |||||
const uint8_t midiControl = midiEvent.data[1]; | |||||
engineEvent.type = kEngineEventTypeControl; | |||||
if (MIDI_IS_CONTROL_BANK_SELECT(midiControl)) | |||||
{ | |||||
const uint8_t midiBank = midiEvent.data[2]; | |||||
engineEvent.ctrl.type = kEngineControlEventTypeMidiBank; | |||||
engineEvent.ctrl.param = midiBank; | |||||
engineEvent.ctrl.value = 0.0f; | |||||
} | |||||
else if (midiControl == MIDI_CONTROL_ALL_SOUND_OFF) | |||||
{ | |||||
engineEvent.ctrl.type = kEngineControlEventTypeAllSoundOff; | |||||
engineEvent.ctrl.param = 0; | |||||
engineEvent.ctrl.value = 0.0f; | |||||
} | |||||
else if (midiControl == MIDI_CONTROL_ALL_NOTES_OFF) | |||||
{ | |||||
engineEvent.ctrl.type = kEngineControlEventTypeAllNotesOff; | |||||
engineEvent.ctrl.param = 0; | |||||
engineEvent.ctrl.value = 0.0f; | |||||
} | |||||
else | |||||
{ | |||||
const uint8_t midiValue = midiEvent.data[2]; | |||||
engineEvent.ctrl.type = kEngineControlEventTypeParameter; | |||||
engineEvent.ctrl.param = midiControl; | |||||
engineEvent.ctrl.value = float(midiValue)/127.0f; | |||||
} | |||||
} | |||||
else if (MIDI_IS_STATUS_PROGRAM_CHANGE(midiStatus)) | |||||
{ | |||||
const uint8_t midiProgram = midiEvent.data[1]; | |||||
engineEvent.type = kEngineEventTypeControl; | |||||
engineEvent.ctrl.type = kEngineControlEventTypeMidiProgram; | |||||
engineEvent.ctrl.param = midiProgram; | |||||
engineEvent.ctrl.value = 0.0f; | |||||
} | |||||
else | |||||
{ | |||||
engineEvent.type = kEngineEventTypeMidi; | |||||
engineEvent.midi.data[0] = midiStatus; | |||||
engineEvent.midi.data[1] = midiEvent.data[1]; | |||||
engineEvent.midi.data[2] = midiEvent.data[2]; | |||||
engineEvent.midi.data[3] = midiEvent.data[3]; | |||||
engineEvent.midi.size = midiEvent.size; | |||||
} | |||||
engineEvent.fillFromMidiData(midiEvent.size, midiEvent.data); | |||||
if (engineEventIndex >= kEngineMaxInternalEventCount) | if (engineEventIndex >= kEngineMaxInternalEventCount) | ||||
break; | break; | ||||
@@ -1124,7 +1065,7 @@ protected: | |||||
const size_t messageSize = message->size(); | const size_t messageSize = message->size(); | ||||
static uint32_t lastTime = 0; | static uint32_t lastTime = 0; | ||||
if (messageSize == 0 || messageSize > 4) | |||||
if (messageSize == 0 || messageSize > EngineMidiEvent::kDataSize) | |||||
return; | return; | ||||
timeStamp /= 2; | timeStamp /= 2; | ||||
@@ -1142,38 +1083,13 @@ protected: | |||||
else | else | ||||
lastTime = midiEvent.time; | lastTime = midiEvent.time; | ||||
if (messageSize == 1) | |||||
{ | |||||
midiEvent.data[0] = message->at(0); | |||||
midiEvent.data[1] = 0; | |||||
midiEvent.data[2] = 0; | |||||
midiEvent.data[3] = 0; | |||||
midiEvent.size = 1; | |||||
} | |||||
else if (messageSize == 2) | |||||
{ | |||||
midiEvent.data[0] = message->at(0); | |||||
midiEvent.data[1] = message->at(1); | |||||
midiEvent.data[2] = 0; | |||||
midiEvent.data[3] = 0; | |||||
midiEvent.size = 2; | |||||
} | |||||
else if (messageSize == 3) | |||||
{ | |||||
midiEvent.data[0] = message->at(0); | |||||
midiEvent.data[1] = message->at(1); | |||||
midiEvent.data[2] = message->at(2); | |||||
midiEvent.data[3] = 0; | |||||
midiEvent.size = 3; | |||||
} | |||||
else | |||||
{ | |||||
midiEvent.data[0] = message->at(0); | |||||
midiEvent.data[1] = message->at(1); | |||||
midiEvent.data[2] = message->at(2); | |||||
midiEvent.data[3] = message->at(3); | |||||
midiEvent.size = 4; | |||||
} | |||||
midiEvent.size = messageSize; | |||||
size_t i=0; | |||||
for (; i < messageSize; ++i) | |||||
midiEvent.data[i] = message->at(i); | |||||
for (; i < EngineMidiEvent::kDataSize; ++i) | |||||
midiEvent.data[i] = 0; | |||||
fMidiInEvents.append(midiEvent); | fMidiInEvents.append(midiEvent); | ||||
} | } | ||||
@@ -1337,8 +1253,8 @@ private: | |||||
struct RtMidiEvent { | struct RtMidiEvent { | ||||
uint32_t time; | uint32_t time; | ||||
unsigned char data[4]; | |||||
unsigned char size; | |||||
uint8_t size; | |||||
uint8_t data[EngineMidiEvent::kDataSize]; | |||||
}; | }; | ||||
struct RtMidiEvents { | struct RtMidiEvents { | ||||
@@ -29,10 +29,10 @@ CARLA_BACKEND_START_NAMESPACE | |||||
// ------------------------------------------------------------------- | // ------------------------------------------------------------------- | ||||
// Fallback data | // Fallback data | ||||
static ParameterData kParameterDataNull; | |||||
static ParameterRanges kParameterRangesNull; | |||||
static MidiProgramData kMidiProgramDataNull; | |||||
static CustomData kCustomDataNull; | |||||
static const ParameterData kParameterDataNull = { PARAMETER_UNKNOWN, 0x0, PARAMETER_NULL, -1, -1, 0 }; | |||||
static const ParameterRanges kParameterRangesNull = { 0.0f, 0.0f, 1.0f, 0.01f, 0.0001f, 0.1f }; | |||||
static const MidiProgramData kMidiProgramDataNull = { 0, 0, nullptr }; | |||||
static const CustomData kCustomDataNull = { nullptr, nullptr, nullptr }; | |||||
static bool gIsLoadingProject = false; | static bool gIsLoadingProject = false; | ||||
@@ -229,17 +229,6 @@ CarlaPlugin::CarlaPlugin(CarlaEngine* const engine, const unsigned int id) | |||||
CARLA_ASSERT(id == engine->getCurrentPluginCount()); | CARLA_ASSERT(id == engine->getCurrentPluginCount()); | ||||
carla_debug("CarlaPlugin::CarlaPlugin(%p, %i)", engine, id); | carla_debug("CarlaPlugin::CarlaPlugin(%p, %i)", engine, id); | ||||
static bool sFallbackDataNeedsInit = true; | |||||
if (sFallbackDataNeedsInit) | |||||
{ | |||||
kParameterDataNull.clear(); | |||||
kParameterRangesNull.clear(); | |||||
kMidiProgramDataNull.clear(); | |||||
kCustomDataNull.clear(); | |||||
sFallbackDataNeedsInit = false; | |||||
} | |||||
switch (engine->getProccessMode()) | switch (engine->getProccessMode()) | ||||
{ | { | ||||
case ENGINE_PROCESS_MODE_SINGLE_CLIENT: | case ENGINE_PROCESS_MODE_SINGLE_CLIENT: | ||||
@@ -1240,9 +1240,9 @@ const ParameterData* carla_get_parameter_data(uint pluginId, uint32_t parameterI | |||||
{ | { | ||||
carla_debug("carla_get_parameter_data(%i, %i)", pluginId, parameterId); | carla_debug("carla_get_parameter_data(%i, %i)", pluginId, parameterId); | ||||
static ParameterData fallbackParamData; | |||||
static const ParameterData fallbackParameterData = { CB::PARAMETER_UNKNOWN, 0x0, CB::PARAMETER_NULL, -1, -1, 0 }; | |||||
CARLA_SAFE_ASSERT_RETURN(gStandalone.engine != nullptr, &fallbackParamData); | |||||
CARLA_SAFE_ASSERT_RETURN(gStandalone.engine != nullptr, &fallbackParameterData); | |||||
if (CarlaPlugin* const plugin = gStandalone.engine->getPlugin(pluginId)) | if (CarlaPlugin* const plugin = gStandalone.engine->getPlugin(pluginId)) | ||||
{ | { | ||||
@@ -1250,18 +1250,18 @@ const ParameterData* carla_get_parameter_data(uint pluginId, uint32_t parameterI | |||||
return &plugin->getParameterData(parameterId); | return &plugin->getParameterData(parameterId); | ||||
carla_stderr2("carla_get_parameter_data(%i, %i) - parameterId out of bounds", pluginId, parameterId); | carla_stderr2("carla_get_parameter_data(%i, %i) - parameterId out of bounds", pluginId, parameterId); | ||||
return &fallbackParamData; | |||||
return &fallbackParameterData; | |||||
} | } | ||||
carla_stderr2("carla_get_parameter_data(%i, %i) - could not find plugin", pluginId, parameterId); | carla_stderr2("carla_get_parameter_data(%i, %i) - could not find plugin", pluginId, parameterId); | ||||
return &fallbackParamData; | |||||
return &fallbackParameterData; | |||||
} | } | ||||
const ParameterRanges* carla_get_parameter_ranges(uint pluginId, uint32_t parameterId) | const ParameterRanges* carla_get_parameter_ranges(uint pluginId, uint32_t parameterId) | ||||
{ | { | ||||
carla_debug("carla_get_parameter_ranges(%i, %i)", pluginId, parameterId); | carla_debug("carla_get_parameter_ranges(%i, %i)", pluginId, parameterId); | ||||
static ParameterRanges fallbackParamRanges; | |||||
static const ParameterRanges fallbackParamRanges = { 0.0f, 0.0f, 1.0f, 0.01f, 0.0001f, 0.1f }; | |||||
CARLA_SAFE_ASSERT_RETURN(gStandalone.engine != nullptr, &fallbackParamRanges); | CARLA_SAFE_ASSERT_RETURN(gStandalone.engine != nullptr, &fallbackParamRanges); | ||||
@@ -1282,7 +1282,7 @@ const MidiProgramData* carla_get_midi_program_data(uint pluginId, uint32_t midiP | |||||
{ | { | ||||
carla_debug("carla_get_midi_program_data(%i, %i)", pluginId, midiProgramId); | carla_debug("carla_get_midi_program_data(%i, %i)", pluginId, midiProgramId); | ||||
static MidiProgramData fallbackMidiProgData; | |||||
static const MidiProgramData fallbackMidiProgData = { 0, 0, nullptr }; | |||||
CARLA_SAFE_ASSERT_RETURN(gStandalone.engine != nullptr, &fallbackMidiProgData); | CARLA_SAFE_ASSERT_RETURN(gStandalone.engine != nullptr, &fallbackMidiProgData); | ||||
@@ -1303,7 +1303,7 @@ const CustomData* carla_get_custom_data(uint pluginId, uint32_t customDataId) | |||||
{ | { | ||||
carla_debug("carla_get_custom_data(%i, %i)", pluginId, customDataId); | carla_debug("carla_get_custom_data(%i, %i)", pluginId, customDataId); | ||||
static CustomData fallbackCustomData; | |||||
static const CustomData fallbackCustomData = { nullptr, nullptr, nullptr }; | |||||
CARLA_SAFE_ASSERT_RETURN(gStandalone.engine != nullptr, &fallbackCustomData); | CARLA_SAFE_ASSERT_RETURN(gStandalone.engine != nullptr, &fallbackCustomData); | ||||