diff --git a/src/effects/lv2/LV2Effect.cpp b/src/effects/lv2/LV2Effect.cpp index 72723348c..c81991207 100644 --- a/src/effects/lv2/LV2Effect.cpp +++ b/src/effects/lv2/LV2Effect.cpp @@ -187,7 +187,7 @@ LV2EffectSettingsDialog::LV2EffectSettingsDialog(wxWindow *parent, LV2Effect *ef mEffect->mHost->GetSharedConfig(wxT("Settings"), wxT("UseLatency"), mUseLatency, true); mEffect->mHost->GetSharedConfig(wxT("Settings"), wxT("UseGUI"), mUseGUI, true); -wxPrintf(wxT("#1 usegui %d\n"), mUseGUI); + ShuttleGui S(this, eIsCreating); PopulateOrExchange(S); } @@ -296,6 +296,7 @@ LV2Effect::LV2Effect(const LilvPlugin *plug) mHost = NULL; mMaster = NULL; mProcess = NULL; + mSuilInstance = NULL; mSampleRate = 44100; mBlockSize = 512; @@ -317,6 +318,8 @@ LV2Effect::LV2Effect(const LilvPlugin *plug) mIdleFeature = NULL; mOptionsInterface = NULL; + + mFactoryPresetsLoaded = false; } LV2Effect::~LV2Effect() @@ -490,6 +493,7 @@ bool LV2Effect::SetHost(EffectHostInterface *host) ctrl.mIndex = index; // Get the port name + ctrl.mSymbol = LilvString(lilv_port_get_symbol(mPlug, port)); LilvNode *tmpName = lilv_port_get_name(mPlug, port); ctrl.mName = LilvString(tmpName); lilv_node_free(tmpName); @@ -632,7 +636,6 @@ bool LV2Effect::SetHost(EffectHostInterface *host) { mHost->GetSharedConfig(wxT("Settings"), wxT("UseLatency"), mUseLatency, true); mHost->GetSharedConfig(wxT("Settings"), wxT("UseGUI"), mUseGUI, true); -wxPrintf(wxT("#1 usegui %d\n"), mUseGUI); bool haveDefaults; mHost->GetPrivateConfig(mHost->GetFactoryDefaultsGroup(), wxT("Initialized"), haveDefaults, false); @@ -1049,7 +1052,6 @@ bool LV2Effect::PopulateUI(wxWindow *parent) wxT("UseGUI"), mUseGUI, true); -wxPrintf(wxT("#2 usegui %d\n"), mUseGUI); if (mUseGUI) { @@ -1133,7 +1135,12 @@ bool LV2Effect::CloseUI() bool LV2Effect::LoadUserPreset(const wxString & name) { - return LoadParameters(name); + if (!LoadParameters(name)) + { + return false; + } + + return TransferDataToWindow(); } bool LV2Effect::SaveUserPreset(const wxString & name) @@ -1143,22 +1150,86 @@ bool LV2Effect::SaveUserPreset(const wxString & name) wxArrayString LV2Effect::GetFactoryPresets() { - return wxArrayString(); + if (mFactoryPresetsLoaded) + { + return mFactoryPresetNames; + } + + LilvNodes* presets = lilv_plugin_get_related(mPlug, gPreset); + if (presets) + { + LILV_FOREACH(nodes, i, presets) + { + const LilvNode *preset = lilv_nodes_get(presets, i); + + mFactoryPresetUris.Add(LilvString(preset)); + + lilv_world_load_resource(gWorld, preset); + + LilvNodes *labels = lilv_world_find_nodes(gWorld, preset, gLabel, NULL); + if (labels) + { + const LilvNode *label = lilv_nodes_get_first(labels); + + mFactoryPresetNames.Add(LilvString(label)); + + lilv_nodes_free(labels); + } + else + { + mFactoryPresetNames.Add(LilvString(preset).AfterLast(wxT('#'))); + } + } + + lilv_nodes_free(presets); + } + + mFactoryPresetsLoaded = true; + + return mFactoryPresetNames; } -bool LV2Effect::LoadFactoryPreset(int WXUNUSED(id)) +bool LV2Effect::LoadFactoryPreset(int id) { - return true; + if (id < 0 || id >= (int) mFactoryPresetUris.GetCount()) + { + return false; + } + + LilvNode *preset = lilv_new_uri(gWorld, mFactoryPresetUris[id].ToUTF8()); + if (!preset) + { + return false; + } + + LilvState *state = lilv_state_new_from_world(gWorld, &mURIDMapFeature, preset); + if (state) + { + lilv_state_restore(state, mMaster, set_value_func, this, 0, NULL); + + lilv_state_free(state); + + TransferDataToWindow(); + } + + lilv_node_free(preset); + + return state != NULL; } bool LV2Effect::LoadFactoryDefaults() { - return LoadParameters(mHost->GetFactoryDefaultsGroup()); + if (!LoadParameters(mHost->GetFactoryDefaultsGroup())) + { + return false; + } + + return TransferDataToWindow(); } bool LV2Effect::CanExportPresets() { - return true; + return false; } void LV2Effect::ExportPresets() @@ -1449,7 +1520,7 @@ bool LV2Effect::BuildFancy() mIdleFeature = (const LV2UI_Idle_Interface *) suil_instance_extension_data(mSuilInstance, LV2_UI__idleInterface); - UIRefresh(); + TransferDataToWindow(); return true; } @@ -1747,6 +1818,26 @@ bool LV2Effect::BuildPlain() bool LV2Effect::TransferDataToWindow() { + if (mUseGUI) + { + if (mSuilInstance) + { + for (size_t p = 0, cnt = mControls.GetCount(); p < cnt; p++) + { + if (mControls[p].mInput) + { + suil_instance_port_event(mSuilInstance, + mControls[p].mIndex, + sizeof(float), + 0, + &mControls[p].mVal); + } + } + } + + return true; + } + if (!mParent->TransferDataToWindow()) { return false; @@ -1870,24 +1961,6 @@ void LV2Effect::OnIdle(wxIdleEvent & WXUNUSED(evt)) } } -void LV2Effect::UIRefresh() -{ - if (mSuilInstance) - { - for (size_t p = 0, cnt = mControls.GetCount(); p < cnt; p++) - { - if (mControls[p].mInput) - { - suil_instance_port_event(mSuilInstance, - p, - sizeof(float), - 0, - &mControls[p].mVal); - } - } - } -} - // ============================================================================ // Feature handlers // ============================================================================ @@ -1980,4 +2053,56 @@ void LV2Effect::UIWrite(uint32_t port_index, } } +// static callback +void LV2Effect::set_value_func(const char *port_symbol, + void *user_data, + const void *value, + uint32_t size, + uint32_t type) +{ + ((LV2Effect *)user_data)->SetPortValue(port_symbol, value, size, type); +} + +void LV2Effect::SetPortValue(const char *port_symbol, + const void *value, + uint32_t size, + uint32_t type) +{ + wxString symbol = wxString::FromUTF8(port_symbol); + LV2_URID Bool = URID_Map(lilv_node_as_string(gBool)); + LV2_URID Double = URID_Map(lilv_node_as_string(gDouble)); + LV2_URID Float = URID_Map(lilv_node_as_string(gFloat)); + LV2_URID Int = URID_Map(lilv_node_as_string(gInt)); + LV2_URID Long = URID_Map(lilv_node_as_string(gLong)); + + for (size_t p = 0, cnt = mControls.GetCount(); p < cnt; p++) + { + if (mControls[p].mSymbol.IsSameAs(symbol)) + { + if (type == Bool && size == sizeof(bool)) + { + mControls[p].mVal = (float) *((const bool *) value) ? 1.0f : 0.0f; + } + else if (type == Double && size == sizeof(double)) + { + mControls[p].mVal = (float) *((const double *) value); + } + else if (type == Float && size == sizeof(float)) + { + mControls[p].mVal = (float) *((const float *) value); + } + else if (type == Int && size == sizeof(int32_t)) + { + mControls[p].mVal = (float) *((const int32_t *) value); + } + else if (type == Long && size == sizeof(int64_t)) + { + mControls[p].mVal = (float) *((const int64_t *) value); + } + + break; + } + } +} + #endif diff --git a/src/effects/lv2/LV2Effect.h b/src/effects/lv2/LV2Effect.h index 03f4387f0..d8d623fd7 100644 --- a/src/effects/lv2/LV2Effect.h +++ b/src/effects/lv2/LV2Effect.h @@ -57,6 +57,7 @@ public: } uint32_t mIndex; + wxString mSymbol; wxString mName; wxString mGroup; wxString mUnits; @@ -232,7 +233,16 @@ private: uint32_t protocol, const void *buffer); - void UIRefresh(); + static void set_value_func(const char *port_symbol, + void *user_data, + const void *value, + uint32_t size, + uint32_t type); + + void SetPortValue(const char *port_symbol, + const void *value, + uint32_t size, + uint32_t type); private: // Declare the static URI nodes @@ -308,6 +318,10 @@ private: wxSlider **mSliders; wxTextCtrl **mFields; + bool mFactoryPresetsLoaded; + wxArrayString mFactoryPresetNames; + wxArrayString mFactoryPresetUris; + DECLARE_EVENT_TABLE(); friend class LV2EffectSettingsDialog; diff --git a/src/effects/lv2/LoadLV2.h b/src/effects/lv2/LoadLV2.h index 507e533d1..61ab314f8 100644 --- a/src/effects/lv2/LoadLV2.h +++ b/src/effects/lv2/LoadLV2.h @@ -36,6 +36,11 @@ // Define the list of URIs that we will use #undef URILIST #define URILIST \ + URI( gBool, LV2_ATOM__Bool ) \ + URI( gDouble, LV2_ATOM__Double ) \ + URI( gFloat, LV2_ATOM__Float ) \ + URI( gInt, LV2_ATOM__Int ) \ + URI( gLong, LV2_ATOM__Long ) \ URI( gAudio, LV2_CORE__AudioPort ) \ URI( gControl, LV2_CORE__ControlPort ) \ URI( gInput, LV2_CORE__InputPort ) \