diff --git a/source/backend/plugin/CarlaPluginLV2.cpp b/source/backend/plugin/CarlaPluginLV2.cpp index d04c71f4e..02d255032 100644 --- a/source/backend/plugin/CarlaPluginLV2.cpp +++ b/source/backend/plugin/CarlaPluginLV2.cpp @@ -304,7 +304,7 @@ struct CarlaPluginLV2Options { NominalBlockLenth, SequenceSize, SampleRate, - FrontendWinId, + TransientWinId, WindowTitle, Null, Count @@ -315,7 +315,7 @@ struct CarlaPluginLV2Options { int nominalBufferSize; int sequenceSize; double sampleRate; - int64_t frontendWinId; + int64_t transientWinId; const char* windowTitle; LV2_Options_Option opts[Count]; @@ -325,7 +325,7 @@ struct CarlaPluginLV2Options { nominalBufferSize(0), sequenceSize(MAX_DEFAULT_BUFFER_SIZE), sampleRate(0.0), - frontendWinId(0), + transientWinId(0), windowTitle(nullptr) { LV2_Options_Option& optMaxBlockLenth(opts[MaxBlockLenth]); @@ -368,13 +368,13 @@ struct CarlaPluginLV2Options { optSampleRate.type = CARLA_URI_MAP_ID_ATOM_DOUBLE; optSampleRate.value = &sampleRate; - LV2_Options_Option& optFrontendWinId(opts[FrontendWinId]); - optFrontendWinId.context = LV2_OPTIONS_INSTANCE; - optFrontendWinId.subject = 0; - optFrontendWinId.key = CARLA_URI_MAP_ID_CARLA_TRANSIENT_WIN_ID; - optFrontendWinId.size = sizeof(int64_t); - optFrontendWinId.type = CARLA_URI_MAP_ID_ATOM_LONG; - optFrontendWinId.value = &frontendWinId; + LV2_Options_Option& optTransientWinId(opts[TransientWinId]); + optTransientWinId.context = LV2_OPTIONS_INSTANCE; + optTransientWinId.subject = 0; + optTransientWinId.key = CARLA_URI_MAP_ID_CARLA_TRANSIENT_WIN_ID; + optTransientWinId.size = sizeof(int64_t); + optTransientWinId.type = CARLA_URI_MAP_ID_ATOM_LONG; + optTransientWinId.value = &transientWinId; LV2_Options_Option& optWindowTitle(opts[WindowTitle]); optWindowTitle.context = LV2_OPTIONS_INSTANCE; @@ -4932,7 +4932,7 @@ public: fLv2Options.maxBufferSize = bufferSize; fLv2Options.nominalBufferSize = bufferSize; fLv2Options.sampleRate = pData->engine->getSampleRate(); - fLv2Options.frontendWinId = static_cast(pData->engine->getOptions().frontendWinId); + fLv2Options.transientWinId = static_cast(pData->engine->getOptions().frontendWinId); uint32_t eventBufferSize = MAX_DEFAULT_BUFFER_SIZE; @@ -4957,23 +4957,23 @@ public: eventFt->lv2_event_ref = carla_lv2_event_ref; eventFt->lv2_event_unref = carla_lv2_event_unref; - LV2_Log_Log* const logFt = new LV2_Log_Log; - logFt->handle = this; - logFt->printf = carla_lv2_log_printf; - logFt->vprintf = carla_lv2_log_vprintf; + LV2_Log_Log* const logFt = new LV2_Log_Log; + logFt->handle = this; + logFt->printf = carla_lv2_log_printf; + logFt->vprintf = carla_lv2_log_vprintf; LV2_State_Make_Path* const stateMakePathFt = new LV2_State_Make_Path; stateMakePathFt->handle = this; stateMakePathFt->path = carla_lv2_state_make_path; - LV2_State_Map_Path* const stateMapPathFt = new LV2_State_Map_Path; - stateMapPathFt->handle = this; - stateMapPathFt->abstract_path = carla_lv2_state_map_abstract_path; - stateMapPathFt->absolute_path = carla_lv2_state_map_absolute_path; + LV2_State_Map_Path* const stateMapPathFt = new LV2_State_Map_Path; + stateMapPathFt->handle = this; + stateMapPathFt->abstract_path = carla_lv2_state_map_abstract_path; + stateMapPathFt->absolute_path = carla_lv2_state_map_absolute_path; - LV2_Programs_Host* const programsFt = new LV2_Programs_Host; - programsFt->handle = this; - programsFt->program_changed = carla_lv2_program_changed; + LV2_Programs_Host* const programsFt = new LV2_Programs_Host; + programsFt->handle = this; + programsFt->program_changed = carla_lv2_program_changed; LV2_Resize_Port_Resize* const rsPortFt = new LV2_Resize_Port_Resize; rsPortFt->data = this; @@ -4989,13 +4989,13 @@ public: uriMapFt->callback_data = this; uriMapFt->uri_to_id = carla_lv2_uri_to_id; - LV2_URID_Map* const uridMapFt = new LV2_URID_Map; - uridMapFt->handle = this; - uridMapFt->map = carla_lv2_urid_map; + LV2_URID_Map* const uridMapFt = new LV2_URID_Map; + uridMapFt->handle = this; + uridMapFt->map = carla_lv2_urid_map; - LV2_URID_Unmap* const uridUnmapFt = new LV2_URID_Unmap; - uridUnmapFt->handle = this; - uridUnmapFt->unmap = carla_lv2_urid_unmap; + LV2_URID_Unmap* const uridUnmapFt = new LV2_URID_Unmap; + uridUnmapFt->handle = this; + uridUnmapFt->unmap = carla_lv2_urid_unmap; LV2_Worker_Schedule* const workerFt = new LV2_Worker_Schedule; workerFt->handle = this; diff --git a/source/bridges-ui/CarlaBridgeUI-LV2.cpp b/source/bridges-ui/CarlaBridgeUI-LV2.cpp index 04c6e18b8..bae69baf7 100644 --- a/source/bridges-ui/CarlaBridgeUI-LV2.cpp +++ b/source/bridges-ui/CarlaBridgeUI-LV2.cpp @@ -1,6 +1,6 @@ /* * Carla Bridge UI, LV2 version - * Copyright (C) 2011-2014 Filipe Coelho + * Copyright (C) 2011-2017 Filipe Coelho * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License as @@ -34,7 +34,6 @@ CARLA_BRIDGE_START_NAMESPACE // ----------------------------------------------------- -static int gBufferSize = 1024; static double gSampleRate = 44100.0; // Maximum default buffer size @@ -92,91 +91,50 @@ const uint32_t CARLA_URI_MAP_ID_CARLA_TRANSIENT_WIN_ID = 47; const uint32_t CARLA_URI_MAP_ID_COUNT = 48; // LV2 Feature Ids -const uint32_t kFeatureIdLogs = 0; -const uint32_t kFeatureIdOptions = 1; -const uint32_t kFeatureIdPrograms = 2; -const uint32_t kFeatureIdStateMakePath = 3; -const uint32_t kFeatureIdStateMapPath = 4; -const uint32_t kFeatureIdUriMap = 5; -const uint32_t kFeatureIdUridMap = 6; -const uint32_t kFeatureIdUridUnmap = 7; -const uint32_t kFeatureIdUiIdleInterface = 8; -const uint32_t kFeatureIdUiFixedSize = 9; -const uint32_t kFeatureIdUiMakeResident = 10; -const uint32_t kFeatureIdUiMakeResident2 = 11; -const uint32_t kFeatureIdUiNoUserResize = 12; -const uint32_t kFeatureIdUiParent = 13; -const uint32_t kFeatureIdUiPortMap = 14; -const uint32_t kFeatureIdUiPortSubscribe = 15; -const uint32_t kFeatureIdUiResize = 16; -const uint32_t kFeatureIdUiTouch = 17; -const uint32_t kFeatureCount = 18; +enum CarlaLv2Features { + // DSP features + kFeatureIdLogs = 0, + kFeatureIdOptions, + kFeatureIdPrograms, + kFeatureIdStateMakePath, + kFeatureIdStateMapPath, + kFeatureIdUriMap, + kFeatureIdUridMap, + kFeatureIdUridUnmap, + kFeatureIdUiIdleInterface, + kFeatureIdUiFixedSize, + kFeatureIdUiMakeResident, + kFeatureIdUiMakeResident2, + kFeatureIdUiNoUserResize, + kFeatureIdUiParent, + kFeatureIdUiPortMap, + kFeatureIdUiPortSubscribe, + kFeatureIdUiResize, + kFeatureIdUiTouch, + kFeatureCount +}; // ------------------------------------------------------------------------- struct Lv2PluginOptions { enum OptIndex { - MaxBlockLenth = 0, - MinBlockLenth, - NominalBlockLenth, - SequenceSize, SampleRate, - FrontendWinId, - //WindowTitle, + TransientWinId, + WindowTitle, Null, Count }; - int maxBufferSize; - int minBufferSize; - int nominalBufferSize; - int sequenceSize; double sampleRate; - int64_t frontendWinId; + int64_t transientWinId; const char* windowTitle; LV2_Options_Option opts[Count]; Lv2PluginOptions() noexcept - : maxBufferSize(0), - minBufferSize(0), - nominalBufferSize(0), - sequenceSize(MAX_DEFAULT_BUFFER_SIZE), - sampleRate(0.0), - frontendWinId(0), + : sampleRate(0.0), + transientWinId(0), windowTitle(nullptr) { - LV2_Options_Option& optMaxBlockLenth(opts[MaxBlockLenth]); - optMaxBlockLenth.context = LV2_OPTIONS_INSTANCE; - optMaxBlockLenth.subject = 0; - optMaxBlockLenth.key = CARLA_URI_MAP_ID_BUF_MAX_LENGTH; - optMaxBlockLenth.size = sizeof(int); - optMaxBlockLenth.type = CARLA_URI_MAP_ID_ATOM_INT; - optMaxBlockLenth.value = &maxBufferSize; - - LV2_Options_Option& optMinBlockLenth(opts[MinBlockLenth]); - optMinBlockLenth.context = LV2_OPTIONS_INSTANCE; - optMinBlockLenth.subject = 0; - optMinBlockLenth.key = CARLA_URI_MAP_ID_BUF_MIN_LENGTH; - optMinBlockLenth.size = sizeof(int); - optMinBlockLenth.type = CARLA_URI_MAP_ID_ATOM_INT; - optMinBlockLenth.value = &minBufferSize; - - LV2_Options_Option& optNominalBlockLenth(opts[NominalBlockLenth]); - optNominalBlockLenth.context = LV2_OPTIONS_INSTANCE; - optNominalBlockLenth.subject = 0; - optNominalBlockLenth.key = CARLA_URI_MAP_ID_BUF_NOMINAL_LENGTH; - optNominalBlockLenth.size = sizeof(int); - optNominalBlockLenth.type = CARLA_URI_MAP_ID_ATOM_INT; - optNominalBlockLenth.value = &nominalBufferSize; - - LV2_Options_Option& optSequenceSize(opts[SequenceSize]); - optSequenceSize.context = LV2_OPTIONS_INSTANCE; - optSequenceSize.subject = 0; - optSequenceSize.key = CARLA_URI_MAP_ID_BUF_SEQUENCE_SIZE; - optSequenceSize.size = sizeof(int); - optSequenceSize.type = CARLA_URI_MAP_ID_ATOM_INT; - optSequenceSize.value = &sequenceSize; - LV2_Options_Option& optSampleRate(opts[SampleRate]); optSampleRate.context = LV2_OPTIONS_INSTANCE; optSampleRate.subject = 0; @@ -185,15 +143,14 @@ struct Lv2PluginOptions { optSampleRate.type = CARLA_URI_MAP_ID_ATOM_DOUBLE; optSampleRate.value = &sampleRate; - LV2_Options_Option& optFrontendWinId(opts[FrontendWinId]); - optFrontendWinId.context = LV2_OPTIONS_INSTANCE; - optFrontendWinId.subject = 0; - optFrontendWinId.key = CARLA_URI_MAP_ID_CARLA_TRANSIENT_WIN_ID; - optFrontendWinId.size = sizeof(int64_t); - optFrontendWinId.type = CARLA_URI_MAP_ID_ATOM_LONG; - optFrontendWinId.value = &frontendWinId; + LV2_Options_Option& optTransientWinId(opts[TransientWinId]); + optTransientWinId.context = LV2_OPTIONS_INSTANCE; + optTransientWinId.subject = 0; + optTransientWinId.key = CARLA_URI_MAP_ID_CARLA_TRANSIENT_WIN_ID; + optTransientWinId.size = sizeof(int64_t); + optTransientWinId.type = CARLA_URI_MAP_ID_ATOM_LONG; + optTransientWinId.value = &transientWinId; - /* LV2_Options_Option& optWindowTitle(opts[WindowTitle]); optWindowTitle.context = LV2_OPTIONS_INSTANCE; optWindowTitle.subject = 0; @@ -201,7 +158,6 @@ struct Lv2PluginOptions { optWindowTitle.size = 0; optWindowTitle.type = CARLA_URI_MAP_ID_ATOM_STRING; optWindowTitle.value = nullptr; - */ LV2_Options_Option& optNull(opts[Null]); optNull.context = LV2_OPTIONS_INSTANCE; @@ -237,43 +193,40 @@ public: // --------------------------------------------------------------- // initialize options - fLv2Options.minBufferSize = gBufferSize; - fLv2Options.maxBufferSize = gBufferSize; - fLv2Options.nominalBufferSize = gBufferSize; - fLv2Options.sampleRate = gSampleRate; + fLv2Options.sampleRate = gSampleRate; // --------------------------------------------------------------- // initialize features (part 1) - LV2_Log_Log* const logFt = new LV2_Log_Log; - logFt->handle = this; - logFt->printf = carla_lv2_log_printf; - logFt->vprintf = carla_lv2_log_vprintf; + LV2_Log_Log* const logFt = new LV2_Log_Log; + logFt->handle = this; + logFt->printf = carla_lv2_log_printf; + logFt->vprintf = carla_lv2_log_vprintf; LV2_State_Make_Path* const stateMakePathFt = new LV2_State_Make_Path; stateMakePathFt->handle = this; stateMakePathFt->path = carla_lv2_state_make_path; - LV2_State_Map_Path* const stateMapPathFt = new LV2_State_Map_Path; - stateMapPathFt->handle = this; - stateMapPathFt->abstract_path = carla_lv2_state_map_abstract_path; - stateMapPathFt->absolute_path = carla_lv2_state_map_absolute_path; + LV2_State_Map_Path* const stateMapPathFt = new LV2_State_Map_Path; + stateMapPathFt->handle = this; + stateMapPathFt->abstract_path = carla_lv2_state_map_abstract_path; + stateMapPathFt->absolute_path = carla_lv2_state_map_absolute_path; - LV2_Programs_Host* const programsFt = new LV2_Programs_Host; - programsFt->handle = this; - programsFt->program_changed = carla_lv2_program_changed; + LV2_Programs_Host* const programsFt = new LV2_Programs_Host; + programsFt->handle = this; + programsFt->program_changed = carla_lv2_program_changed; LV2_URI_Map_Feature* const uriMapFt = new LV2_URI_Map_Feature; uriMapFt->callback_data = this; uriMapFt->uri_to_id = carla_lv2_uri_to_id; - LV2_URID_Map* const uridMapFt = new LV2_URID_Map; - uridMapFt->handle = this; - uridMapFt->map = carla_lv2_urid_map; + LV2_URID_Map* const uridMapFt = new LV2_URID_Map; + uridMapFt->handle = this; + uridMapFt->map = carla_lv2_urid_map; - LV2_URID_Unmap* const uridUnmapFt = new LV2_URID_Unmap; - uridUnmapFt->handle = this; - uridUnmapFt->unmap = carla_lv2_urid_unmap; + LV2_URID_Unmap* const uridUnmapFt = new LV2_URID_Unmap; + uridUnmapFt->handle = this; + uridUnmapFt->unmap = carla_lv2_urid_unmap; LV2UI_Port_Map* const uiPortMapFt = new LV2UI_Port_Map; uiPortMapFt->handle = this; @@ -624,7 +577,13 @@ public: { carla_debug("CarlaLv2Client::uiOptionsChanged(%g, %s, %s, \"%s\", " P_UINTPTR ")", sampleRate, bool2str(useTheme), bool2str(useThemeColors), windowTitle, transientWindowId); - fLv2Options.sampleRate = gSampleRate = sampleRate; + delete[] fLv2Options.windowTitle; + + gSampleRate = sampleRate; + + fLv2Options.sampleRate = sampleRate; + fLv2Options.transientWinId = static_cast(transientWindowId); + fLv2Options.windowTitle = carla_strdup_safe(windowTitle); fUiOptions.useTheme = useTheme; fUiOptions.useThemeColors = useThemeColors; @@ -711,33 +670,40 @@ public: return 0; } - void handleUiWrite(uint32_t portIndex, uint32_t bufferSize, uint32_t format, const void* buffer) + void handleUiWrite(uint32_t rindex, uint32_t bufferSize, uint32_t format, const void* buffer) { CARLA_SAFE_ASSERT_RETURN(buffer != nullptr,); CARLA_SAFE_ASSERT_RETURN(bufferSize > 0,); - carla_debug("CarlaLv2Client::handleUiWrite(%i, %i, %i, %p)", portIndex, bufferSize, format, buffer); + carla_debug("CarlaLv2Client::handleUiWrite(%i, %i, %i, %p)", rindex, bufferSize, format, buffer); - if (format == 0) + switch (format) { + case CARLA_URI_MAP_ID_NULL: { CARLA_SAFE_ASSERT_RETURN(bufferSize == sizeof(float),); const float value(*(const float*)buffer); if (isPipeRunning()) - writeControlMessage(portIndex, value); - } - else if (format == CARLA_URI_MAP_ID_ATOM_TRANSFER_ATOM || CARLA_URI_MAP_ID_ATOM_TRANSFER_EVENT) - { + writeControlMessage(rindex, value); + + } break; + + case CARLA_URI_MAP_ID_ATOM_TRANSFER_ATOM: + case CARLA_URI_MAP_ID_ATOM_TRANSFER_EVENT: { CARLA_SAFE_ASSERT_RETURN(bufferSize >= sizeof(LV2_Atom),); const LV2_Atom* const atom((const LV2_Atom*)buffer); + // plugins sometimes fail on this, not good... + CARLA_SAFE_ASSERT_INT2(bufferSize == lv2_atom_total_size(atom), bufferSize, atom->size); + if (isPipeRunning()) - writeLv2AtomMessage(portIndex, atom); - } - else - { - carla_stdout("CarlaLv2Client::handleUiWrite(%i, %i, %i:\"%s\", %p) - unknown format", portIndex, bufferSize, format, carla_lv2_urid_unmap(this, format), buffer); + writeLv2AtomMessage(rindex, atom); + } break; + + default: + carla_stdout("CarlaLv2Client::handleUiWrite(%i, %i, %i:\"%s\", %p) - unknown format", rindex, bufferSize, format, carla_lv2_urid_unmap(this, format), buffer); + break; } } @@ -869,8 +835,8 @@ private: static char* carla_lv2_state_map_abstract_path(LV2_State_Map_Path_Handle handle, const char* absolute_path) { - CARLA_SAFE_ASSERT_RETURN(handle != nullptr, nullptr); - CARLA_SAFE_ASSERT_RETURN(absolute_path != nullptr && absolute_path[0] != '\0', nullptr); + CARLA_SAFE_ASSERT_RETURN(handle != nullptr, strdup("")); + CARLA_SAFE_ASSERT_RETURN(absolute_path != nullptr && absolute_path[0] != '\0', strdup("")); carla_debug("carla_lv2_state_map_abstract_path(%p, \"%s\")", handle, absolute_path); // may already be an abstract path @@ -882,8 +848,9 @@ private: static char* carla_lv2_state_map_absolute_path(LV2_State_Map_Path_Handle handle, const char* abstract_path) { - CARLA_SAFE_ASSERT_RETURN(handle != nullptr, nullptr); - CARLA_SAFE_ASSERT_RETURN(abstract_path != nullptr && abstract_path[0] != '\0', nullptr); + const char* const cwd(File::getCurrentWorkingDirectory().getFullPathName().toRawUTF8()); + CARLA_SAFE_ASSERT_RETURN(handle != nullptr, strdup(cwd)); + CARLA_SAFE_ASSERT_RETURN(abstract_path != nullptr && abstract_path[0] != '\0', strdup(cwd)); carla_debug("carla_lv2_state_map_absolute_path(%p, \"%s\")", handle, abstract_path); // may already be an absolute path