| @@ -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); | ||||