| @@ -752,6 +752,16 @@ public: | |||||
| return fTimeInfo; | return fTimeInfo; | ||||
| } | } | ||||
| /*! | |||||
| * TODO. | |||||
| */ | |||||
| float getInputPeak(const unsigned int pluginId, const unsigned short id) const; | |||||
| /*! | |||||
| * TODO. | |||||
| */ | |||||
| float getOutputPeak(const unsigned int pluginId, const unsigned short id) const; | |||||
| /*! | /*! | ||||
| * Tell the engine it's about to close.\n | * Tell the engine it's about to close.\n | ||||
| * This is used to prevent the engine thread(s) from reactivating. | * This is used to prevent the engine thread(s) from reactivating. | ||||
| @@ -763,16 +773,6 @@ public: | |||||
| */ | */ | ||||
| void waitForProccessEnd(); | void waitForProccessEnd(); | ||||
| #if 0 | |||||
| // ------------------------------------------------------------------- | |||||
| // Information (audio peaks) | |||||
| double getInputPeak(const unsigned short pluginId, const unsigned short id) const; | |||||
| double getOutputPeak(const unsigned short pluginId, const unsigned short id) const; | |||||
| void setInputPeak(const unsigned short pluginId, const unsigned short id, double value); | |||||
| void setOutputPeak(const unsigned short pluginId, const unsigned short id, double value); | |||||
| #endif | |||||
| // ------------------------------------------------------------------- | // ------------------------------------------------------------------- | ||||
| // Callback | // Callback | ||||
| @@ -881,6 +881,12 @@ protected: | |||||
| */ | */ | ||||
| void proccessPendingEvents(); | void proccessPendingEvents(); | ||||
| public: | |||||
| /*! | |||||
| * TODO. | |||||
| */ | |||||
| void setPeaks(const unsigned int pluginId, float* inPeaks, float* outPeaks); | |||||
| #ifndef BUILD_BRIDGE | #ifndef BUILD_BRIDGE | ||||
| // Rack mode data | // Rack mode data | ||||
| EngineEvent* getRackEventBuffer(const bool isInput); | EngineEvent* getRackEventBuffer(const bool isInput); | ||||
| @@ -735,9 +735,21 @@ public: | |||||
| // ------------------------------------------------------------------- | // ------------------------------------------------------------------- | ||||
| // Engine helpers | // Engine helpers | ||||
| /*! | |||||
| * TODO. | |||||
| */ | |||||
| float* getAudioInPortBuffer(uint32_t index); | float* getAudioInPortBuffer(uint32_t index); | ||||
| /*! | |||||
| * TODO. | |||||
| */ | |||||
| float* getAudioOutPortBuffer(uint32_t index); | float* getAudioOutPortBuffer(uint32_t index); | ||||
| /*! | |||||
| * TODO. | |||||
| */ | |||||
| CarlaEngine* getEngine() const; | |||||
| // ------------------------------------------------------------------- | // ------------------------------------------------------------------- | ||||
| // Plugin initializers | // Plugin initializers | ||||
| @@ -356,6 +356,14 @@ CarlaEngine::~CarlaEngine() | |||||
| // ----------------------------------------------------------------------- | // ----------------------------------------------------------------------- | ||||
| // Helpers | // Helpers | ||||
| void doIdle(CarlaEngineProtectedData* const fData, const bool unlock) | |||||
| { | |||||
| fData->nextAction.opcode = EnginePostActionNull; | |||||
| if (unlock) | |||||
| fData->nextAction.mutex.unlock(); | |||||
| } | |||||
| void doPluginRemove(CarlaEngineProtectedData* const fData, const bool unlock) | void doPluginRemove(CarlaEngineProtectedData* const fData, const bool unlock) | ||||
| { | { | ||||
| CARLA_ASSERT(fData->curPluginCount > 0); | CARLA_ASSERT(fData->curPluginCount > 0); | ||||
| @@ -937,48 +945,49 @@ void CarlaEngine::__bridgePluginRegister(const unsigned short id, CarlaPlugin* c | |||||
| // ----------------------------------------------------------------------- | // ----------------------------------------------------------------------- | ||||
| // Information (base) | // Information (base) | ||||
| void CarlaEngine::setAboutToClose() | |||||
| { | |||||
| qDebug("CarlaEngine::setAboutToClose()"); | |||||
| fData->aboutToClose = true; | |||||
| } | |||||
| #if 0 | |||||
| // ----------------------------------------------------------------------- | |||||
| // Information (audio peaks) | |||||
| double CarlaEngine::getInputPeak(const unsigned short pluginId, const unsigned short id) const | |||||
| float CarlaEngine::getInputPeak(const unsigned int pluginId, const unsigned short id) const | |||||
| { | { | ||||
| CARLA_ASSERT(pluginId < data->maxPluginNumber); | |||||
| CARLA_ASSERT(pluginId < fData->curPluginCount); | |||||
| CARLA_ASSERT(id < MAX_PEAKS); | CARLA_ASSERT(id < MAX_PEAKS); | ||||
| return data->insPeak[pluginId*MAX_PEAKS + id]; | |||||
| return fData->plugins[pluginId].insPeak[id]; | |||||
| } | } | ||||
| double CarlaEngine::getOutputPeak(const unsigned short pluginId, const unsigned short id) const | |||||
| float CarlaEngine::getOutputPeak(const unsigned int pluginId, const unsigned short id) const | |||||
| { | { | ||||
| CARLA_ASSERT(pluginId < data->maxPluginNumber); | |||||
| CARLA_ASSERT(pluginId < fData->curPluginCount); | |||||
| CARLA_ASSERT(id < MAX_PEAKS); | CARLA_ASSERT(id < MAX_PEAKS); | ||||
| return data->outsPeak[pluginId*MAX_PEAKS + id]; | |||||
| return fData->plugins[pluginId].outsPeak[id]; | |||||
| } | } | ||||
| void CarlaEngine::setInputPeak(const unsigned short pluginId, const unsigned short id, double value) | |||||
| void CarlaEngine::setAboutToClose() | |||||
| { | { | ||||
| CARLA_ASSERT(pluginId < data->maxPluginNumber); | |||||
| CARLA_ASSERT(id < MAX_PEAKS); | |||||
| data->insPeak[pluginId*MAX_PEAKS + id] = value; | |||||
| qDebug("CarlaEngine::setAboutToClose()"); | |||||
| fData->aboutToClose = true; | |||||
| } | } | ||||
| void CarlaEngine::setOutputPeak(const unsigned short pluginId, const unsigned short id, double value) | |||||
| void CarlaEngine::waitForProccessEnd() | |||||
| { | { | ||||
| CARLA_ASSERT(pluginId < data->maxPluginNumber); | |||||
| CARLA_ASSERT(id < MAX_PEAKS); | |||||
| qDebug("CarlaEngine::waitForProccessEnd()"); | |||||
| fData->nextAction.pluginId = 0; | |||||
| fData->nextAction.opcode = EnginePostActionIdle; | |||||
| data->outsPeak[pluginId*MAX_PEAKS + id] = value; | |||||
| fData->nextAction.mutex.lock(); | |||||
| if (isRunning()) | |||||
| { | |||||
| // block wait for unlock on proccessing side | |||||
| fData->nextAction.mutex.lock(); | |||||
| } | |||||
| else | |||||
| { | |||||
| doIdle(fData, false); | |||||
| } | |||||
| fData->nextAction.mutex.unlock(); | |||||
| } | } | ||||
| #endif | |||||
| // ----------------------------------------------------------------------- | // ----------------------------------------------------------------------- | ||||
| // Callback | // Callback | ||||
| @@ -1219,12 +1228,26 @@ void CarlaEngine::proccessPendingEvents() | |||||
| { | { | ||||
| case EnginePostActionNull: | case EnginePostActionNull: | ||||
| break; | break; | ||||
| case EnginePostActionIdle: | |||||
| doIdle(fData, true); | |||||
| break; | |||||
| case EnginePostActionRemovePlugin: | case EnginePostActionRemovePlugin: | ||||
| doPluginRemove(fData, true); | doPluginRemove(fData, true); | ||||
| break; | break; | ||||
| } | } | ||||
| // TODO - peak values | |||||
| for (unsigned int i=0; i < fData->curPluginCount; i++) | |||||
| { | |||||
| // TODO - peak values | |||||
| } | |||||
| } | |||||
| void CarlaEngine::setPeaks(const unsigned int pluginId, float* inPeaks, float* outPeaks) | |||||
| { | |||||
| fData->plugins[pluginId].insPeak[0] = inPeaks[0]; | |||||
| fData->plugins[pluginId].insPeak[1] = inPeaks[1]; | |||||
| fData->plugins[pluginId].outsPeak[0] = outPeaks[0]; | |||||
| fData->plugins[pluginId].outsPeak[1] = outPeaks[1]; | |||||
| } | } | ||||
| #ifndef BUILD_BRIDGE | #ifndef BUILD_BRIDGE | ||||
| @@ -119,6 +119,7 @@ struct EnginePostEvent { | |||||
| enum EnginePostAction { | enum EnginePostAction { | ||||
| EnginePostActionNull, | EnginePostActionNull, | ||||
| EnginePostActionIdle, | |||||
| EnginePostActionRemovePlugin | EnginePostActionRemovePlugin | ||||
| }; | }; | ||||
| @@ -129,8 +130,8 @@ struct EnginePluginData { | |||||
| EnginePluginData() | EnginePluginData() | ||||
| : plugin(nullptr), | : plugin(nullptr), | ||||
| insPeak{ 0.0f }, | |||||
| outsPeak{ 0.0f } {} | |||||
| insPeak{0.0f}, | |||||
| outsPeak{0.0f} {} | |||||
| }; | }; | ||||
| // ------------------------------------------------------------------------------------------------------------------- | // ------------------------------------------------------------------------------------------------------------------- | ||||
| @@ -1011,13 +1011,44 @@ private: | |||||
| float* inBuffer[inCount]; | float* inBuffer[inCount]; | ||||
| float* outBuffer[outCount]; | float* outBuffer[outCount]; | ||||
| float inPeaks[inCount]; | |||||
| float outPeaks[outCount]; | |||||
| carla_zeroFloat(inPeaks, inCount); | |||||
| carla_zeroFloat(outPeaks, outCount); | |||||
| for (uint32_t i=0; i < inCount; i++) | for (uint32_t i=0; i < inCount; i++) | ||||
| inBuffer[i] = p->getAudioInPortBuffer(i); | inBuffer[i] = p->getAudioInPortBuffer(i); | ||||
| for (uint32_t i=0; i < outCount; i++) | for (uint32_t i=0; i < outCount; i++) | ||||
| outBuffer[i] = p->getAudioOutPortBuffer(i); | outBuffer[i] = p->getAudioOutPortBuffer(i); | ||||
| for (uint32_t i=0; i < inCount; i++) | |||||
| { | |||||
| for (uint32_t j=0; j < nframes; j++) | |||||
| { | |||||
| const float absV = std::abs(inBuffer[i][j]); | |||||
| if (absV > inPeaks[i]) | |||||
| inPeaks[i] = absV; | |||||
| } | |||||
| } | |||||
| p->process(inBuffer, outBuffer, nframes); | p->process(inBuffer, outBuffer, nframes); | ||||
| for (uint32_t i=0; i < outCount; i++) | |||||
| { | |||||
| for (uint32_t j=0; j < nframes; j++) | |||||
| { | |||||
| const float absV = std::abs(outBuffer[i][j]); | |||||
| if (absV > outPeaks[i]) | |||||
| outPeaks[i] = absV; | |||||
| } | |||||
| } | |||||
| if (CarlaEngine* const engine = p->getEngine()) | |||||
| engine->setPeaks(p->id(), inPeaks, outPeaks); | |||||
| } | } | ||||
| static void latencyPlugin(CarlaPlugin* const p, jack_latency_callback_mode_t mode) | static void latencyPlugin(CarlaPlugin* const p, jack_latency_callback_mode_t mode) | ||||
| @@ -31,6 +31,7 @@ endif | |||||
| OBJS = \ | OBJS = \ | ||||
| carla_plugin.cpp.o \ | carla_plugin.cpp.o \ | ||||
| carla_plugin_thread.cpp.o \ | carla_plugin_thread.cpp.o \ | ||||
| carla_bridge.cpp.o \ | |||||
| native.cpp.o \ | native.cpp.o \ | ||||
| ladspa.cpp.o \ | ladspa.cpp.o \ | ||||
| dssi.cpp.o \ | dssi.cpp.o \ | ||||
| @@ -39,8 +40,6 @@ OBJS = \ | |||||
| fluidsynth.cpp.o \ | fluidsynth.cpp.o \ | ||||
| linuxsampler.cpp.o | linuxsampler.cpp.o | ||||
| # carla_bridge.cpp.o | |||||
| SHARED = ../libcarla_plugin.so | SHARED = ../libcarla_plugin.so | ||||
| STATIC = ../libcarla_plugin.a | STATIC = ../libcarla_plugin.a | ||||
| @@ -1421,6 +1421,11 @@ float* CarlaPlugin::getAudioOutPortBuffer(uint32_t index) | |||||
| return fData->audioOut.ports[index].port->getBuffer(); | return fData->audioOut.ports[index].port->getBuffer(); | ||||
| } | } | ||||
| CarlaEngine* CarlaPlugin::getEngine() const | |||||
| { | |||||
| return fData->engine; | |||||
| } | |||||
| // ------------------------------------------------------------------- | // ------------------------------------------------------------------- | ||||
| // Scoped Disabler | // Scoped Disabler | ||||
| @@ -966,8 +966,8 @@ float carla_get_input_peak_value(unsigned int pluginId, unsigned short portId) | |||||
| return 0.0f; | return 0.0f; | ||||
| } | } | ||||
| //if (portId == 1 || portId == 2) | |||||
| // return standalone.engine->getInputPeak(pluginId, portId-1); | |||||
| if (portId == 1 || portId == 2) | |||||
| return standalone.engine->getInputPeak(pluginId, portId-1); | |||||
| qCritical("carla_get_input_peak_value(%i, %i) - invalid port value", pluginId, portId); | qCritical("carla_get_input_peak_value(%i, %i) - invalid port value", pluginId, portId); | ||||
| return 0.0f; | return 0.0f; | ||||
| @@ -987,8 +987,8 @@ float carla_get_output_peak_value(unsigned int pluginId, unsigned short portId) | |||||
| return 0.0f; | return 0.0f; | ||||
| } | } | ||||
| //if (portId == 1 || portId == 2) | |||||
| // return standalone.engine->getOutputPeak(pluginId, portId-1); | |||||
| if (portId == 1 || portId == 2) | |||||
| return standalone.engine->getOutputPeak(pluginId, portId-1); | |||||
| qCritical("carla_get_output_peak_value(%i, %i) - invalid port value", pluginId, portId); | qCritical("carla_get_output_peak_value(%i, %i) - invalid port value", pluginId, portId); | ||||
| return 0.0f; | return 0.0f; | ||||