| @@ -183,21 +183,22 @@ struct EngineControlEvent { | |||||
| * Engine MIDI event. | * Engine MIDI event. | ||||
| */ | */ | ||||
| struct EngineMidiEvent { | struct EngineMidiEvent { | ||||
| uint8_t port; //!< Port offset (usually 0) | |||||
| uint8_t size; //!< Number of bytes used | |||||
| uint8_t data[4]; //!< MIDI data, without channel bit | |||||
| static const uint8_t kDataSize = 4; //!< Size of data | |||||
| uint8_t port; //!< Port offset (usually 0) | |||||
| uint8_t size; //!< Number of bytes used | |||||
| uint8_t data[kDataSize]; //!< MIDI data, without channel bit | |||||
| /*! | /*! | ||||
| * Clear data. | * Clear data. | ||||
| */ | */ | ||||
| void clear() noexcept | void clear() noexcept | ||||
| { | { | ||||
| port = 0; | |||||
| size = 0; | |||||
| data[0] = 0; | |||||
| data[1] = 0; | |||||
| data[2] = 0; | |||||
| data[3] = 0; | |||||
| port = 0; | |||||
| size = 0; | |||||
| for (uint8_t i=0; i < kDataSize; ++i) | |||||
| data[i] = 0; | |||||
| } | } | ||||
| }; | }; | ||||
| @@ -323,12 +324,12 @@ struct EngineTimeInfoBBT { | |||||
| * Engine Time information. | * Engine Time information. | ||||
| */ | */ | ||||
| struct EngineTimeInfo { | struct EngineTimeInfo { | ||||
| static const uint32_t ValidBBT = 0x1; | |||||
| static const uint kValidBBT = 0x1; | |||||
| bool playing; | bool playing; | ||||
| uint64_t frame; | uint64_t frame; | ||||
| uint64_t usecs; | uint64_t usecs; | ||||
| uint32_t valid; | |||||
| uint valid; | |||||
| EngineTimeInfoBBT bbt; | EngineTimeInfoBBT bbt; | ||||
| EngineTimeInfo() noexcept | EngineTimeInfo() noexcept | ||||
| @@ -348,10 +349,10 @@ struct EngineTimeInfo { | |||||
| // quick operator, doesn't check all values | // quick operator, doesn't check all values | ||||
| bool operator==(const EngineTimeInfo& timeInfo) const noexcept | bool operator==(const EngineTimeInfo& timeInfo) const noexcept | ||||
| { | { | ||||
| if (timeInfo.playing != playing || timeInfo.frame != frame) | |||||
| return false; | |||||
| if (timeInfo.valid != valid) | |||||
| if (timeInfo.playing != playing || timeInfo.frame != frame || timeInfo.valid != valid) | |||||
| return false; | return false; | ||||
| if ((valid & kValidBBT) == 0) | |||||
| return true; | |||||
| if (timeInfo.bbt.beatsPerMinute != bbt.beatsPerMinute) | if (timeInfo.bbt.beatsPerMinute != bbt.beatsPerMinute) | ||||
| return false; | return false; | ||||
| return true; | return true; | ||||
| @@ -488,6 +489,11 @@ public: | |||||
| */ | */ | ||||
| virtual void initBuffer() override; | virtual void initBuffer() override; | ||||
| /*! | |||||
| * Set a new buffer size. | |||||
| */ | |||||
| void setBufferSize(const uint32_t bufferSize); | |||||
| #if 0 | #if 0 | ||||
| // TESTING: I should remove this | // TESTING: I should remove this | ||||
| /*! | /*! | ||||
| @@ -495,10 +501,6 @@ public: | |||||
| */ | */ | ||||
| virtual void writeBuffer(const uint32_t frames, const uint32_t timeOffset); | virtual void writeBuffer(const uint32_t frames, const uint32_t timeOffset); | ||||
| /*! | |||||
| * Set a new buffer size. | |||||
| */ | |||||
| void setBufferSize(const uint32_t bufferSize); | |||||
| #endif | #endif | ||||
| /*! | /*! | ||||
| @@ -512,6 +514,7 @@ public: | |||||
| #ifndef DOXYGEN | #ifndef DOXYGEN | ||||
| protected: | protected: | ||||
| float* fBuffer; | float* fBuffer; | ||||
| const EngineProcessMode fProcessMode; | |||||
| CARLA_DECLARE_NON_COPY_CLASS(CarlaEngineCVPort) | CARLA_DECLARE_NON_COPY_CLASS(CarlaEngineCVPort) | ||||
| #endif | #endif | ||||
| @@ -584,14 +587,14 @@ public: | |||||
| * Arguments are the same as in the EngineMidiEvent struct. | * Arguments are the same as in the EngineMidiEvent struct. | ||||
| * \note You must only call this for output ports. | * \note You must only call this for output ports. | ||||
| */ | */ | ||||
| virtual bool writeMidiEvent(const uint32_t time, const uint8_t channel, const uint8_t port, const uint8_t* const data, const uint8_t size); | |||||
| virtual bool writeMidiEvent(const uint32_t time, const uint8_t channel, const uint8_t port, const uint8_t size, const uint8_t* const data); | |||||
| /*! | /*! | ||||
| * Write a MIDI event into the buffer, overloaded call. | * Write a MIDI event into the buffer, overloaded call. | ||||
| */ | */ | ||||
| bool writeMidiEvent(const uint32_t time, const uint8_t* const data, const uint8_t size) | |||||
| bool writeMidiEvent(const uint32_t time, const uint8_t size, const uint8_t* const data) | |||||
| { | { | ||||
| return writeMidiEvent(time, MIDI_GET_CHANNEL_FROM_DATA(data), 0, data, size); | |||||
| return writeMidiEvent(time, MIDI_GET_CHANNEL_FROM_DATA(data), 0, size, data); | |||||
| } | } | ||||
| /*! | /*! | ||||
| @@ -599,12 +602,13 @@ public: | |||||
| */ | */ | ||||
| bool writeMidiEvent(const uint32_t time, const uint8_t channel, const EngineMidiEvent& midi) | bool writeMidiEvent(const uint32_t time, const uint8_t channel, const EngineMidiEvent& midi) | ||||
| { | { | ||||
| return writeMidiEvent(time, channel, midi.port, midi.data, midi.size); | |||||
| return writeMidiEvent(time, channel, midi.port, midi.size, midi.data); | |||||
| } | } | ||||
| #ifndef DOXYGEN | #ifndef DOXYGEN | ||||
| protected: | protected: | ||||
| EngineEvent* fBuffer; | EngineEvent* fBuffer; | ||||
| const EngineProcessMode fProcessMode; | |||||
| CARLA_DECLARE_NON_COPY_CLASS(CarlaEngineEventPort) | CARLA_DECLARE_NON_COPY_CLASS(CarlaEngineEventPort) | ||||
| #endif | #endif | ||||
| @@ -95,23 +95,32 @@ void CarlaEngineAudioPort::initBuffer() | |||||
| CarlaEngineCVPort::CarlaEngineCVPort(const CarlaEngine& engine, const bool isInput) | CarlaEngineCVPort::CarlaEngineCVPort(const CarlaEngine& engine, const bool isInput) | ||||
| : CarlaEnginePort(engine, isInput), | : CarlaEnginePort(engine, isInput), | ||||
| fBuffer(new float[engine.getBufferSize()]) | |||||
| fBuffer(nullptr), | |||||
| fProcessMode(engine.getProccessMode()) | |||||
| { | { | ||||
| carla_debug("CarlaEngineCVPort::CarlaEngineCVPort(%s)", bool2str(isInput)); | carla_debug("CarlaEngineCVPort::CarlaEngineCVPort(%s)", bool2str(isInput)); | ||||
| if (fProcessMode != ENGINE_PROCESS_MODE_SINGLE_CLIENT && fProcessMode != ENGINE_PROCESS_MODE_MULTIPLE_CLIENTS) | |||||
| fBuffer = new float[engine.getBufferSize()]; | |||||
| } | } | ||||
| CarlaEngineCVPort::~CarlaEngineCVPort() | CarlaEngineCVPort::~CarlaEngineCVPort() | ||||
| { | { | ||||
| CARLA_SAFE_ASSERT_RETURN(fBuffer != nullptr,); | |||||
| carla_debug("CarlaEngineCVPort::~CarlaEngineCVPort()"); | carla_debug("CarlaEngineCVPort::~CarlaEngineCVPort()"); | ||||
| delete[] fBuffer; | |||||
| fBuffer = nullptr; | |||||
| if (fProcessMode != ENGINE_PROCESS_MODE_SINGLE_CLIENT && fProcessMode != ENGINE_PROCESS_MODE_MULTIPLE_CLIENTS) | |||||
| { | |||||
| CARLA_SAFE_ASSERT_RETURN(fBuffer != nullptr,); | |||||
| delete[] fBuffer; | |||||
| fBuffer = nullptr; | |||||
| } | |||||
| } | } | ||||
| void CarlaEngineCVPort::initBuffer() | void CarlaEngineCVPort::initBuffer() | ||||
| { | { | ||||
| CARLA_SAFE_ASSERT_RETURN(fBuffer != nullptr,); | CARLA_SAFE_ASSERT_RETURN(fBuffer != nullptr,); | ||||
| CARLA_SAFE_ASSERT_RETURN(fProcessMode != ENGINE_PROCESS_MODE_SINGLE_CLIENT && fProcessMode != ENGINE_PROCESS_MODE_MULTIPLE_CLIENTS,); | |||||
| #ifdef HAVE_JUCE | #ifdef HAVE_JUCE | ||||
| FloatVectorOperations::clear(fBuffer, fEngine.getBufferSize()); | FloatVectorOperations::clear(fBuffer, fEngine.getBufferSize()); | ||||
| @@ -120,27 +129,22 @@ void CarlaEngineCVPort::initBuffer() | |||||
| #endif | #endif | ||||
| } | } | ||||
| #if 0 | |||||
| void CarlaEngineCVPort::writeBuffer(const uint32_t, const uint32_t) | |||||
| { | |||||
| CARLA_SAFE_ASSERT_RETURN(! fIsInput,); | |||||
| } | |||||
| void CarlaEngineCVPort::setBufferSize(const uint32_t bufferSize) | void CarlaEngineCVPort::setBufferSize(const uint32_t bufferSize) | ||||
| { | { | ||||
| if (fBuffer != nullptr) | |||||
| delete[] fBuffer; | |||||
| CARLA_SAFE_ASSERT_RETURN(fBuffer != nullptr,); | |||||
| CARLA_SAFE_ASSERT_RETURN(fProcessMode != ENGINE_PROCESS_MODE_SINGLE_CLIENT && fProcessMode != ENGINE_PROCESS_MODE_MULTIPLE_CLIENTS,); | |||||
| delete[] fBuffer; | |||||
| fBuffer = new float[bufferSize]; | fBuffer = new float[bufferSize]; | ||||
| } | } | ||||
| #endif | |||||
| // ----------------------------------------------------------------------- | // ----------------------------------------------------------------------- | ||||
| // Carla Engine Event port | // Carla Engine Event port | ||||
| CarlaEngineEventPort::CarlaEngineEventPort(const CarlaEngine& engine, const bool isInput) | CarlaEngineEventPort::CarlaEngineEventPort(const CarlaEngine& engine, const bool isInput) | ||||
| : CarlaEnginePort(engine, isInput), | : CarlaEnginePort(engine, isInput), | ||||
| fBuffer(nullptr) | |||||
| fBuffer(nullptr), | |||||
| fProcessMode(engine.getProccessMode()) | |||||
| { | { | ||||
| carla_debug("CarlaEngineEventPort::CarlaEngineEventPort(%s)", bool2str(isInput)); | carla_debug("CarlaEngineEventPort::CarlaEngineEventPort(%s)", bool2str(isInput)); | ||||
| @@ -152,7 +156,7 @@ CarlaEngineEventPort::CarlaEngineEventPort(const CarlaEngine& engine, const bool | |||||
| sFallbackEngineEventNeedsInit = false; | sFallbackEngineEventNeedsInit = false; | ||||
| } | } | ||||
| if (fEngine.getProccessMode() == ENGINE_PROCESS_MODE_PATCHBAY) | |||||
| if (fProcessMode == ENGINE_PROCESS_MODE_PATCHBAY) | |||||
| fBuffer = new EngineEvent[kEngineMaxInternalEventCount]; | fBuffer = new EngineEvent[kEngineMaxInternalEventCount]; | ||||
| } | } | ||||
| @@ -160,7 +164,7 @@ CarlaEngineEventPort::~CarlaEngineEventPort() | |||||
| { | { | ||||
| carla_debug("CarlaEngineEventPort::~CarlaEngineEventPort()"); | carla_debug("CarlaEngineEventPort::~CarlaEngineEventPort()"); | ||||
| if (fEngine.getProccessMode() == ENGINE_PROCESS_MODE_PATCHBAY) | |||||
| if (fProcessMode == ENGINE_PROCESS_MODE_PATCHBAY) | |||||
| { | { | ||||
| CARLA_SAFE_ASSERT_RETURN(fBuffer != nullptr,); | CARLA_SAFE_ASSERT_RETURN(fBuffer != nullptr,); | ||||
| @@ -171,9 +175,9 @@ CarlaEngineEventPort::~CarlaEngineEventPort() | |||||
| void CarlaEngineEventPort::initBuffer() | void CarlaEngineEventPort::initBuffer() | ||||
| { | { | ||||
| if (fEngine.getProccessMode() == ENGINE_PROCESS_MODE_CONTINUOUS_RACK || fEngine.getProccessMode() == ENGINE_PROCESS_MODE_BRIDGE) | |||||
| if (fProcessMode == ENGINE_PROCESS_MODE_CONTINUOUS_RACK || fProcessMode == ENGINE_PROCESS_MODE_BRIDGE) | |||||
| fBuffer = fEngine.getInternalEventBuffer(fIsInput); | fBuffer = fEngine.getInternalEventBuffer(fIsInput); | ||||
| else if (fEngine.getProccessMode() == ENGINE_PROCESS_MODE_PATCHBAY && ! fIsInput) | |||||
| else if (fProcessMode == ENGINE_PROCESS_MODE_PATCHBAY && ! fIsInput) | |||||
| carla_zeroStruct<EngineEvent>(fBuffer, kEngineMaxInternalEventCount); | carla_zeroStruct<EngineEvent>(fBuffer, kEngineMaxInternalEventCount); | ||||
| } | } | ||||
| @@ -181,7 +185,7 @@ uint32_t CarlaEngineEventPort::getEventCount() const | |||||
| { | { | ||||
| CARLA_SAFE_ASSERT_RETURN(fIsInput, 0); | CARLA_SAFE_ASSERT_RETURN(fIsInput, 0); | ||||
| CARLA_SAFE_ASSERT_RETURN(fBuffer != nullptr, 0); | CARLA_SAFE_ASSERT_RETURN(fBuffer != nullptr, 0); | ||||
| CARLA_SAFE_ASSERT_RETURN(fEngine.getProccessMode() != ENGINE_PROCESS_MODE_SINGLE_CLIENT && fEngine.getProccessMode() != ENGINE_PROCESS_MODE_MULTIPLE_CLIENTS, 0); | |||||
| CARLA_SAFE_ASSERT_RETURN(fProcessMode != ENGINE_PROCESS_MODE_SINGLE_CLIENT && fProcessMode != ENGINE_PROCESS_MODE_MULTIPLE_CLIENTS, 0); | |||||
| uint32_t i=0; | uint32_t i=0; | ||||
| @@ -198,7 +202,7 @@ const EngineEvent& CarlaEngineEventPort::getEvent(const uint32_t index) | |||||
| { | { | ||||
| CARLA_SAFE_ASSERT_RETURN(fIsInput, kFallbackEngineEvent); | CARLA_SAFE_ASSERT_RETURN(fIsInput, kFallbackEngineEvent); | ||||
| CARLA_SAFE_ASSERT_RETURN(fBuffer != nullptr, kFallbackEngineEvent); | CARLA_SAFE_ASSERT_RETURN(fBuffer != nullptr, kFallbackEngineEvent); | ||||
| CARLA_SAFE_ASSERT_RETURN(fEngine.getProccessMode() != ENGINE_PROCESS_MODE_SINGLE_CLIENT && fEngine.getProccessMode() != ENGINE_PROCESS_MODE_MULTIPLE_CLIENTS, kFallbackEngineEvent); | |||||
| CARLA_SAFE_ASSERT_RETURN(fProcessMode != ENGINE_PROCESS_MODE_SINGLE_CLIENT && fProcessMode != ENGINE_PROCESS_MODE_MULTIPLE_CLIENTS, kFallbackEngineEvent); | |||||
| CARLA_SAFE_ASSERT_RETURN(index < kEngineMaxInternalEventCount, kFallbackEngineEvent); | CARLA_SAFE_ASSERT_RETURN(index < kEngineMaxInternalEventCount, kFallbackEngineEvent); | ||||
| return fBuffer[index]; | return fBuffer[index]; | ||||
| @@ -213,7 +217,7 @@ bool CarlaEngineEventPort::writeControlEvent(const uint32_t time, const uint8_t | |||||
| { | { | ||||
| CARLA_SAFE_ASSERT_RETURN(! fIsInput, false); | CARLA_SAFE_ASSERT_RETURN(! fIsInput, false); | ||||
| CARLA_SAFE_ASSERT_RETURN(fBuffer != nullptr, false); | CARLA_SAFE_ASSERT_RETURN(fBuffer != nullptr, false); | ||||
| CARLA_SAFE_ASSERT_RETURN(fEngine.getProccessMode() != ENGINE_PROCESS_MODE_SINGLE_CLIENT && fEngine.getProccessMode() != ENGINE_PROCESS_MODE_MULTIPLE_CLIENTS, false); | |||||
| CARLA_SAFE_ASSERT_RETURN(fProcessMode != ENGINE_PROCESS_MODE_SINGLE_CLIENT && fProcessMode != ENGINE_PROCESS_MODE_MULTIPLE_CLIENTS, false); | |||||
| CARLA_SAFE_ASSERT_RETURN(type != kEngineControlEventTypeNull, false); | CARLA_SAFE_ASSERT_RETURN(type != kEngineControlEventTypeNull, false); | ||||
| CARLA_SAFE_ASSERT_RETURN(channel < MAX_MIDI_CHANNELS, false); | CARLA_SAFE_ASSERT_RETURN(channel < MAX_MIDI_CHANNELS, false); | ||||
| CARLA_SAFE_ASSERT(value >= 0.0f && value <= 1.0f); | CARLA_SAFE_ASSERT(value >= 0.0f && value <= 1.0f); | ||||
| @@ -247,14 +251,14 @@ bool CarlaEngineEventPort::writeControlEvent(const uint32_t time, const uint8_t | |||||
| return false; | return false; | ||||
| } | } | ||||
| bool CarlaEngineEventPort::writeMidiEvent(const uint32_t time, const uint8_t channel, const uint8_t port, const uint8_t* const data, const uint8_t size) | |||||
| bool CarlaEngineEventPort::writeMidiEvent(const uint32_t time, const uint8_t channel, const uint8_t port, const uint8_t size, const uint8_t* const data) | |||||
| { | { | ||||
| CARLA_SAFE_ASSERT_RETURN(! fIsInput, false); | CARLA_SAFE_ASSERT_RETURN(! fIsInput, false); | ||||
| CARLA_SAFE_ASSERT_RETURN(fBuffer != nullptr, false); | CARLA_SAFE_ASSERT_RETURN(fBuffer != nullptr, false); | ||||
| CARLA_SAFE_ASSERT_RETURN(fEngine.getProccessMode() != ENGINE_PROCESS_MODE_SINGLE_CLIENT && fEngine.getProccessMode() != ENGINE_PROCESS_MODE_MULTIPLE_CLIENTS, false); | |||||
| CARLA_SAFE_ASSERT_RETURN(fProcessMode != ENGINE_PROCESS_MODE_SINGLE_CLIENT && fProcessMode != ENGINE_PROCESS_MODE_MULTIPLE_CLIENTS, false); | |||||
| CARLA_SAFE_ASSERT_RETURN(channel < MAX_MIDI_CHANNELS, false); | CARLA_SAFE_ASSERT_RETURN(channel < MAX_MIDI_CHANNELS, false); | ||||
| CARLA_SAFE_ASSERT_RETURN(size > 0 && size <= EngineMidiEvent::kDataSize, false); | |||||
| CARLA_SAFE_ASSERT_RETURN(data != nullptr, false); | CARLA_SAFE_ASSERT_RETURN(data != nullptr, false); | ||||
| CARLA_SAFE_ASSERT_RETURN(size > 0 && size <= 4, false); | |||||
| for (uint32_t i=0; i < kEngineMaxInternalEventCount; ++i) | for (uint32_t i=0; i < kEngineMaxInternalEventCount; ++i) | ||||
| { | { | ||||
| @@ -270,7 +274,7 @@ bool CarlaEngineEventPort::writeMidiEvent(const uint32_t time, const uint8_t cha | |||||
| event.midi.port = port; | event.midi.port = port; | ||||
| event.midi.size = size; | event.midi.size = size; | ||||
| event.midi.data[0] = MIDI_GET_CHANNEL_FROM_DATA(data); | |||||
| event.midi.data[0] = MIDI_GET_STATUS_FROM_DATA(data); | |||||
| for (uint8_t j=1; j < size; ++j) | for (uint8_t j=1; j < size; ++j) | ||||
| event.midi.data[j] = data[j]; | event.midi.data[j] = data[j]; | ||||
| @@ -38,6 +38,8 @@ CARLA_BACKEND_START_NAMESPACE | |||||
| } // Fix editor indentation | } // Fix editor indentation | ||||
| #endif | #endif | ||||
| class CarlaEngineJack; | |||||
| // ----------------------------------------------------------------------- | // ----------------------------------------------------------------------- | ||||
| // Fallback data | // Fallback data | ||||
| @@ -71,7 +73,11 @@ public: | |||||
| carla_debug("CarlaEngineJackAudioPort::~CarlaEngineJackAudioPort()"); | carla_debug("CarlaEngineJackAudioPort::~CarlaEngineJackAudioPort()"); | ||||
| if (fClient != nullptr && fPort != nullptr) | if (fClient != nullptr && fPort != nullptr) | ||||
| { | |||||
| jackbridge_port_unregister(fClient, fPort); | jackbridge_port_unregister(fClient, fPort); | ||||
| fClient = nullptr; | |||||
| fPort = nullptr; | |||||
| } | |||||
| } | } | ||||
| void initBuffer() override | void initBuffer() override | ||||
| @@ -130,7 +136,11 @@ public: | |||||
| carla_debug("CarlaEngineJackCVPort::~CarlaEngineJackCVPort()"); | carla_debug("CarlaEngineJackCVPort::~CarlaEngineJackCVPort()"); | ||||
| if (fClient != nullptr && fPort != nullptr) | if (fClient != nullptr && fPort != nullptr) | ||||
| { | |||||
| jackbridge_port_unregister(fClient, fPort); | jackbridge_port_unregister(fClient, fPort); | ||||
| fClient = nullptr; | |||||
| fPort = nullptr; | |||||
| } | |||||
| } | } | ||||
| void initBuffer() override | void initBuffer() override | ||||
| @@ -140,40 +150,18 @@ public: | |||||
| const uint32_t bufferSize(fEngine.getBufferSize()); | const uint32_t bufferSize(fEngine.getBufferSize()); | ||||
| if (fIsInput) | |||||
| { | |||||
| float* const jackBuffer((float*)jackbridge_port_get_buffer(fPort, bufferSize)); | |||||
| #ifdef HAVE_JUCE | |||||
| FloatVectorOperations::copy(fBuffer, jackBuffer, bufferSize); | |||||
| #else | |||||
| carla_copyFloat(fBuffer, jackBuffer, bufferSize); | |||||
| #endif | |||||
| } | |||||
| else | |||||
| fBuffer = (float*)jackbridge_port_get_buffer(fPort, bufferSize); | |||||
| if (! fIsInput) | |||||
| { | { | ||||
| #ifdef HAVE_JUCE | #ifdef HAVE_JUCE | ||||
| FloatVectorOperations::clear(fBuffer, bufferSize); | |||||
| FloatVectorOperations::clear(fBuffer, bufferSize); | |||||
| #else | #else | ||||
| carla_zeroFloat(fBuffer, bufferSize); | |||||
| carla_zeroFloat(fBuffer, bufferSize); | |||||
| #endif | #endif | ||||
| } | } | ||||
| } | } | ||||
| #if 0 | |||||
| void writeBuffer(const uint32_t frames, const uint32_t timeOffset) override | |||||
| { | |||||
| CARLA_SAFE_ASSERT_RETURN(! fIsInput,); | |||||
| float* const jackBuffer((float*)jackbridge_port_get_buffer(fPort, fEngine.getBufferSize())); | |||||
| #ifdef HAVE_JUCE | |||||
| FloatVectorOperations::copy(jackBuffer+timeOffset, fBuffer, frames); | |||||
| #else | |||||
| carla_copyFloat(jackBuffer+timeOffset, fBuffer, frames); | |||||
| #endif | |||||
| } | |||||
| #endif | |||||
| private: | private: | ||||
| jack_client_t* fClient; | jack_client_t* fClient; | ||||
| jack_port_t* fPort; | jack_port_t* fPort; | ||||
| @@ -220,7 +208,11 @@ public: | |||||
| carla_debug("CarlaEngineJackEventPort::~CarlaEngineJackEventPort()"); | carla_debug("CarlaEngineJackEventPort::~CarlaEngineJackEventPort()"); | ||||
| if (fClient != nullptr && fPort != nullptr) | if (fClient != nullptr && fPort != nullptr) | ||||
| { | |||||
| jackbridge_port_unregister(fClient, fPort); | jackbridge_port_unregister(fClient, fPort); | ||||
| fClient = nullptr; | |||||
| fPort = nullptr; | |||||
| } | |||||
| } | } | ||||
| void initBuffer() override | void initBuffer() override | ||||
| @@ -263,10 +255,10 @@ public: | |||||
| if (! jackbridge_midi_event_get(&jackEvent, fJackBuffer, index)) | if (! jackbridge_midi_event_get(&jackEvent, fJackBuffer, index)) | ||||
| return kFallbackJackEngineEvent; | return kFallbackJackEngineEvent; | ||||
| if (jackEvent.size == 0 || jackEvent.size > 4) | |||||
| return kFallbackJackEngineEvent; | |||||
| fRetEvent.clear(); | |||||
| 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 midiStatus = MIDI_GET_STATUS_FROM_DATA(jackEvent.buffer); | ||||
| const uint8_t midiChannel = MIDI_GET_CHANNEL_FROM_DATA(jackEvent.buffer); | const uint8_t midiChannel = MIDI_GET_CHANNEL_FROM_DATA(jackEvent.buffer); | ||||
| @@ -276,13 +268,14 @@ public: | |||||
| if (midiStatus == MIDI_STATUS_CONTROL_CHANGE) | if (midiStatus == MIDI_STATUS_CONTROL_CHANGE) | ||||
| { | { | ||||
| CARLA_ASSERT(jackEvent.size == 2 || jackEvent.size == 3); | |||||
| fRetEvent.type = kEngineEventTypeControl; | |||||
| const uint8_t midiControl = jackEvent.buffer[1]; | const uint8_t midiControl = jackEvent.buffer[1]; | ||||
| fRetEvent.type = kEngineEventTypeControl; | |||||
| if (MIDI_IS_CONTROL_BANK_SELECT(midiControl)) | if (MIDI_IS_CONTROL_BANK_SELECT(midiControl)) | ||||
| { | { | ||||
| CARLA_SAFE_ASSERT_INT(jackEvent.size == 3, jackEvent.size); | |||||
| const uint8_t midiBank = jackEvent.buffer[2]; | const uint8_t midiBank = jackEvent.buffer[2]; | ||||
| fRetEvent.ctrl.type = kEngineControlEventTypeMidiBank; | fRetEvent.ctrl.type = kEngineControlEventTypeMidiBank; | ||||
| @@ -291,19 +284,23 @@ public: | |||||
| } | } | ||||
| else if (midiControl == MIDI_CONTROL_ALL_SOUND_OFF) | else if (midiControl == MIDI_CONTROL_ALL_SOUND_OFF) | ||||
| { | { | ||||
| CARLA_SAFE_ASSERT_INT(jackEvent.size == 2, jackEvent.size); | |||||
| fRetEvent.ctrl.type = kEngineControlEventTypeAllSoundOff; | fRetEvent.ctrl.type = kEngineControlEventTypeAllSoundOff; | ||||
| fRetEvent.ctrl.param = 0; | fRetEvent.ctrl.param = 0; | ||||
| fRetEvent.ctrl.value = 0.0f; | fRetEvent.ctrl.value = 0.0f; | ||||
| } | } | ||||
| else if (midiControl == MIDI_CONTROL_ALL_NOTES_OFF) | else if (midiControl == MIDI_CONTROL_ALL_NOTES_OFF) | ||||
| { | { | ||||
| CARLA_SAFE_ASSERT_INT(jackEvent.size == 2, jackEvent.size); | |||||
| fRetEvent.ctrl.type = kEngineControlEventTypeAllNotesOff; | fRetEvent.ctrl.type = kEngineControlEventTypeAllNotesOff; | ||||
| fRetEvent.ctrl.param = 0; | fRetEvent.ctrl.param = 0; | ||||
| fRetEvent.ctrl.value = 0.0f; | fRetEvent.ctrl.value = 0.0f; | ||||
| } | } | ||||
| else | else | ||||
| { | { | ||||
| CARLA_ASSERT(jackEvent.size == 3); | |||||
| CARLA_SAFE_ASSERT_INT2(jackEvent.size == 3, jackEvent.size, midiControl); | |||||
| const uint8_t midiValue = jackEvent.buffer[2]; | const uint8_t midiValue = jackEvent.buffer[2]; | ||||
| @@ -316,8 +313,9 @@ public: | |||||
| { | { | ||||
| CARLA_SAFE_ASSERT_INT2(jackEvent.size == 2, jackEvent.size, jackEvent.buffer[1]); | CARLA_SAFE_ASSERT_INT2(jackEvent.size == 2, jackEvent.size, jackEvent.buffer[1]); | ||||
| fRetEvent.type = kEngineEventTypeControl; | |||||
| const uint8_t midiProgram = jackEvent.buffer[1]; | const uint8_t midiProgram = jackEvent.buffer[1]; | ||||
| fRetEvent.type = kEngineEventTypeControl; | |||||
| fRetEvent.ctrl.type = kEngineControlEventTypeMidiProgram; | fRetEvent.ctrl.type = kEngineControlEventTypeMidiProgram; | ||||
| fRetEvent.ctrl.param = midiProgram; | fRetEvent.ctrl.param = midiProgram; | ||||
| @@ -327,13 +325,16 @@ public: | |||||
| { | { | ||||
| fRetEvent.type = kEngineEventTypeMidi; | fRetEvent.type = kEngineEventTypeMidi; | ||||
| fRetEvent.midi.port = 0; | |||||
| fRetEvent.midi.size = static_cast<uint8_t>(jackEvent.size); | |||||
| fRetEvent.midi.port = 0; | |||||
| fRetEvent.midi.size = static_cast<uint8_t>(jackEvent.size); | |||||
| fRetEvent.midi.data[0] = midiStatus; | fRetEvent.midi.data[0] = midiStatus; | ||||
| for (uint8_t i=1; i < fRetEvent.midi.size; ++i) | |||||
| uint8_t i=1; | |||||
| for (; i < fRetEvent.midi.size; ++i) | |||||
| fRetEvent.midi.data[i] = jackEvent.buffer[i]; | fRetEvent.midi.data[i] = jackEvent.buffer[i]; | ||||
| for (; i < EngineMidiEvent::kDataSize; ++i) | |||||
| fRetEvent.midi.data[i] = 0; | |||||
| } | } | ||||
| return fRetEvent; | return fRetEvent; | ||||
| @@ -359,7 +360,7 @@ public: | |||||
| const float fixedValue(carla_fixValue<float>(0.0f, 1.0f, value)); | const float fixedValue(carla_fixValue<float>(0.0f, 1.0f, value)); | ||||
| size_t size = 0; | size_t size = 0; | ||||
| jack_midi_data_t data[4] = { 0, 0, 0, 0 }; | |||||
| jack_midi_data_t data[3] = { 0, 0, 0 }; | |||||
| switch (type) | switch (type) | ||||
| { | { | ||||
| @@ -402,16 +403,16 @@ public: | |||||
| return jackbridge_midi_event_write(fJackBuffer, time, data, size); | return jackbridge_midi_event_write(fJackBuffer, time, data, size); | ||||
| } | } | ||||
| bool writeMidiEvent(const uint32_t time, const uint8_t channel, const uint8_t port, const uint8_t* const data, const uint8_t size) override | |||||
| bool writeMidiEvent(const uint32_t time, const uint8_t channel, const uint8_t port, const uint8_t size, const uint8_t* const data) override | |||||
| { | { | ||||
| if (fPort == nullptr) | if (fPort == nullptr) | ||||
| return CarlaEngineEventPort::writeMidiEvent(time, channel, port, data, size); | |||||
| return CarlaEngineEventPort::writeMidiEvent(time, channel, port, size, data); | |||||
| CARLA_SAFE_ASSERT_RETURN(! fIsInput, false); | CARLA_SAFE_ASSERT_RETURN(! fIsInput, false); | ||||
| CARLA_SAFE_ASSERT_RETURN(fJackBuffer != nullptr, false); | CARLA_SAFE_ASSERT_RETURN(fJackBuffer != nullptr, false); | ||||
| CARLA_SAFE_ASSERT_RETURN(channel < MAX_MIDI_CHANNELS, false); | CARLA_SAFE_ASSERT_RETURN(channel < MAX_MIDI_CHANNELS, false); | ||||
| CARLA_SAFE_ASSERT_RETURN(data != nullptr, false); | |||||
| CARLA_SAFE_ASSERT_RETURN(size > 0, false); | CARLA_SAFE_ASSERT_RETURN(size > 0, 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); | std::memset(jdata, 0, sizeof(jack_midi_data_t)*size); | ||||
| @@ -1144,7 +1145,7 @@ protected: | |||||
| if (fTransportPos.valid & JackPositionBBT) | if (fTransportPos.valid & JackPositionBBT) | ||||
| { | { | ||||
| pData->timeInfo.valid = EngineTimeInfo::ValidBBT; | |||||
| pData->timeInfo.valid = EngineTimeInfo::kValidBBT; | |||||
| pData->timeInfo.bbt.bar = fTransportPos.bar; | pData->timeInfo.bbt.bar = fTransportPos.bar; | ||||
| pData->timeInfo.bbt.beat = fTransportPos.beat; | pData->timeInfo.bbt.beat = fTransportPos.beat; | ||||
| pData->timeInfo.bbt.tick = fTransportPos.tick; | pData->timeInfo.bbt.tick = fTransportPos.tick; | ||||
| @@ -2498,14 +2498,14 @@ public: | |||||
| // BBT | // BBT | ||||
| case LV2_PORT_DESIGNATION_TIME_BAR: | case LV2_PORT_DESIGNATION_TIME_BAR: | ||||
| if ((timeInfo.valid & EngineTimeInfo::ValidBBT) != 0 && fLastTimeInfo.bbt.bar != timeInfo.bbt.bar) | |||||
| if ((timeInfo.valid & EngineTimeInfo::kValidBBT) != 0 && fLastTimeInfo.bbt.bar != timeInfo.bbt.bar) | |||||
| { | { | ||||
| fParamBuffers[k] = timeInfo.bbt.bar - 1; | fParamBuffers[k] = timeInfo.bbt.bar - 1; | ||||
| doPostRt = true; | doPostRt = true; | ||||
| } | } | ||||
| break; | break; | ||||
| case LV2_PORT_DESIGNATION_TIME_BAR_BEAT: | case LV2_PORT_DESIGNATION_TIME_BAR_BEAT: | ||||
| if ((timeInfo.valid & EngineTimeInfo::ValidBBT) != 0 && (fLastTimeInfo.bbt.tick != timeInfo.bbt.tick || | |||||
| if ((timeInfo.valid & EngineTimeInfo::kValidBBT) != 0 && (fLastTimeInfo.bbt.tick != timeInfo.bbt.tick || | |||||
| fLastTimeInfo.bbt.ticksPerBeat != timeInfo.bbt.ticksPerBeat)) | fLastTimeInfo.bbt.ticksPerBeat != timeInfo.bbt.ticksPerBeat)) | ||||
| { | { | ||||
| fParamBuffers[k] = timeInfo.bbt.beat - 1 + (double(timeInfo.bbt.tick) / timeInfo.bbt.ticksPerBeat); | fParamBuffers[k] = timeInfo.bbt.beat - 1 + (double(timeInfo.bbt.tick) / timeInfo.bbt.ticksPerBeat); | ||||
| @@ -2513,28 +2513,28 @@ public: | |||||
| } | } | ||||
| break; | break; | ||||
| case LV2_PORT_DESIGNATION_TIME_BEAT: | case LV2_PORT_DESIGNATION_TIME_BEAT: | ||||
| if ((timeInfo.valid & EngineTimeInfo::ValidBBT) != 0 && fLastTimeInfo.bbt.beat != timeInfo.bbt.beat) | |||||
| if ((timeInfo.valid & EngineTimeInfo::kValidBBT) != 0 && fLastTimeInfo.bbt.beat != timeInfo.bbt.beat) | |||||
| { | { | ||||
| fParamBuffers[k] = timeInfo.bbt.beat - 1; | fParamBuffers[k] = timeInfo.bbt.beat - 1; | ||||
| doPostRt = true; | doPostRt = true; | ||||
| } | } | ||||
| break; | break; | ||||
| case LV2_PORT_DESIGNATION_TIME_BEAT_UNIT: | case LV2_PORT_DESIGNATION_TIME_BEAT_UNIT: | ||||
| if ((timeInfo.valid & EngineTimeInfo::ValidBBT) != 0 && fLastTimeInfo.bbt.beatType != timeInfo.bbt.beatType) | |||||
| if ((timeInfo.valid & EngineTimeInfo::kValidBBT) != 0 && fLastTimeInfo.bbt.beatType != timeInfo.bbt.beatType) | |||||
| { | { | ||||
| fParamBuffers[k] = timeInfo.bbt.beatType; | fParamBuffers[k] = timeInfo.bbt.beatType; | ||||
| doPostRt = true; | doPostRt = true; | ||||
| } | } | ||||
| break; | break; | ||||
| case LV2_PORT_DESIGNATION_TIME_BEATS_PER_BAR: | case LV2_PORT_DESIGNATION_TIME_BEATS_PER_BAR: | ||||
| if ((timeInfo.valid & EngineTimeInfo::ValidBBT) != 0 && fLastTimeInfo.bbt.beatsPerBar != timeInfo.bbt.beatsPerBar) | |||||
| if ((timeInfo.valid & EngineTimeInfo::kValidBBT) != 0 && fLastTimeInfo.bbt.beatsPerBar != timeInfo.bbt.beatsPerBar) | |||||
| { | { | ||||
| fParamBuffers[k] = timeInfo.bbt.beatsPerBar; | fParamBuffers[k] = timeInfo.bbt.beatsPerBar; | ||||
| doPostRt = true; | doPostRt = true; | ||||
| } | } | ||||
| break; | break; | ||||
| case LV2_PORT_DESIGNATION_TIME_BEATS_PER_MINUTE: | case LV2_PORT_DESIGNATION_TIME_BEATS_PER_MINUTE: | ||||
| if ((timeInfo.valid & EngineTimeInfo::ValidBBT) != 0 && fLastTimeInfo.bbt.beatsPerMinute != timeInfo.bbt.beatsPerMinute) | |||||
| if ((timeInfo.valid & EngineTimeInfo::kValidBBT) != 0 && fLastTimeInfo.bbt.beatsPerMinute != timeInfo.bbt.beatsPerMinute) | |||||
| { | { | ||||
| fParamBuffers[k] = timeInfo.bbt.beatsPerMinute; | fParamBuffers[k] = timeInfo.bbt.beatsPerMinute; | ||||
| doPostRt = true; | doPostRt = true; | ||||
| @@ -2561,7 +2561,7 @@ public: | |||||
| lv2_atom_forge_property_head(&fAtomForge, CARLA_URI_MAP_ID_TIME_FRAME, 0); | lv2_atom_forge_property_head(&fAtomForge, CARLA_URI_MAP_ID_TIME_FRAME, 0); | ||||
| lv2_atom_forge_long(&fAtomForge, timeInfo.frame); | lv2_atom_forge_long(&fAtomForge, timeInfo.frame); | ||||
| if (timeInfo.valid & EngineTimeInfo::ValidBBT) | |||||
| if (timeInfo.valid & EngineTimeInfo::kValidBBT) | |||||
| { | { | ||||
| lv2_atom_forge_property_head(&fAtomForge, CARLA_URI_MAP_ID_TIME_BAR, 0); | lv2_atom_forge_property_head(&fAtomForge, CARLA_URI_MAP_ID_TIME_BAR, 0); | ||||
| lv2_atom_forge_long(&fAtomForge, timeInfo.bbt.bar - 1); | lv2_atom_forge_long(&fAtomForge, timeInfo.bbt.bar - 1); | ||||
| @@ -3000,7 +3000,7 @@ public: | |||||
| break; | break; | ||||
| if (ev->body.type == CARLA_URI_MAP_ID_MIDI_EVENT && fEventsOut.ctrl->port != nullptr) | if (ev->body.type == CARLA_URI_MAP_ID_MIDI_EVENT && fEventsOut.ctrl->port != nullptr) | ||||
| fEventsOut.ctrl->port->writeMidiEvent(ev->time.frames, data, ev->body.size); | |||||
| fEventsOut.ctrl->port->writeMidiEvent(ev->time.frames, ev->body.size, data); | |||||
| else if (ev->body.type == CARLA_URI_MAP_ID_ATOM_BLANK) | else if (ev->body.type == CARLA_URI_MAP_ID_ATOM_BLANK) | ||||
| fAtomQueueOut.put(&ev->body, rindex); | fAtomQueueOut.put(&ev->body, rindex); | ||||
| @@ -3025,7 +3025,7 @@ public: | |||||
| break; | break; | ||||
| if (ev->type == CARLA_URI_MAP_ID_MIDI_EVENT) | if (ev->type == CARLA_URI_MAP_ID_MIDI_EVENT) | ||||
| fEventsOut.ctrl->port->writeMidiEvent(ev->frames, data, ev->size); | |||||
| fEventsOut.ctrl->port->writeMidiEvent(ev->frames, ev->size, data); | |||||
| lv2_event_increment(&iter); | lv2_event_increment(&iter); | ||||
| } | } | ||||
| @@ -3043,7 +3043,7 @@ public: | |||||
| if (eventData == nullptr || eventSize == 0) | if (eventData == nullptr || eventSize == 0) | ||||
| break; | break; | ||||
| fEventsOut.ctrl->port->writeMidiEvent(eventTime, eventData, eventSize); | |||||
| fEventsOut.ctrl->port->writeMidiEvent(eventTime, eventSize, eventData); | |||||
| lv2midi_step(&state); | lv2midi_step(&state); | ||||
| } | } | ||||
| } | } | ||||
| @@ -1262,7 +1262,7 @@ public: | |||||
| fTimeInfo.frame = timeInfo.frame; | fTimeInfo.frame = timeInfo.frame; | ||||
| fTimeInfo.usecs = timeInfo.usecs; | fTimeInfo.usecs = timeInfo.usecs; | ||||
| if (timeInfo.valid & EngineTimeInfo::ValidBBT) | |||||
| if (timeInfo.valid & EngineTimeInfo::kValidBBT) | |||||
| { | { | ||||
| fTimeInfo.bbt.valid = true; | fTimeInfo.bbt.valid = true; | ||||
| @@ -1640,9 +1640,9 @@ public: | |||||
| const uint8_t port = fMidiEvents[k].port; | const uint8_t port = fMidiEvents[k].port; | ||||
| if (pData->event.portOut != nullptr) | if (pData->event.portOut != nullptr) | ||||
| pData->event.portOut->writeMidiEvent(fMidiEvents[k].time, channel, port, fMidiEvents[k].data, fMidiEvents[k].size); | |||||
| pData->event.portOut->writeMidiEvent(fMidiEvents[k].time, channel, port, fMidiEvents[k].size, fMidiEvents[k].data); | |||||
| else if (port < fMidiOut.count) | else if (port < fMidiOut.count) | ||||
| fMidiOut.ports[port]->writeMidiEvent(fMidiEvents[k].time, channel, port, fMidiEvents[k].data, fMidiEvents[k].size); | |||||
| fMidiOut.ports[port]->writeMidiEvent(fMidiEvents[k].time, channel, port, fMidiEvents[k].size, fMidiEvents[k].data); | |||||
| } | } | ||||
| } // End of Control and MIDI Output | } // End of Control and MIDI Output | ||||
| @@ -1070,7 +1070,7 @@ public: | |||||
| fTimeInfo.flags |= kVstNanosValid; | fTimeInfo.flags |= kVstNanosValid; | ||||
| } | } | ||||
| if (timeInfo.valid & EngineTimeInfo::ValidBBT) | |||||
| if (timeInfo.valid & EngineTimeInfo::kValidBBT) | |||||
| { | { | ||||
| double ppqBar = double(timeInfo.bbt.bar - 1) * timeInfo.bbt.beatsPerBar; | double ppqBar = double(timeInfo.bbt.bar - 1) * timeInfo.bbt.beatsPerBar; | ||||
| double ppqBeat = double(timeInfo.bbt.beat - 1); | double ppqBeat = double(timeInfo.bbt.beat - 1); | ||||
| @@ -1436,7 +1436,7 @@ public: | |||||
| midiData[1] = fMidiEvents[k].midiData[1]; | midiData[1] = fMidiEvents[k].midiData[1]; | ||||
| midiData[2] = fMidiEvents[k].midiData[2]; | midiData[2] = fMidiEvents[k].midiData[2]; | ||||
| pData->event.portOut->writeMidiEvent(fMidiEvents[k].deltaFrames, channel, 0, midiData, 3); | |||||
| pData->event.portOut->writeMidiEvent(fMidiEvents[k].deltaFrames, channel, 0, 3, midiData); | |||||
| } | } | ||||
| } // End of Control and MIDI Output | } // End of Control and MIDI Output | ||||
| @@ -837,7 +837,7 @@ const CarlaTransportInfo* carla_get_transport_info() | |||||
| retInfo.playing = timeInfo.playing; | retInfo.playing = timeInfo.playing; | ||||
| retInfo.frame = timeInfo.frame; | retInfo.frame = timeInfo.frame; | ||||
| if (timeInfo.valid & timeInfo.ValidBBT) | |||||
| if (timeInfo.valid & CB::EngineTimeInfo::kValidBBT) | |||||
| { | { | ||||
| retInfo.bar = timeInfo.bbt.bar; | retInfo.bar = timeInfo.bbt.bar; | ||||
| retInfo.beat = timeInfo.bbt.beat; | retInfo.beat = timeInfo.bbt.beat; | ||||