EffectNyquist::EffectNyquist(wxString fName) { mAction = _("Applying Nyquist Effect..."); mInputCmd = wxEmptyString; mCmd = wxEmptyString; SetEffectFlags(HIDDEN_EFFECT); mInteractive = false; mExternal = false; mCompiler = false; mDebug = false; mIsSal = false; mOK = false; mStop = false; mBreak = false; mCont = false; if (fName == wxT("")) { // Interactive Nyquist mOK = true; mInteractive = true; mName = _("Nyquist Prompt..."); SetEffectFlags(PROCESS_EFFECT | BUILTIN_EFFECT | ADVANCED_EFFECT); return; } // wxLogNull dontLog; // Vaughan, 2010-08-27: Why turn off logging? Logging is good! mName = wxFileName(fName).GetName(); mFileName = wxFileName(fName); mFileModified = mFileName.GetModificationTime(); ParseFile(); }
void EffectNyquist::ParseFile() { wxTextFile f(mFileName.GetFullPath()); if (!f.Open()) return; mCmd = wxT(""); SetEffectFlags(PROCESS_EFFECT | PLUGIN_EFFECT); mOK = false; mIsSal = false; mControls.Clear(); mDebug = false; int i; int len = f.GetLineCount(); wxString line; for (i = 0; i < len; i++) { line = f[i]; if (line.Length() > 1 && line[0] == wxT(';')) { Parse(line); } // preserve comments so that SAL effects compile with proper line numbers mCmd += line + wxT("\n"); } }
VSTEffect::VSTEffect(const wxString & path) : mPath(path) { mModule = NULL; mAEffect = NULL; mInBuffer = NULL; mOutBuffer = NULL; mInputs = 0; mOutputs = 0; mChannels = 0; mBlockSize = 0; memset(&mTimeInfo, 0, sizeof(mTimeInfo)); mTimeInfo.samplePos = 0.0; mTimeInfo.sampleRate = 44100.0; mTimeInfo.nanoSeconds = wxGetLocalTimeMillis().ToDouble(); mTimeInfo.tempo = 120.0; mTimeInfo.timeSigNumerator = 4; mTimeInfo.timeSigDenominator = 4; mTimeInfo.flags = kVstTempoValid | kVstNanosValid; PluginManager & pm = PluginManager::Get(); if (pm.IsRegistered(VSTPLUGINTYPE, mPath)) { mName = pm.Read(wxT("Name"), wxEmptyString); mVendor = pm.Read(wxT("Vendor"), wxEmptyString); mInputs = pm.Read(wxT("Inputs"), 0L); mOutputs = pm.Read(wxT("Outputs"), 0L); } else if (Load()) { pm.RegisterPlugin(VSTPLUGINTYPE, mPath); pm.Write(wxT("Name"), mName); pm.Write(wxT("Vendor"), mVendor); pm.Write(wxT("Inputs"), mInputs); pm.Write(wxT("Outputs"), mOutputs); } if (mVendor.IsEmpty()) { mVendor = VSTPLUGINTYPE; } if (mName.IsEmpty()) { wxFileName fn(mPath); mName = fn.GetName(); } int flags = PLUGIN_EFFECT; if (mInputs == 0) { flags |= INSERT_EFFECT; } else if (mOutputs == 0) { flags |= ANALYZE_EFFECT; } else { flags |= PROCESS_EFFECT; } SetEffectFlags(flags); }
EffectToneGen::EffectToneGen() { SetEffectFlags(BUILTIN_EFFECT | INSERT_EFFECT); mbChirp = false; mbLogInterpolation = false; waveform = 0; //sine frequency[0] = float(440.0); //Hz frequency[1] = float(1320.0); //Hz amplitude[0] = float(0.8); amplitude[1] = float(0.1); interpolation = 0; }
VampEffect::VampEffect(Vamp::HostExt::PluginLoader::PluginKey key, int output, bool hasParameters, wxString name, wxString category) : mKey(key), mOutput(output), mHasParameters(hasParameters), mName(name), mRate(0), mCategory(category), mPlugin(NULL) { SetEffectFlags(PLUGIN_EFFECT | ANALYZE_EFFECT); }
VampEffect::VampEffect(Vamp::HostExt::PluginLoader::PluginKey key, int output, bool hasParameters, wxString name, wxString category) : mKey(key), mOutput(output), mHasParameters(hasParameters), mName(name), mRate(0), mCategory(category), mPlugin(NULL) { Vamp::HostExt::PluginLoader *loader = Vamp::HostExt::PluginLoader::getInstance(); mPlugin = loader->loadPlugin(mKey, 48000); // rate doesn't matter here SetEffectFlags(PLUGIN_EFFECT | ANALYZE_EFFECT); }
EffectAutoDuck::EffectAutoDuck() { SetEffectFlags(BUILTIN_EFFECT | PROCESS_EFFECT | ADVANCED_EFFECT); gPrefs->Read(wxT("/Effects/AutoDuck/DuckAmountDb"), &mDuckAmountDb, PARAM_DEFAULT_DUCK_AMOUNT_DB); gPrefs->Read(wxT("/Effects/AutoDuck/InnerFadeDownLen"), &mInnerFadeDownLen, PARAM_DEFAULT_INNER_FADE_DOWN_LEN); gPrefs->Read(wxT("/Effects/AutoDuck/InnerFadeUpLen"), &mInnerFadeUpLen, PARAM_DEFAULT_INNER_FADE_UP_LEN); gPrefs->Read(wxT("/Effects/AutoDuck/OuterFadeDownLen"), &mOuterFadeDownLen, PARAM_DEFAULT_OUTER_FADE_DOWN_LEN); gPrefs->Read(wxT("/Effects/AutoDuck/OuterFadeUpLen"), &mOuterFadeUpLen, PARAM_DEFAULT_OUTER_FADE_UP_LEN); gPrefs->Read(wxT("/Effects/AutoDuck/ThresholdDb"), &mThresholdDb, PARAM_DEFAULT_THRESHOLD_DB); gPrefs->Read(wxT("/Effects/AutoDuck/MaximumPause"), &mMaximumPause, PARAM_DEFAULT_MAXIMUM_PAUSE); mControlTrack = NULL; }
void EffectNyquist::SetCommand(wxString cmd) { mExternal = true; mInteractive = false; mCmd = wxT(""); SetEffectFlags(INSERT_EFFECT | HIDDEN_EFFECT); mOK = false; mIsSal = false; mControls.Clear(); wxStringTokenizer lines(cmd, wxT("\n")); while (lines.HasMoreTokens()) { wxString line = lines.GetNextToken(); if (line.Length() > 1 && line[0] == wxT(';')) { Parse(line); } else { mCmd += line + wxT("\n"); } } }
LV2Effect::LV2Effect(const LilvPlugin *data, const std::set<wxString> & categories) : mValid(true), mCategories(categories), mMidiInput(0), mLatencyPortIndex(-1) { // We don't support any features at all, so if the plugin requires // any we skip it. LilvNodes *req = lilv_plugin_get_required_features(data); size_t nFeatures = lilv_nodes_size(req); lilv_nodes_free(req); if (nFeatures > 0) { mValid = false; return; } mData = data; pluginName = GetString(lilv_plugin_get_name(mData), true); fInBuffer = NULL; fOutBuffer = NULL; mLength = 0; // Allocate buffers for the port indices and the default control values int numPorts = lilv_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) lilv_plugin_get_port_ranges_float(mData, minimumValues, maximumValues, defaultValues); // Get info about all ports for (int i = 0; i < numPorts; i++) { const LilvPort *port = lilv_plugin_get_port_by_index(mData, i); LV2Port internalPort; internalPort.mIndex = lilv_port_get_index(mData, port); // Get the port name LilvNode *tmpName = lilv_port_get_name(mData, port); internalPort.mName = GetString(tmpName); lilv_node_free(tmpName); // Get the scale points LilvScalePoints* points = lilv_port_get_scale_points(mData, port); LILV_FOREACH(scale_points, j, points) { const LilvScalePoint *point = lilv_scale_points_get(points, j); internalPort.mScaleValues.Add(lilv_node_as_float(lilv_scale_point_get_value(point))); internalPort.mScaleLabels.Add(GetString(lilv_scale_point_get_label(point))); } lilv_scale_points_free(points); // Get the groups LilvNodes *groups = lilv_port_get_value(mData, port, gPortGroup); if (groups) { LilvNode *group = lilv_nodes_get_first(groups); wxString uri = GetString(group); wxString label; const LilvNode *name = lilv_world_get(gWorld, group, gName, NULL); if (name) { label = GetString(name); } else { // Shouldn't happen, but provide something label = uri; } lilv_nodes_free(groups); // Check for new group if (mPortGroups.find(uri) == mPortGroups.end()) { mPortGroups[uri] = LV2PortGroup(label); } #if 0 // Get subgroup // // LLL: This isn't right...must find or construct a plugin with // subgroups. LilvNodes *subgroup = lilv_node_get_value(mData, port, gSubGroupOf); if (subgroups) { LilvNode *subgroup = lilv_nodes_get_first(subgroups); wxString uri = GetString(subgroup); const LilvNode *subgroup = lilv_world_get(gWorld, group, gSubGroupOf, NULL); wxString label = GetString(name); lilv_nodes_free(subgroup); } else #endif { mRootGroup.AddSubGroup(mPortGroups[uri]); } mPortGroups[uri].AddParameter(i); } else { mRootGroup.AddParameter(i); } // Get the port type if (lilv_port_is_a(mData, port, gAudioPortClass)) { if (lilv_port_is_a(mData, port, gInputPortClass)) { mAudioInputs.Add(internalPort); } else if (lilv_port_is_a(mData, port, gOutputPortClass)) { mAudioOutputs.Add(internalPort); } } else if (lilv_port_is_a(mData, port, gControlPortClass) && lilv_port_is_a(mData, port, gInputPortClass)) { internalPort.mControlBuffer = float(1.0); internalPort.mMin = minimumValues[i]; internalPort.mMax = maximumValues[i]; internalPort.mDefault = defaultValues[i]; if (isfinite(defaultValues[i])) { internalPort.mControlBuffer = defaultValues[i]; } else if (isfinite(minimumValues[i])) { internalPort.mControlBuffer = minimumValues[i]; } else if (isfinite(maximumValues[i])) { internalPort.mControlBuffer = maximumValues[i]; } if (lilv_port_has_property(mData, port, gPortToggled)) { internalPort.mToggle = true; } else if (lilv_port_has_property(mData, port, gPortIsInteger)) { internalPort.mInteger = true; } else if (lilv_port_has_property(mData, port, gPortIsSampleRate)) { internalPort.mSampleRate = true; } else if (lilv_port_has_property(mData, port, gPortIsEnumeration)) { internalPort.mEnumeration = true; } mControlInputs.Add(internalPort); } else if (lilv_port_is_a(mData, port, gControlPortClass) && lilv_port_is_a(mData, port, gOutputPortClass)) { // If there is more than one latency port, the plugin is invalid if (lilv_port_has_property(mData, port, gPortIsLatency)) { if (mLatencyPortIndex >= 0) { mValid = false; continue; } mLatencyPortIndex = i; } else if (!lilv_port_has_property(mData, port, gPortIsOptional)) { mControlOutputs.Add(internalPort); } } else if (lilv_port_is_a(mData, port, gMidiPortClass) && lilv_port_is_a(mData, port, gInputPortClass)) { // If there is more than one MIDI input port, 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.GetCount() > 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) int flags = PLUGIN_EFFECT; if (mAudioInputs.GetCount() == 0) { flags |= INSERT_EFFECT; } else if (mAudioOutputs.GetCount() == 0) { flags |= ANALYZE_EFFECT; } else { flags |= PROCESS_EFFECT; } SetEffectFlags(flags); }
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; } } int flags = PLUGIN_EFFECT; if (inputs == 0) flags |= INSERT_EFFECT; else if (outputs == 0) flags |= ANALYZE_EFFECT; else flags |= PROCESS_EFFECT; SetEffectFlags(flags); }
EffectFindClipping::EffectFindClipping() { SetEffectFlags(BUILTIN_EFFECT | ANALYZE_EFFECT); mStart = 3; mStop = 3; }
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) int flags = PLUGIN_EFFECT; if (mAudioInputs.size() == 0) flags |= INSERT_EFFECT; else if (mAudioOutputs.size() == 0) flags |= ANALYZE_EFFECT; else flags |= PROCESS_EFFECT; SetEffectFlags(flags); }
void EffectNyquist::Parse(wxString line) { wxArrayString tokens; int i; int len = line.Length(); bool sl = false; bool q = false; wxString tok = wxT(""); for (i = 1; i < len; i++) { wxChar c = line[i]; if (c == wxT('\\')) { sl = true; } else if (c == wxT('"')) { q = !q; } else { if ((!q && !sl && c == wxT(' ')) || c == wxT('\t')) { tokens.Add(tok); tok = wxT(""); } else if (sl && c == wxT('n')) { tok += wxT('\n'); } else { tok += c; } sl = false; } } if (tok != wxT("")) { tokens.Add(tok); } len = tokens.GetCount(); if (len < 1) { return; } if (len == 2 && tokens[0] == wxT("nyquist") && tokens[1] == wxT("plug-in")) { mOK = true; return; } if (len >= 2 && tokens[0] == wxT("type")) { if (tokens[1] == wxT("process")) { SetEffectFlags(PROCESS_EFFECT | PLUGIN_EFFECT); } else if (tokens[1] == wxT("generate")) { SetEffectFlags(INSERT_EFFECT | PLUGIN_EFFECT); } else if (tokens[1] == wxT("analyze")) { SetEffectFlags(ANALYZE_EFFECT | PLUGIN_EFFECT); } return; } if (len == 2 && tokens[0] == wxT("codetype")) { if (tokens[1] == wxT("lisp")) { mIsSal = false; } else if (tokens[1] == wxT("sal")) { mIsSal = true; } return; } if (len >= 2 && tokens[0] == wxT("debugflags")) { for (int i = 1; i < len; i++) { // Note: "trace" and "notrace" are overridden by "Debug" and "OK" // buttons if the plug-in generates a dialog box by using controls if (tokens[i] == wxT("trace")) { mDebug = true; } else if (tokens[i] == wxT("notrace")) { mDebug = false; } else if (tokens[i] == wxT("compiler")) { mCompiler = true; } else if (tokens[i] == wxT("nocompiler")) { mCompiler = false; } } return; } // We support versions 1, 2 and 3 // (Version 2 added support for string parameters.) // (Version 3 added support for choice parameters.) if (len >= 2 && tokens[0] == wxT("version")) { if (tokens[1] != wxT("1") && tokens[1] != wxT("2") && tokens[1] != wxT("3")) { // This is an unsupported plug-in version mOK = false; return; } } if (len >= 2 && tokens[0] == wxT("name")) { mName = UnQuote(tokens[1]); return; } if (len >= 2 && tokens[0] == wxT("action")) { mAction = UnQuote(tokens[1]); return; } if (len >= 2 && tokens[0] == wxT("info")) { mInfo = UnQuote(tokens[1]); return; } if (len >= 6 && tokens[0] == wxT("control")) { NyqControl ctrl; ctrl.var = tokens[1]; ctrl.name = tokens[2]; ctrl.label = tokens[4]; ctrl.valStr = tokens[5]; if (tokens[3] == wxT("string")) { ctrl.type = NYQ_CTRL_STRING; } else if (tokens[ 3 ] == wxT("choice")) { ctrl.type = NYQ_CTRL_CHOICE; } else { if (len < 8) { return; } if ((tokens[3] == wxT("real")) || (tokens[3] == wxT("float"))) // undocumented, but useful, alternative ctrl.type = NYQ_CTRL_REAL; else if (tokens[3] == wxT("int")) ctrl.type = NYQ_CTRL_INT; else { wxString str; str.Printf(_("Bad Nyquist 'control' type specification: '%s' in plugin file '%s'.\nControl not created."), tokens[3].c_str(), mFileName.GetFullPath().c_str()); // Too disturbing to show alert before Audacity frame is up. // wxMessageBox(str, wxT("Nyquist Warning"), wxOK | wxICON_EXCLAMATION); // Note that the AudacityApp's mLogger has not yet been created, // so this brings up an alert box, but after the Audacity frame is up. wxLogWarning(str); return; } ctrl.lowStr = tokens[6]; ctrl.highStr = tokens[7]; } ctrl.val = UNINITIALIZED_CONTROL; mControls.Add(ctrl); } if (len >= 2 && tokens[0] == wxT("categories")) { for (size_t i = 1; i < tokens.GetCount(); ++i) { mCategories.Add(tokens[i]); } } }