void VampEffect::AddFeatures(LabelTrack *ltrack, Vamp::Plugin::FeatureSet &features) { for (Vamp::Plugin::FeatureList::iterator fli = features[mOutput].begin(); fli != features[mOutput].end(); ++fli) { Vamp::RealTime ftime0 = fli->timestamp; double ltime0 = ftime0.sec + (double(ftime0.nsec) / 1000000000.0); Vamp::RealTime ftime1 = ftime0; if (fli->hasDuration) ftime1 = ftime0 + fli->duration; double ltime1 = ftime1.sec + (double(ftime1.nsec) / 1000000000.0); wxString label = LAT1CTOWX(fli->label.c_str()); if (label == wxString()) { if (fli->values.empty()) { label = wxString::Format(LAT1CTOWX("%.3f"), ltime0); } else { label = wxString::Format(LAT1CTOWX("%.3f"), *fli->values.begin()); } } ltrack->AddLabel(ltime0, ltime1, label); } }
wxString sf_header_shortname(int format) { SF_FORMAT_INFO format_info; char *tmp; int i; wxString s; memset(&format_info, 0, sizeof(format_info)); format_info.format = (format & SF_FORMAT_TYPEMASK); sf_command(NULL, SFC_GET_FORMAT_INFO, &format_info, sizeof(format_info)); tmp = (char *)malloc(strlen(format_info.name)+1); strcpy(tmp, format_info.name); i = 0; while(tmp[i]) { if (tmp[i]==' ') tmp[i] = 0; else i++; } s = LAT1CTOWX(tmp); free(tmp); return s; }
wxArrayString sf_get_all_extensions() { wxArrayString exts; SF_FORMAT_INFO format_info; int count, k; memset(&format_info, 0, sizeof(format_info)); sf_command(NULL, SFC_GET_FORMAT_MAJOR_COUNT, &count, sizeof(count)); for(k=0; k<count; k++) { format_info.format = k; sf_command(NULL, SFC_GET_FORMAT_MAJOR, &format_info, sizeof (format_info)) ; exts.Add(LAT1CTOWX(format_info.extension)); } // Some other extensions that are often sound files // but aren't included by libsndfile exts.Add(wxT("aif")); // AIFF file with a DOS-style extension exts.Add(wxT("ircam")); exts.Add(wxT("snd")); exts.Add(wxT("svx")); exts.Add(wxT("svx8")); exts.Add(wxT("sv16")); return exts; }
// // Returns the full path of program module (.exe, .dll, .so, .dylib) containing address // wxString FileNames::PathFromAddr(void *addr) { wxFileName name; #if defined(__WXMAC__) || defined(__WXGTK__) Dl_info info; if (dladdr(addr, &info)) { char realname[PLATFORM_MAX_PATH + 1]; int len; name = LAT1CTOWX(info.dli_fname); len = readlink(OSINPUT(name.GetFullPath()), realname, PLATFORM_MAX_PATH); if (len > 0) { realname[len] = 0; name.SetFullName(LAT1CTOWX(realname)); } } #elif defined(__WXMSW__) && defined(_UNICODE) // The GetModuleHandlEx() function did not appear until Windows XP and // GetModuleFileName() did appear until Windows 2000, so we have to // check for them at runtime. typedef BOOL (WINAPI *getmodulehandleex)(DWORD dwFlags, LPCWSTR lpModuleName, HMODULE* phModule); typedef DWORD (WINAPI *getmodulefilename)(HMODULE hModule, LPWCH lpFilename, DWORD nSize); getmodulehandleex gmhe = (getmodulehandleex) GetProcAddress(GetModuleHandle(TEXT("kernel32.dll")), "GetModuleHandleExW"); getmodulefilename gmfn = (getmodulefilename) GetProcAddress(GetModuleHandle(TEXT("kernel32.dll")), "GetModuleFileNameW"); if (gmhe != NULL && gmfn != NULL) { HMODULE module; if (gmhe(GET_MODULE_HANDLE_EX_FLAG_FROM_ADDRESS | GET_MODULE_HANDLE_EX_FLAG_UNCHANGED_REFCOUNT, (LPTSTR) addr, &module)) { TCHAR path[MAX_PATH]; DWORD nSize; nSize = gmfn(module, path, MAX_PATH); if (nSize && nSize < MAX_PATH) { name = LAT1CTOWX(path); } } } #endif return name.GetFullPath(); }
static void LoadLadspaEffect(wxSortedArrayString &uniq, wxString fname, DL_Array &dls) { wxLogNull logNo; LADSPA_Descriptor_Function mainFn = NULL; // Since we now have builtin VST support, ignore the VST bridge as it // causes duplicate menu entries to appear. wxFileName f(fname); if (f.GetName().CmpNoCase(wxT("vst-bridge")) == 0) { return; } // As a courtesy to some plug-ins that might be bridges to // open other plug-ins, we set the current working // directory to be the plug-in's directory. wxString saveOldCWD = ::wxGetCwd(); wxString prefix = ::wxPathOnly(fname); ::wxSetWorkingDirectory(prefix); wxDynamicLibrary* pDLL = new wxDynamicLibrary(); dls.push_back(pDLL); if (pDLL && pDLL->Load(fname, wxDL_LAZY)) { mainFn = (LADSPA_Descriptor_Function)(pDLL->GetSymbol(wxT(descriptorFnName))); } if (mainFn) { int index = 0; const LADSPA_Descriptor *data; data = mainFn(index); while(data) { wxString uniqid = wxString::Format(wxT("%08x-%s"), data->UniqueID, LAT1CTOWX(data->Label).c_str()); if (uniq.Index(uniqid) == wxNOT_FOUND) { uniq.Add(uniqid); std::set<wxString> categories; #if defined(USE_LIBLRDF) && defined(EFFECT_CATEGORIES) std::multimap<unsigned long, wxString>::const_iterator iter; iter = gPluginCategories.lower_bound(data->UniqueID); for ( ; (iter != gPluginCategories.end() && iter->first == data->UniqueID); ++iter) categories.insert(iter->second); #endif LadspaEffect *effect = new LadspaEffect(data, categories); EffectManager::Get().RegisterEffect(effect); } // Get next plugin index++; data = mainFn(index); } } ::wxSetWorkingDirectory(saveOldCWD); }
wxString VampEffect::GetEffectName() { if (mHasParameters) { return mName + LAT1CTOWX("..."); } else { return mName; } }
wxString sf_encoding_name(int encoding) { SF_FORMAT_INFO format_info; memset(&format_info, 0, sizeof(format_info)); format_info.format = (encoding & SF_FORMAT_SUBMASK); sf_command(NULL, SFC_GET_FORMAT_INFO, &format_info, sizeof(format_info)); return LAT1CTOWX(format_info.name); }
wxString sf_encoding_index_name(int i) { SF_FORMAT_INFO format_info ; memset(&format_info, 0, sizeof(format_info)); format_info.format = i; sf_command (NULL, SFC_GET_FORMAT_SUBTYPE, &format_info, sizeof (format_info)); return LAT1CTOWX(format_info.name); }
wxString EffectNyquist::NyquistToWxString(const char *nyqString) { wxString str(nyqString, wxConvUTF8); if (nyqString != NULL && nyqString[0] && str.IsEmpty()) { // invalid UTF-8 string, convert as Latin-1 str = _("[Warning: Nyquist returned invalid UTF-8 string, converted here as Latin-1]"); str += LAT1CTOWX(nyqString); } return str; }
wxString VSTEffect::GetString(int opcode, int index) { char buf[256]; buf[0] = '\0'; callDispatcher(opcode, index, 0, buf, 0.0); return LAT1CTOWX(buf); }
wxString sf_header_extension(int format) { SF_FORMAT_INFO format_info; memset(&format_info, 0, sizeof(format_info)); format_info.format = (format & SF_FORMAT_TYPEMASK); sf_command(NULL, SFC_GET_FORMAT_INFO, &format_info, sizeof(format_info)); return LAT1CTOWX(format_info.extension); }
wxString sf_header_index_name(int format) { SF_FORMAT_INFO format_info; memset(&format_info, 0, sizeof(format_info)); format_info.format = format; sf_command(NULL, SFC_GET_FORMAT_MAJOR, &format_info, sizeof (format_info)) ; return LAT1CTOWX(format_info.name); }
bool LadspaEffect::GetAutomationParameters(EffectAutomationParameters & parms) { for (unsigned long p = 0; p < mData->PortCount; p++) { LADSPA_PortDescriptor d = mData->PortDescriptors[p]; if (LADSPA_IS_PORT_CONTROL(d) && LADSPA_IS_PORT_INPUT(d)) { if (!parms.Write(LAT1CTOWX(mData->PortNames[p]), mInputControls[p])) { return false; } } } return true; }
bool LadspaEffect::SetAutomationParameters(EffectAutomationParameters & parms) { for (unsigned long p = 0; p < mData->PortCount; p++) { LADSPA_PortDescriptor d = mData->PortDescriptors[p]; if (LADSPA_IS_PORT_CONTROL(d) && LADSPA_IS_PORT_INPUT(d)) { wxString labelText = LAT1CTOWX(mData->PortNames[p]); double d = 0.0; if (!parms.Read(labelText, &d)) { return false; } mInputControls[p] = d; } } return true; }
wxString VampEffect::GetDescription() { return LAT1CTOWX(mPlugin->getCopyright().c_str()); }
VampEffectDialog::VampEffectDialog(VampEffect *effect, wxWindow *parent, Vamp::Plugin *plugin) : wxDialog(parent, -1, effect->GetEffectName(), wxDefaultPosition, wxDefaultSize, wxDEFAULT_DIALOG_STYLE | wxRESIZE_BORDER), mEffect(effect), mPlugin(plugin) { Vamp::Plugin::ProgramList programs = plugin->getPrograms(); mParameters = plugin->getParameterDescriptors(); #ifdef __WXMSW__ // On Windows, for some reason, wxWindows calls OnTextCtrl during creation // of the text control, and VampEffectDialog::OnTextCtrl calls HandleText, // which assumes all the fields have been initialized. // This can give us a bad pointer crash, so manipulate inSlider to // no-op HandleText during creation. inSlider = true; #else inSlider = false; #endif inText = false; int count = mParameters.size(); toggles = new wxCheckBox*[count]; sliders = new wxSlider*[count]; fields = new wxTextCtrl*[count]; labels = new wxStaticText*[count]; combos = new wxComboBox*[count]; wxControl *item; wxBoxSizer *vSizer = new wxBoxSizer(wxVERTICAL); item = new wxStaticText(this, 0, LAT1CTOWX(plugin->getName().c_str()) + wxString(_(" - Vamp audio analysis plugin"))); vSizer->Add(item, 0, wxALL, 5); item = new wxStaticText(this, 0, LAT1CTOWX(plugin->getDescription().c_str())); vSizer->Add(item, 0, wxALL, 5); item = new wxStaticText(this, 0, wxString(_("Author: ")) + LAT1CTOWX(plugin->getMaker().c_str())); vSizer->Add(item, 0, wxALL, 5); item = new wxStaticText(this, 0, LAT1CTOWX(plugin->getCopyright().c_str())); vSizer->Add(item, 0, wxALL, 5); wxScrolledWindow *w = new wxScrolledWindow(this, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxVSCROLL | wxTAB_TRAVERSAL); // Try to give the window a sensible default/minimum size w->SetMinSize(wxSize( wxMax(400, parent->GetSize().GetWidth() / 2), parent->GetSize().GetHeight() / 2)); w->SetScrollRate(0, 20); vSizer->Add(w, 1, wxEXPAND|wxALL, 5); vSizer->Add(CreateStdButtonSizer(this, eCancelButton|eOkButton), 0, wxEXPAND); SetSizer(vSizer); wxSizer *paramSizer = new wxStaticBoxSizer(wxVERTICAL, w, _("Plugin Settings")); wxFlexGridSizer *gridSizer = new wxFlexGridSizer(5, 0, 0); gridSizer->AddGrowableCol(3); programCombo = 0; if (!programs.empty()) { wxArrayString choices; wxString currentProgram = wxString(mPlugin->getCurrentProgram().c_str(), wxConvISO8859_1); for (size_t i = 0; i < programs.size(); ++i) { wxString choice = wxString(programs[i].c_str(), wxConvISO8859_1); choices.Add(choice); } gridSizer->Add(new wxStaticText(w, 0, _("Program")), 0, wxALIGN_CENTER_VERTICAL | wxALL, 5); programCombo = new wxComboBox(w, 9999, currentProgram, wxDefaultPosition, wxDefaultSize, choices, wxCB_READONLY); programCombo->SetName(_("Program")); gridSizer->Add(1, 1, 0); gridSizer->Add(1, 1, 0); gridSizer->Add(programCombo, 0, wxALIGN_CENTER_VERTICAL | wxEXPAND | wxALL, 5); ConnectFocus(programCombo); gridSizer->Add(1, 1, 0); } for (int p = 0; p < count; p++) { wxString labelText = LAT1CTOWX(mParameters[p].name.c_str()); item = new wxStaticText(w, 0, labelText + wxT(":")); item->SetName(labelText); gridSizer->Add(item, 0, wxALIGN_CENTER_VERTICAL | wxALL, 5); wxString fieldText; float value = mPlugin->getParameter(mParameters[p].identifier); toggles[p] = 0; combos[p] = 0; sliders[p] = 0; fields[p] = 0; if (mParameters[p].isQuantized && mParameters[p].quantizeStep == 1.0 && mParameters[p].minValue == 0.0 && mParameters[p].maxValue == 1.0) { toggles[p] = new wxCheckBox(w, p, wxT("")); toggles[p]->SetName(labelText); toggles[p]->SetValue(value > 0.5); gridSizer->Add(toggles[p], 0, wxALL, 5); ConnectFocus(toggles[p]); gridSizer->Add(1, 1, 0); gridSizer->Add(1, 1, 0); gridSizer->Add(1, 1, 0); } else if (mParameters[p].isQuantized && mParameters[p].quantizeStep == 1.0 && !mParameters[p].valueNames.empty()) { wxArrayString choices; wxString selected; for (size_t i = 0; i < mParameters[p].valueNames.size(); ++i) { wxString choice = wxString (mParameters[p].valueNames[i].c_str(), wxConvISO8859_1); if (int(value - mParameters[p].minValue + 0.5) == i) { selected = choice; } choices.Add(choice); } combos[p] = new wxComboBox(w, p, selected, wxDefaultPosition, wxDefaultSize, choices, wxCB_READONLY); combos[p]->SetName(labelText); gridSizer->Add(1, 1, 0); gridSizer->Add(1, 1, 0); gridSizer->Add(combos[p], 0, wxALIGN_CENTER_VERTICAL | wxEXPAND | wxALL, 5); ConnectFocus(combos[p]); gridSizer->Add(1, 1, 0); } else { fieldText = Internat::ToDisplayString(value); fields[p] = new wxTextCtrl(w, p, fieldText); fields[p]->SetName(labelText); gridSizer->Add(fields[p], 0, wxALIGN_CENTER_VERTICAL | wxALL, 5); ConnectFocus(fields[p]); wxString str = Internat::ToDisplayString(mParameters[p].minValue); item = new wxStaticText(w, 0, str); gridSizer->Add(item, 0, wxALIGN_CENTER_VERTICAL | wxALIGN_RIGHT | wxALL, 5); sliders[p] = new wxSlider(w, p, 0, 0, 1000, wxDefaultPosition, wxSize(100, -1)); sliders[p]->SetName(labelText); gridSizer->Add(sliders[p], 0, wxALIGN_CENTER_VERTICAL | wxEXPAND | wxALL, 5); ConnectFocus(sliders[p]); str = Internat::ToDisplayString(mParameters[p].maxValue); item = new wxStaticText(w, 0, str); gridSizer->Add(item, 0, wxALIGN_CENTER_VERTICAL | wxALIGN_LEFT | wxALL, 5); } } // Set all of the sliders based on the value in the // text fields inSlider = false; // Now we're ready for HandleText to actually do something. HandleText(); paramSizer->Add(gridSizer, 1, wxEXPAND | wxALL, 5); w->SetSizer(paramSizer); Layout(); Fit(); SetSizeHints(GetSize()); }
bool ImportPCM(wxWindow * parent, wxString fName, WaveTrack ** channels[], int *numChannels, DirManager * dirManager) { SF_INFO info; SNDFILE *fp; sampleFormat format; fp = sf_open_read(OSFILENAME(fName), &info); if (!fp) { char str[1000]; sf_error_str((SNDFILE *)NULL, str, 1000); wxMessageBox(LAT1CTOWX(str)); return false; } wxString progressStr; wxString formatName = sf_header_name(info.format & SF_FORMAT_TYPEMASK); progressStr.Printf(_("Importing %s File..."), formatName.c_str()); *numChannels = info.channels; *channels = new WaveTrack*[*numChannels]; if (info.pcmbitwidth > 16) format = floatSample; else format = int16Sample; int c; for(c=0; c<*numChannels; c++) { (*channels)[c] = new WaveTrack(dirManager, format, info.samplerate); (*channels)[c]->SetName(TrackNameFromFileName(fName)); (*channels)[c]->SetChannel(Track::MonoChannel); } if (*numChannels == 2) { (*channels)[0]->SetChannel(Track::LeftChannel); (*channels)[1]->SetChannel(Track::RightChannel); (*channels)[0]->SetLinked(true); (*channels)[1]->SetTeamed(true); } sampleCount fileTotalFrames = (sampleCount)info.frames; sampleCount maxBlockSize = (*channels)[0]->GetMaxBlockSize(); wxString copyEdit = gPrefs->Read(wxT("/FileFormats/CopyOrEditUncompressedData"), wxT("edit")); // Fall back to "edit" if it doesn't match anything else bool doEdit = true; if (copyEdit.IsSameAs(wxT("copy"), false)) doEdit = false; if (doEdit) { wxLogDebug(wxT("Importing PCM...ImportPCM \n")); // If this mode has been selected, we form the tracks as // aliases to the files we're editing, i.e. ("foo.wav", 12000-18000) // instead of actually making fresh copies of the samples. bool cancelling = false; GetActiveProject()->ProgressShow(_("Import"), progressStr); for (sampleCount i = 0; i < fileTotalFrames; i += maxBlockSize) { sampleCount blockLen = maxBlockSize; if (i + blockLen > fileTotalFrames) blockLen = fileTotalFrames - i; for(c=0; c<*numChannels; c++) (*channels)[c]->AppendAlias(fName, i, blockLen, c); cancelling = !GetActiveProject()->ProgressUpdate((int)((i*1000.0)/fileTotalFrames)); if (cancelling) i = fileTotalFrames; } GetActiveProject()->ProgressHide(); //printf(_("Time elapsed: %d\n"), wxGetElapsedTime()); if (cancelling) { for(c=0; c<*numChannels; c++) delete (*channels)[c]; delete[] (*channels); *channels = NULL; return false; } return true; } // Otherwise, we're in the "copy" mode, where we read in the actual // samples from the file and store our own local copy of the // samples in the tracks. samplePtr srcbuffer = NewSamples(maxBlockSize * (*numChannels), format); samplePtr buffer = NewSamples(maxBlockSize, format); sampleCount framescompleted = 0; bool cancelling = false; GetActiveProject->ProgressShow(_("Import"), progressStr); long block; do { block = maxBlockSize; if (format == int16Sample) block = sf_readf_short(fp, (short *)srcbuffer, block); else block = sf_readf_float(fp, (float *)srcbuffer, block); if (block) { for(c=0; c<(*numChannels); c++) { if (format==int16Sample) { if (info.pcmbitwidth == 8) { for(int j=0; j<block; j++) ((short *)buffer)[j] = ((short *)srcbuffer)[(*numChannels)*j+c] << 8; } else { for(int j=0; j<block; j++) ((short *)buffer)[j] = ((short *)srcbuffer)[(*numChannels)*j+c]; } } else for(int j=0; j<block; j++) ((float *)buffer)[j] = ((float *)srcbuffer)[(*numChannels)*j+c]; (*channels)[c]->Append(buffer, format, block); } framescompleted += block; } int progressvalue = (framescompleted > fileTotalFrames) ? fileTotalFrames : framescompleted; cancelling = !GetActiveProject()->ProgressUpdate((int)((progressvalue*1000.0)/fileTotalFrames)); if (cancelling) block = 0; } while (block > 0); GetActiveProject()->ProgressHide(); sf_close(fp); //printf("Time elapsed: %d\n", wxGetElapsedTime()); DeleteSamples(srcbuffer); DeleteSamples(buffer); if (cancelling) { for(c=0; c<*numChannels; c++) delete (*channels)[c]; delete[] (*channels); *channels = NULL; return false; } return true; }
LadspaEffectDialog::LadspaEffectDialog(LadspaEffect *eff, wxWindow * parent, const LADSPA_Descriptor *data, float *inputControls, int sampleRate, double length) :wxDialog(parent, -1, LAT1CTOWX(data->Name), wxDefaultPosition, wxDefaultSize, wxDEFAULT_DIALOG_STYLE | wxRESIZE_BORDER), effect(eff) { mLength = length; numParams = 0; this->mData = data; this->inputControls = inputControls; this->sampleRate = sampleRate; #ifdef __WXMSW__ // On Windows, for some reason, wxWindows calls OnTextCtrl during creation // of the text control, and LadspaEffectDialog::OnTextCtrl calls HandleText, // which assumes all the fields have been initialized. // This can give us a bad pointer crash, so manipulate inSlider to // no-op HandleText during creation. inSlider = true; #else inSlider = false; #endif inText = false; toggles = new wxCheckBox*[mData->PortCount]; sliders = new wxSlider*[mData->PortCount]; fields = new wxTextCtrl*[mData->PortCount]; labels = new wxStaticText*[mData->PortCount]; ports = new unsigned long [mData->PortCount]; unsigned long p; for(p=0; p<mData->PortCount; p++) { LADSPA_PortDescriptor d = mData->PortDescriptors[p]; if (LADSPA_IS_PORT_CONTROL(d) && LADSPA_IS_PORT_INPUT(d)) { ports[numParams] = p; numParams++; } } wxControl *item; wxBoxSizer *vSizer = new wxBoxSizer(wxVERTICAL); if (mData->Maker && mData->Maker[0] && LAT1CTOWX(mData->Maker) != wxString(_("None"))) { item = new wxStaticText(this, 0, wxString(_("Author: "))+LAT1CTOWX(mData->Maker)); vSizer->Add(item, 0, wxALL, 5); } if (mData->Copyright && mData->Copyright[0] && LAT1CTOWX(mData->Copyright) != wxString(_("None"))) { item = new wxStaticText(this, 0, LAT1CTOWX(mData->Copyright)); vSizer->Add(item, 0, wxALL, 5); } wxScrolledWindow *w = new wxScrolledWindow(this, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxVSCROLL | wxTAB_TRAVERSAL); // Try to give the window a sensible default/minimum size w->SetMinSize(wxSize( wxMax(600, parent->GetSize().GetWidth() * 2/3), parent->GetSize().GetHeight() / 2)); w->SetScrollRate(0, 20); vSizer->Add(w, 1, wxEXPAND|wxALL, 5); // Preview, OK, & Cancel buttons vSizer->Add(CreateStdButtonSizer(this, ePreviewButton|eCancelButton|eOkButton), 0, wxEXPAND); SetSizer(vSizer); wxSizer *paramSizer = new wxStaticBoxSizer(wxVERTICAL, w, _("Effect Settings")); wxFlexGridSizer *gridSizer = new wxFlexGridSizer(5, 0, 0); gridSizer->AddGrowableCol(3); for (p = 0; p < numParams; p++) { wxString labelText = LAT1CTOWX(mData->PortNames[ports[p]]); item = new wxStaticText(w, 0, labelText + wxT(":")); gridSizer->Add(item, 0, wxALIGN_CENTER_VERTICAL | wxALIGN_RIGHT | wxALL, 5); wxString fieldText; LADSPA_PortRangeHint hint = mData->PortRangeHints[ports[p]]; if (LADSPA_IS_HINT_TOGGLED(hint.HintDescriptor)) { toggles[p] = new wxCheckBox(w, p, wxT("")); toggles[p]->SetName(labelText); toggles[p]->SetValue(inputControls[ports[p]] > 0); gridSizer->Add(toggles[p], 0, wxALL, 5); ConnectFocus(toggles[p]); gridSizer->Add(1, 1, 0); gridSizer->Add(1, 1, 0); gridSizer->Add(1, 1, 0); } else { if (LADSPA_IS_HINT_INTEGER(hint.HintDescriptor)) fieldText.Printf(wxT("%d"), (int)(inputControls[ports[p]] + 0.5)); else fieldText = Internat::ToDisplayString(inputControls[ports[p]]); fields[p] = new wxTextCtrl(w, p, fieldText); fields[p]->SetName(labelText); gridSizer->Add(fields[p], 0, wxALIGN_CENTER_VERTICAL | wxALL, 5); ConnectFocus(fields[p]); wxString bound; double lower = 0.0; double upper = 0.0; bool haslo = false; bool hashi = false; bool forceint = false; if (LADSPA_IS_HINT_BOUNDED_BELOW(hint.HintDescriptor)) { lower = hint.LowerBound; haslo = true; } if (LADSPA_IS_HINT_BOUNDED_ABOVE(hint.HintDescriptor)) { upper = hint.UpperBound; hashi = true; } if (LADSPA_IS_HINT_SAMPLE_RATE(hint.HintDescriptor)) { lower *= sampleRate * 1000; upper *= sampleRate; forceint = true; } wxString str; if (haslo) { if (LADSPA_IS_HINT_INTEGER(hint.HintDescriptor) || forceint) str.Printf(wxT("%d"), (int)(lower + 0.5)); else str = Internat::ToDisplayString(lower); item = new wxStaticText(w, 0, str); gridSizer->Add(item, 0, wxALIGN_CENTER_VERTICAL | wxALIGN_RIGHT | wxALL, 5); } else { gridSizer->Add(1, 1, 0); } sliders[p] = new wxSlider(w, p, 0, 0, 1000, wxDefaultPosition, wxSize(200, -1)); sliders[p]->SetName(labelText); gridSizer->Add(sliders[p], 0, wxALIGN_CENTER_VERTICAL | wxEXPAND | wxALL, 5); ConnectFocus(sliders[p]); if (hashi) { if (LADSPA_IS_HINT_INTEGER(hint.HintDescriptor) || forceint) str.Printf(wxT("%d"), (int)(upper + 0.5)); else str = Internat::ToDisplayString(upper); item = new wxStaticText(w, 0, str); gridSizer->Add(item, 0, wxALIGN_CENTER_VERTICAL | wxALIGN_LEFT | wxALL, 5); } else { gridSizer->Add(1, 1, 0); } } } // Now add the length control if (effect->GetEffectFlags() & INSERT_EFFECT) { item = new wxStaticText(w, 0, _("Length (seconds)")); gridSizer->Add(item, 0, wxALIGN_CENTER_VERTICAL | wxALL, 5); mSeconds = new wxTextCtrl(w, LADSPA_SECONDS_ID, Internat::ToDisplayString(length)); mSeconds->SetName(_("Length (seconds)")); gridSizer->Add(mSeconds, 0, wxALIGN_CENTER_VERTICAL | wxALL, 5); gridSizer->Add(1, 1, 0); gridSizer->Add(1, 1, 0); gridSizer->Add(1, 1, 0); ConnectFocus(mSeconds); } // Set all of the sliders based on the value in the // text fields inSlider = false; // Now we're ready for HandleText to actually do something. HandleText(); paramSizer->Add(gridSizer, 1, wxEXPAND | wxALL, 5); w->SetSizer(paramSizer); Layout(); Fit(); SetSizeHints(GetSize()); }
LadspaEffect::LadspaEffect(const LADSPA_Descriptor *data, const std::set<wxString>& categories) : mCategories(categories) { mData = data; pluginName = LAT1CTOWX(mData->Name); fInBuffer = NULL; fOutBuffer = NULL; inputs = 0; outputs = 0; numInputControls = 0; mLength = 0; unsigned long p; inputPorts = new unsigned long [mData->PortCount]; outputPorts = new unsigned long [mData->PortCount]; inputControls = new float [mData->PortCount]; outputControls = new float [mData->PortCount]; for(p=0; p<mData->PortCount; p++) { LADSPA_PortDescriptor d = mData->PortDescriptors[p]; if (LADSPA_IS_PORT_AUDIO(d)) { if (LADSPA_IS_PORT_INPUT(d)) { inputPorts[inputs] = p; inputs++; } else if (LADSPA_IS_PORT_OUTPUT(d)) { outputPorts[outputs] = p; outputs++; } } if (LADSPA_IS_PORT_CONTROL(d) && LADSPA_IS_PORT_INPUT(d)) { numInputControls++; float val = float(1.0); LADSPA_PortRangeHint hint = mData->PortRangeHints[p]; if (LADSPA_IS_HINT_BOUNDED_BELOW(hint.HintDescriptor) && val < hint.LowerBound) val = hint.LowerBound; if (LADSPA_IS_HINT_BOUNDED_ABOVE(hint.HintDescriptor) && val > hint.UpperBound) val = hint.UpperBound; if (LADSPA_IS_HINT_DEFAULT_MINIMUM(hint.HintDescriptor)) val = hint.LowerBound; if (LADSPA_IS_HINT_DEFAULT_LOW(hint.HintDescriptor)) val = hint.LowerBound * 0.75f + hint.UpperBound * 0.25f; if (LADSPA_IS_HINT_DEFAULT_MIDDLE(hint.HintDescriptor)) val = hint.LowerBound * 0.5f + hint.UpperBound * 0.5f; if (LADSPA_IS_HINT_DEFAULT_HIGH(hint.HintDescriptor)) val = hint.LowerBound * 0.25f + hint.UpperBound * 0.75f; if (LADSPA_IS_HINT_DEFAULT_MAXIMUM(hint.HintDescriptor)) val = hint.UpperBound; if (LADSPA_IS_HINT_SAMPLE_RATE(hint.HintDescriptor)) val *= mProjectRate; if (LADSPA_IS_HINT_DEFAULT_0(hint.HintDescriptor)) val = 0.0f; if (LADSPA_IS_HINT_DEFAULT_1(hint.HintDescriptor)) val = 1.0f; if (LADSPA_IS_HINT_DEFAULT_100(hint.HintDescriptor)) val = 100.0f; if (LADSPA_IS_HINT_DEFAULT_440(hint.HintDescriptor)) val = 440.0f; inputControls[p] = val; } } flags = PLUGIN_EFFECT; if (inputs == 0) flags |= INSERT_EFFECT; else if (outputs == 0) flags |= ANALYZE_EFFECT; else flags |= PROCESS_EFFECT; }
bool LadspaEffect::PopulateUI(wxWindow *parent) { mParent = parent; mEventHelper = new LadspaEffectEventHelper(this); mParent->PushEventHandler(mEventHelper); mToggles = new wxCheckBox*[mData->PortCount]; mSliders = new wxSlider*[mData->PortCount]; mFields = new wxTextCtrl*[mData->PortCount]; mLabels = new wxStaticText*[mData->PortCount]; memset(mFields, 0, mData->PortCount * sizeof(wxTextCtrl *)); wxSizer *marginSizer = new wxBoxSizer(wxVERTICAL); if (mNumInputControls) { wxSizer *paramSizer = new wxStaticBoxSizer(wxVERTICAL, mParent, _("Effect Settings")); wxFlexGridSizer *gridSizer = new wxFlexGridSizer(5, 0, 0); gridSizer->AddGrowableCol(3); wxControl *item; // Add the duration control for generators if (GetType() == EffectTypeGenerate) { item = new wxStaticText(mParent, 0, _("Duration:")); gridSizer->Add(item, 0, wxALIGN_CENTER_VERTICAL | wxALIGN_RIGHT | wxALL, 5); mDuration = new NumericTextCtrl(NumericConverter::TIME, mParent, ID_DURATION, _("hh:mm:ss + milliseconds"), mHost->GetDuration(), mSampleRate, wxDefaultPosition, wxDefaultSize, true); mDuration->SetName(_("Duration")); mDuration->EnableMenu(); gridSizer->Add(mDuration, 0, wxALIGN_CENTER_VERTICAL | wxALL, 5); gridSizer->Add(1, 1, 0); gridSizer->Add(1, 1, 0); gridSizer->Add(1, 1, 0); } for (unsigned long p = 0; p < mData->PortCount; p++) { LADSPA_PortDescriptor d = mData->PortDescriptors[p]; if (LADSPA_IS_PORT_AUDIO(d) || LADSPA_IS_PORT_OUTPUT(d)) { continue; } wxString labelText = LAT1CTOWX(mData->PortNames[p]); item = new wxStaticText(mParent, 0, labelText + wxT(":")); gridSizer->Add(item, 0, wxALIGN_CENTER_VERTICAL | wxALIGN_RIGHT | wxALL, 5); wxString fieldText; LADSPA_PortRangeHint hint = mData->PortRangeHints[p]; if (LADSPA_IS_HINT_TOGGLED(hint.HintDescriptor)) { mToggles[p] = new wxCheckBox(mParent, ID_TOGGLES + p, wxT("")); mToggles[p]->SetName(labelText); mToggles[p]->SetValue(mInputControls[p] > 0); gridSizer->Add(mToggles[p], 0, wxALL, 5); gridSizer->Add(1, 1, 0); gridSizer->Add(1, 1, 0); gridSizer->Add(1, 1, 0); continue; } wxString bound; double lower = -FLT_MAX; double upper = FLT_MAX; bool haslo = false; bool hashi = false; bool forceint = false; if (LADSPA_IS_HINT_BOUNDED_BELOW(hint.HintDescriptor)) { lower = hint.LowerBound; haslo = true; } if (LADSPA_IS_HINT_BOUNDED_ABOVE(hint.HintDescriptor)) { upper = hint.UpperBound; hashi = true; } if (LADSPA_IS_HINT_SAMPLE_RATE(hint.HintDescriptor)) { lower *= mSampleRate; upper *= mSampleRate; forceint = true; } // Don't specify a value at creation time. This prevents unwanted events // being sent to the OnTextCtrl() handler before the associated slider // has been created. mFields[p] = new wxTextCtrl(mParent, ID_TEXTS + p); mFields[p]->SetName(labelText); gridSizer->Add(mFields[p], 0, wxALIGN_CENTER_VERTICAL | wxALL, 5); wxString str; if (haslo) { if (LADSPA_IS_HINT_INTEGER(hint.HintDescriptor) || forceint) { str.Printf(wxT("%d"), (int)(lower + 0.5)); } else { str = Internat::ToDisplayString(lower); } item = new wxStaticText(mParent, 0, str); gridSizer->Add(item, 0, wxALIGN_CENTER_VERTICAL | wxALIGN_RIGHT | wxALL, 5); } else { gridSizer->Add(1, 1, 0); } mSliders[p] = new wxSlider(mParent, ID_SLIDERS + p, 0, 0, 1000, wxDefaultPosition, wxSize(200, -1)); mSliders[p]->SetName(labelText); gridSizer->Add(mSliders[p], 0, wxALIGN_CENTER_VERTICAL | wxEXPAND | wxALL, 5); if (hashi) { if (LADSPA_IS_HINT_INTEGER(hint.HintDescriptor) || forceint) { str.Printf(wxT("%d"), (int)(upper + 0.5)); } else { str = Internat::ToDisplayString(upper); } item = new wxStaticText(mParent, 0, str); gridSizer->Add(item, 0, wxALIGN_CENTER_VERTICAL | wxALIGN_LEFT | wxALL, 5); } else { gridSizer->Add(1, 1, 0); } if (LADSPA_IS_HINT_INTEGER(hint.HintDescriptor) || forceint) { fieldText.Printf(wxT("%d"), (int)(mInputControls[p] + 0.5)); wxIntegerValidator<float> vld(&mInputControls[p]); vld.SetRange(haslo ? lower : INT_MIN, hashi ? upper : INT_MAX); mFields[p]->SetValidator(vld); } else { fieldText = Internat::ToDisplayString(mInputControls[p]); // > 12 decimal places can cause rounding errors in display. wxFloatingPointValidator<float> vld(12, &mInputControls[p]); vld.SetRange(haslo ? lower : -FLT_MAX, hashi ? upper : FLT_MAX); // Set number of decimal places if (upper - lower < 10.0) { vld.SetStyle(wxNUM_VAL_THREE_TRAILING_ZEROES); } else if (upper - lower < 100.0) { vld.SetStyle(wxNUM_VAL_TWO_TRAILING_ZEROES); } else { vld.SetStyle(wxNUM_VAL_ONE_TRAILING_ZERO); } mFields[p]->SetValidator(vld); } // Set the textctrl value. This will trigger an event so OnTextCtrl() // can update the slider. mFields[p]->SetValue(fieldText); } paramSizer->Add(gridSizer, 1, wxEXPAND | wxALL, 5); marginSizer->Add(paramSizer, 1, wxEXPAND | wxALL, 5); } if (mNumOutputControls > 0 ) { wxSizer *paramSizer = new wxStaticBoxSizer(wxVERTICAL, mParent, _("Effect Output")); wxFlexGridSizer *gridSizer = new wxFlexGridSizer(2, 0, 0); gridSizer->AddGrowableCol(3); wxControl *item; for (unsigned long p = 0; p < mData->PortCount; p++) { LADSPA_PortDescriptor d = mData->PortDescriptors[p]; if (LADSPA_IS_PORT_AUDIO(d) || LADSPA_IS_PORT_INPUT(d)) { continue; } wxString labelText = LAT1CTOWX(mData->PortNames[p]); item = new wxStaticText(mParent, 0, labelText + wxT(":")); gridSizer->Add(item, 0, wxALIGN_CENTER_VERTICAL | wxALIGN_RIGHT | wxALL, 5); wxString fieldText; mFields[p] = new wxTextCtrl(mParent, wxID_ANY, fieldText, wxDefaultPosition, wxDefaultSize, wxTE_READONLY); mFields[p]->SetName(labelText); gridSizer->Add(mFields[p], 0, wxALIGN_CENTER_VERTICAL | wxALL, 5); } paramSizer->Add(gridSizer, 1, wxEXPAND | wxALL, 5); marginSizer->Add(paramSizer, 1, wxEXPAND | wxALL, 5); RefreshControls(true); } mParent->SetSizer(marginSizer); return true; }
wxString LadspaEffect::GetName() { return LAT1CTOWX(mData->Name); }
LV2EffectDialog::LV2EffectDialog(LV2Effect *eff, wxWindow * parent, SLV2Plugin data, int sampleRate, double length, double noteLength, unsigned char noteVelocity, unsigned char noteKey) :wxDialog(parent, -1, LAT1CTOWX(slv2_value_as_string(slv2_plugin_get_name(data))), wxDefaultPosition, wxDefaultSize, wxDEFAULT_DIALOG_STYLE | wxRESIZE_BORDER), effect(eff), mControls(eff->GetControls()) { mLength = length; this->mData = data; this->sampleRate = sampleRate; #ifdef __WXMSW__ // On Windows, for some reason, wxWindows calls OnTextCtrl during creation // of the text control, and LV2EffectDialog::OnTextCtrl calls HandleText, // which assumes all the fields have been initialized. // This can give us a bad pointer crash, so manipulate inSlider to // no-op HandleText during creation. inSlider = true; #else inSlider = false; #endif inText = false; // Allocate memory for the user parameter controls toggles = new wxCheckBox*[mControls.size()]; sliders = new wxSlider*[mControls.size()]; fields = new wxTextCtrl*[mControls.size()]; labels = new wxStaticText*[mControls.size()]; wxControl *item; wxBoxSizer *vSizer = new wxBoxSizer(wxVERTICAL); // Add information about the plugin SLV2Value tmpValue = slv2_plugin_get_author_name(data); if (tmpValue) { const char* author = slv2_value_as_string(tmpValue); item = new wxStaticText(this, 0, wxString(_("Author: "))+LAT1CTOWX(author)); vSizer->Add(item, 0, wxALL, 5); slv2_value_free(tmpValue); } wxScrolledWindow *w = new wxScrolledWindow(this, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxVSCROLL | wxTAB_TRAVERSAL); // Try to give the window a sensible default/minimum size w->SetMinSize(wxSize( wxMax(600, parent->GetSize().GetWidth() * 2/3), parent->GetSize().GetHeight() / 2)); w->SetScrollRate(0, 20); vSizer->Add(w, 1, wxEXPAND|wxALL, 5); // Preview, OK, & Cancel buttons vSizer->Add(CreateStdButtonSizer(this, ePreviewButton|eCancelButton|eOkButton), 0, wxEXPAND); SetSizer(vSizer); wxSizer *paramSizer = new wxStaticBoxSizer(wxVERTICAL, w, _("Effect Settings")); wxFlexGridSizer *gridSizer = new wxFlexGridSizer(5, 0, 0); gridSizer->AddGrowableCol(3); const LV2PortGroup& rootGroup = eff->GetPortGroups(); const ScalePointMap& scalePoints = eff->GetScalePoints(); // Now add the length control if (effect->GetEffectFlags() & INSERT_EFFECT) { item = new wxStaticText(w, 0, _("Length (seconds)")); gridSizer->Add(item, 0, wxALIGN_CENTER_VERTICAL | wxALL, 5); mSeconds = new wxTextCtrl(w, LADSPA_SECONDS_ID, Internat::ToDisplayString(length)); mSeconds->SetName(_("Length (seconds)")); gridSizer->Add(mSeconds, 0, wxALIGN_CENTER_VERTICAL | wxALL, 5); gridSizer->Add(1, 1, 0); gridSizer->Add(1, 1, 0); gridSizer->Add(1, 1, 0); ConnectFocus(mSeconds); } // The note controls if the plugin is a synth if (effect->IsSynth()) { // Note length control item = new wxStaticText(w, 0, _("Note length (seconds)")); gridSizer->Add(item, 0, wxALIGN_CENTER_VERTICAL | wxALIGN_RIGHT | wxALL, 5); mNoteSeconds = new wxTextCtrl(w, LADSPA_SECONDS_ID, Internat::ToDisplayString(length / 2)); mNoteSeconds->SetName(_("Note length (seconds)")); gridSizer->Add(mNoteSeconds, 0, wxALIGN_CENTER_VERTICAL | wxALL, 5); gridSizer->Add(1, 1, 0); gridSizer->Add(1, 1, 0); gridSizer->Add(1, 1, 0); ConnectFocus(mNoteSeconds); // Note velocity control item = new wxStaticText(w, 0, _("Note velocity")); gridSizer->Add(item, 0, wxALIGN_CENTER_VERTICAL | wxALIGN_RIGHT | wxALL, 5); mNoteVelocity = new wxTextCtrl(w, LADSPA_SECONDS_ID, Internat::ToDisplayString(64)); mNoteVelocity->SetName(_("Note velocity")); gridSizer->Add(mNoteVelocity, 0, wxALIGN_CENTER_VERTICAL | wxALL, 5); gridSizer->Add(1, 1, 0); gridSizer->Add(1, 1, 0); gridSizer->Add(1, 1, 0); ConnectFocus(mNoteVelocity); // Note key control item = new wxStaticText(w, 0, _("Note key")); gridSizer->Add(item, 0, wxALIGN_CENTER_VERTICAL | wxALIGN_RIGHT | wxALL, 5); mNoteKey = new wxTextCtrl(w, LADSPA_SECONDS_ID, Internat::ToDisplayString(64)); mNoteKey->SetName(_("Note key")); gridSizer->Add(mNoteKey, 0, wxALIGN_CENTER_VERTICAL | wxALL, 5); gridSizer->Add(1, 1, 0); gridSizer->Add(1, 1, 0); gridSizer->Add(1, 1, 0); ConnectFocus(mNoteKey); } paramSizer->Add(gridSizer, 1, wxEXPAND | wxALL, 5); // Create user parameter controls std::queue<const LV2PortGroup*> groups; groups.push(&rootGroup); while (!groups.empty()) { const LV2PortGroup* pg = groups.front(); groups.pop(); if (pg->GetName() != wxT("")) { wxSizer *groupSizer = new wxStaticBoxSizer(wxVERTICAL, w, pg->GetName()); paramSizer->Add(groupSizer, 0, wxEXPAND | wxALL, 5); gridSizer = new wxFlexGridSizer(5, 0, 0); gridSizer->AddGrowableCol(3); groupSizer->Add(gridSizer, 1, wxEXPAND | wxALL, 5); } std::vector<LV2PortGroup>::const_iterator iter; for (iter = pg->GetSubGroups().begin(); iter != pg->GetSubGroups().end(); ++iter) { groups.push(&*iter); } const std::vector<uint32_t>& params = pg->GetParameters(); for (uint32_t k = 0; k < params.size(); ++k) { uint32_t p = params[k]; wxString labelText = mControls[p].mName; item = new wxStaticText(w, 0, labelText + wxT(":")); gridSizer->Add(item, 0, wxALIGN_CENTER_VERTICAL | wxALIGN_RIGHT | wxALL, 5); wxString fieldText; if (mControls[p].mToggle) { toggles[p] = new wxCheckBox(w, p, wxT("")); toggles[p]->SetName(labelText); toggles[p]->SetValue(mControls[p].mControlBuffer > 0); gridSizer->Add(toggles[p], 0, wxALL, 5); ConnectFocus(toggles[p]); gridSizer->Add(1, 1, 0); gridSizer->Add(1, 1, 0); gridSizer->Add(1, 1, 0); } else { if (mControls[p].mInteger) fieldText.Printf(wxT("%d"), (int)(mControls[p].mControlBuffer + 0.5)); else fieldText = Internat::ToDisplayString(mControls[p].mControlBuffer); fields[p] = new wxTextCtrl(w, p, fieldText); fields[p]->SetName(labelText); gridSizer->Add(fields[p], 0, wxALIGN_CENTER_VERTICAL | wxALL, 5); ConnectFocus(fields[p]); wxString bound; double lower = 0.0; double upper = 0.0; bool haslo = false; bool hashi = false; bool forceint = false; wxString loLabel; wxString hiLabel; ScalePointMap::const_iterator iter = scalePoints.find(mControls[p].mIndex); if (!std::isnan(mControls[p].mMin)) { lower = mControls[p].mMin; haslo = true; if (iter != scalePoints.end()) { std::map<float, wxString>::const_iterator iter2 = iter->second.find(lower); if (iter2 != iter->second.end()) { loLabel = iter2->second; } } } if (!std::isnan(mControls[p].mMax)) { upper = mControls[p].mMax; hashi = true; if (iter != scalePoints.end()) { std::map<float, wxString>::const_iterator iter2 = iter->second.find(upper); if (iter2 != iter->second.end()) hiLabel = iter2->second; } } if (mControls[p].mSampleRate) { lower *= sampleRate * 1000; upper *= sampleRate; forceint = true; } wxString str; if (haslo) { str = loLabel; if (str.IsEmpty()) { if (mControls[p].mInteger || forceint) str.Printf(wxT("%d"), (int)(lower + 0.5)); else str = Internat::ToDisplayString(lower); } item = new wxStaticText(w, 0, str); gridSizer->Add(item, 0, wxALIGN_CENTER_VERTICAL | wxALIGN_RIGHT | wxALL, 5); } else { gridSizer->Add(1, 1, 0); } sliders[p] = new wxSlider(w, p, 0, 0, 1000, wxDefaultPosition, wxSize(200, -1)); sliders[p]->SetName(labelText); gridSizer->Add(sliders[p], 0, wxALIGN_CENTER_VERTICAL | wxEXPAND | wxALL, 5); ConnectFocus(sliders[p]); if (hashi) { str = hiLabel; if (str.IsEmpty()) { if (mControls[p].mInteger || forceint) str.Printf(wxT("%d"), (int)(upper + 0.5)); else str = Internat::ToDisplayString(upper); } item = new wxStaticText(w, 0, str); gridSizer->Add(item, 0, wxALIGN_CENTER_VERTICAL | wxALIGN_LEFT | wxALL, 5); } else { gridSizer->Add(1, 1, 0); } } } } // Set all of the sliders based on the value in the // text fields inSlider = false; // Now we're ready for HandleText to actually do something. HandleText(); w->SetSizer(paramSizer); Layout(); Fit(); SetSizeHints(GetSize()); }
LV2Effect::LV2Effect(SLV2Plugin data, const std::set<wxString>& categories) : mValid(true), mCategories(categories), mMidiInput(0), mScalePointsRetrieved(false), mPortGroupsRetrieved(false) { // We don't support any features at all, so if the plugin requires // any we skip it. SLV2Values req = slv2_plugin_get_required_features(data); size_t nFeatures = slv2_values_size(req); slv2_values_free(req); if (nFeatures > 0) { mValid = false; return; } mData = data; pluginName = wxString::FromUTF8(slv2_value_as_string(slv2_plugin_get_name(mData))); fInBuffer = NULL; fOutBuffer = NULL; mLength = 0; uint32_t p; // Allocate buffers for the port indices and the default control values uint32_t numPorts = slv2_plugin_get_num_ports(mData); float* minimumValues = new float [numPorts]; float* maximumValues = new float [numPorts]; float* defaultValues = new float [numPorts]; // Retrieve the port ranges for all ports (some values may be NaN) slv2_plugin_get_port_ranges_float(mData, minimumValues, maximumValues, defaultValues); // Get info about all ports for(p = 0; p < numPorts; p++) { SLV2Port port = slv2_plugin_get_port_by_index(mData, p); LV2Port internalPort; internalPort.mIndex = p; // Get the port name SLV2Value tmpName = slv2_port_get_name(data, port); internalPort.mName = LAT1CTOWX(slv2_value_as_string(tmpName)); slv2_value_free(tmpName); // Get the port type if (slv2_port_is_a(mData, port, gAudioPortClass)) { if (slv2_port_is_a(mData, port, gInputPortClass)) mAudioInputs.push_back(internalPort); else if (slv2_port_is_a(mData, port, gOutputPortClass)) mAudioOutputs.push_back(internalPort); } else if (slv2_port_is_a(mData, port, gControlPortClass) && slv2_port_is_a(mData, port, gInputPortClass)) { internalPort.mControlBuffer = float(1.0); internalPort.mMin = minimumValues[p]; internalPort.mMax = maximumValues[p]; internalPort.mDefault = defaultValues[p]; if (std::isfinite(defaultValues[p])) internalPort.mControlBuffer = defaultValues[p]; else if (std::isfinite(minimumValues[p])) internalPort.mControlBuffer = minimumValues[p]; else if (std::isfinite(maximumValues[p])) internalPort.mControlBuffer = maximumValues[p]; if (slv2_port_has_property(data, port, gPortToggled)) internalPort.mToggle = true; if (slv2_port_has_property(data, port, gPortIsInteger)) internalPort.mInteger = true; if (slv2_port_has_property(data, port, gPortIsSampleRate)) internalPort.mSampleRate = true; mControlInputs.push_back(internalPort); } else if (slv2_port_is_a(mData, port, gMidiPortClass) && slv2_port_is_a(mData, port, gInputPortClass)) { // If there are more than one MIDI input ports, the plugin is invalid if (mMidiInput) { mValid = false; continue; } mMidiInput = new LV2Port(internalPort); } else { // Unknown port type, we set the invalid flag mValid = false; } } delete [] minimumValues; delete [] maximumValues; delete [] defaultValues; // MIDI synths may not have any audio inputs. if (mMidiInput && mAudioInputs.size() > 0) mValid = false; // Determine whether the plugin is a generator, effect or analyser // depending on the number of ports of each type (not completely accurate, // but works most of the time) flags = PLUGIN_EFFECT; if (mAudioInputs.size() == 0) flags |= INSERT_EFFECT; else if (mAudioOutputs.size() == 0) flags |= ANALYZE_EFFECT; else flags |= PROCESS_EFFECT; }
wxString LadspaEffect::GetVendor() { return LAT1CTOWX(mData->Maker); }
wxString LadspaEffect::GetDescription() { return LAT1CTOWX(mData->Copyright); }
wxString VampEffect::GetVendor() { return LAT1CTOWX(mPlugin->getMaker().c_str()); }
wxString VampEffect::GetEffectIdentifier() { return LAT1CTOWX(mKey.c_str()); }
wxString VampEffect::GetPath() { Vamp::HostExt::PluginLoader *loader = Vamp::HostExt::PluginLoader::getInstance(); return LAT1CTOWX(loader->getLibraryPathForPlugin(mKey).c_str()); }
/* static */ void VSTEffect::Scan() { wxArrayString audacityPathList = wxGetApp().audacityPathList; wxArrayString pathList; wxArrayString files; // Check for the VST_PATH environment variable wxString vstpath = wxGetenv(wxT("VST_PATH")); if (!vstpath.IsEmpty()) { wxGetApp().AddUniquePathToPathList(vstpath, pathList); } // Add Audacity specific paths for (size_t i = 0; i < audacityPathList.GetCount(); i++) { wxString prefix = audacityPathList[i] + wxFILE_SEP_PATH; wxGetApp().AddUniquePathToPathList(prefix + VSTPLUGINTYPE, pathList); wxGetApp().AddUniquePathToPathList(prefix + wxT("plugins"), pathList); wxGetApp().AddUniquePathToPathList(prefix + wxT("plug-ins"), pathList); } #if defined(__WXMAC__) #define VSTPATH wxT("/Library/Audio/Plug-Ins/VST") // Look in /Library/Audio/Plug-Ins/VST and $HOME/Library/Audio/Plug-Ins/VST wxGetApp().AddUniquePathToPathList(VSTPATH, pathList); wxGetApp().AddUniquePathToPathList(wxString(wxGetenv(wxT("HOME"))) + VSTPATH, pathList); // Recursively search all paths for Info.plist files. This will identify all // bundles. wxGetApp().FindFilesInPathList(wxT("Info.plist"), pathList, files, wxDIR_DEFAULT); // Remove the 'Contents/Info.plist' portion of the names for (size_t i = 0, cnt = files.GetCount(); i < cnt; i++) { files[i] = wxPathOnly(wxPathOnly(files[i])); } #elif defined(__WXMSW__) TCHAR dpath[MAX_PATH]; TCHAR tpath[MAX_PATH]; DWORD len = WXSIZEOF(tpath); // Setup the default VST path. dpath[0] = '\0'; ExpandEnvironmentStrings(wxT("%ProgramFiles%\\Steinberg\\VSTPlugins"), dpath, WXSIZEOF(dpath)); // Check registry for the real path if (SHRegGetUSValue(wxT("Software\\VST"), wxT("VSTPluginsPath"), NULL, tpath, &len, FALSE, dpath, (DWORD) _tcslen(dpath)) == ERROR_SUCCESS) { tpath[len] = 0; ExpandEnvironmentStrings(tpath, dpath, WXSIZEOF(dpath)); wxGetApp().AddUniquePathToPathList(LAT1CTOWX(dpath), pathList); } // Recursively scan for all DLLs wxGetApp().FindFilesInPathList(wxT("*.dll"), pathList, files, wxDIR_DEFAULT); #else // Recursively scan for all shared objects wxGetApp().FindFilesInPathList(wxT("*.so"), pathList, files); #endif // This is a hack to allow for long paths in the progress dialog. The // progress dialog should really truncate the message if it's too wide // for the dialog. size_t cnt = files.GetCount(); wxString longest; // JKC: Let's not show the progress dialog if there are no // files to test. if( cnt <= 0 ) return; for (size_t i = 0; i < cnt; i++) { if (files[i].Length() > longest.Length()) { longest = files[i]; } } ProgressDialog *progress = new ProgressDialog(_("Scanning VST Plugins"), longest, pdlgHideStopButton); // progress->SetSize(wxSize(500, -1)); progress->CenterOnScreen(); const wxChar * argv[4]; argv[0] = PlatformCompatibility::GetExecutablePath().c_str(); argv[1] = VSTCMDKEY; argv[2] = NULL; argv[3] = NULL; for (size_t i = 0; i < cnt; i++) { wxString file = files[i]; int status = progress->Update(wxLongLong(i), wxLongLong(cnt), wxString::Format(_("Checking %s"), file.c_str())); if (status != eProgressSuccess) { break; } argv[2] = file.c_str(); // ToDo: do we need a try--catch around this in case a bad plug-in // fails? (JKC Nov09) wxExecute((wxChar **) argv, wxEXEC_SYNC | wxEXEC_NODISABLE, NULL); } delete progress; }