static void listControlsForPlugin(const LADSPA_Descriptor * psDescriptor) { int bFound; unsigned long lIndex; LADSPA_PortRangeHintDescriptor iHintDescriptor; LADSPA_Data fBound; fprintf(stderr, "Plugin \"%s\" has the following control inputs:\n", psDescriptor->Name); bFound = 0; for (lIndex = 0; lIndex < psDescriptor->PortCount; lIndex++) if (LADSPA_IS_PORT_INPUT(psDescriptor->PortDescriptors[lIndex]) && LADSPA_IS_PORT_CONTROL(psDescriptor->PortDescriptors[lIndex])) { fprintf(stderr, "\t%s", psDescriptor->PortNames[lIndex]); bFound = 1; iHintDescriptor = psDescriptor->PortRangeHints[lIndex].HintDescriptor; if (LADSPA_IS_HINT_BOUNDED_BELOW(iHintDescriptor) || LADSPA_IS_HINT_BOUNDED_ABOVE(iHintDescriptor)) { fprintf(stderr, " ("); if (LADSPA_IS_HINT_BOUNDED_BELOW(iHintDescriptor)) { fBound = psDescriptor->PortRangeHints[lIndex].LowerBound; if (LADSPA_IS_HINT_SAMPLE_RATE(iHintDescriptor)) { if (fBound == 0) fprintf(stderr, "0"); else fprintf(stderr, "%g * sample rate", fBound); } else fprintf(stderr, "%g", fBound); } else fprintf(stderr, "..."); fprintf(stderr, " to "); if (LADSPA_IS_HINT_BOUNDED_ABOVE(iHintDescriptor)) { fBound = psDescriptor->PortRangeHints[lIndex].UpperBound; if (LADSPA_IS_HINT_SAMPLE_RATE(iHintDescriptor)) { if (fBound == 0) fprintf(stderr, "0"); else fprintf(stderr, "%g * sample rate", fBound); } else fprintf(stderr, "%g", fBound); } else fprintf(stderr, "..."); fprintf(stderr, ")\n"); } else fprintf(stderr, "\n"); } if (!bFound) fprintf(stderr, "\tnone\n"); }
static ControlData * parse_control (const LADSPA_Descriptor * desc, int port) { g_return_val_if_fail (desc->PortNames[port], NULL); const LADSPA_PortRangeHint * hint = & desc->PortRangeHints[port]; ControlData * control = g_slice_new (ControlData); control->port = port; control->name = g_strdup (desc->PortNames[port]); control->is_toggle = LADSPA_IS_HINT_TOGGLED (hint->HintDescriptor) ? 1 : 0; control->min = LADSPA_IS_HINT_BOUNDED_BELOW (hint->HintDescriptor) ? hint->LowerBound : LADSPA_IS_HINT_BOUNDED_ABOVE (hint->HintDescriptor) ? hint->UpperBound - 100 : -100; control->max = LADSPA_IS_HINT_BOUNDED_ABOVE (hint->HintDescriptor) ? hint->UpperBound : LADSPA_IS_HINT_BOUNDED_BELOW (hint->HintDescriptor) ? hint->LowerBound + 100 : 100; if (LADSPA_IS_HINT_SAMPLE_RATE (hint->HintDescriptor)) { control->min *= 96000; control->max *= 96000; } if (LADSPA_IS_HINT_DEFAULT_0 (hint->HintDescriptor)) control->def = 0; else if (LADSPA_IS_HINT_DEFAULT_1 (hint->HintDescriptor)) control->def = 1; else if (LADSPA_IS_HINT_DEFAULT_100 (hint->HintDescriptor)) control->def = 100; else if (LADSPA_IS_HINT_DEFAULT_440 (hint->HintDescriptor)) control->def = 440; else if (LADSPA_IS_HINT_DEFAULT_MINIMUM (hint->HintDescriptor)) control->def = control->min; else if (LADSPA_IS_HINT_DEFAULT_MAXIMUM (hint->HintDescriptor)) control->def = control->max; else if (LADSPA_IS_HINT_DEFAULT_LOW (hint->HintDescriptor)) { if (LADSPA_IS_HINT_LOGARITHMIC (hint->HintDescriptor)) control->def = expf (0.75 * logf (control->min) + 0.25 * logf (control->max)); else control->def = 0.75 * control->min + 0.25 * control->max; } else if (LADSPA_IS_HINT_DEFAULT_HIGH (hint->HintDescriptor)) { if (LADSPA_IS_HINT_LOGARITHMIC (hint->HintDescriptor)) control->def = expf (0.25 * logf (control->min) + 0.75 * logf (control->max)); else control->def = 0.25 * control->min + 0.75 * control->max; } else { if (LADSPA_IS_HINT_LOGARITHMIC (hint->HintDescriptor)) control->def = expf (0.5 * logf (control->min) + 0.5 * logf (control->max)); else control->def = 0.5 * control->min + 0.5 * control->max; } return control; }
void DemoJuceFilter::setParameter (int index, float value) { // if (index == 0) // { // if (gain != value) // { // gain = value; // // // if this is changing the gain, broadcast a change message which // // our editor will pick up. // sendChangeMessage (this); // } // } jassert (index >= 0 && index < pars.size ()); const LADSPA_PortRangeHint* hint = & ladspa->PortRangeHints [pars [index]]; float lower = hint->LowerBound * (LADSPA_IS_HINT_SAMPLE_RATE (hint->HintDescriptor) ? samplingRate : 1.0f); float upper = hint->UpperBound * (LADSPA_IS_HINT_SAMPLE_RATE (hint->HintDescriptor) ? samplingRate : 1.0f); // @TODO - Handle better lower/upper bound. this is ok for most cases // but in some others it don't if (LADSPA_IS_HINT_TOGGLED (hint->HintDescriptor)) { if (value < 0.5f) normalized [index] = 0.0f; else normalized [index] = 1.0f; } else if (LADSPA_IS_HINT_BOUNDED_BELOW (hint->HintDescriptor) && LADSPA_IS_HINT_BOUNDED_ABOVE (hint->HintDescriptor)) { if (LADSPA_IS_HINT_LOGARITHMIC(hint->HintDescriptor) && (lower >= 1.0f && upper >= 1.0f)) normalized [index] = expf(logf(lower) * value + logf(upper) * (1.0f - value)); else normalized [index] = lower + (upper - lower) * value; } else if (LADSPA_IS_HINT_BOUNDED_BELOW (hint->HintDescriptor)) { normalized [index] = value; } else if (LADSPA_IS_HINT_BOUNDED_ABOVE (hint->HintDescriptor)) { normalized [index] = value * upper; } if (LADSPA_IS_HINT_INTEGER (hint->HintDescriptor)) normalized [index] = (float) ((int) normalized [index]); params [index] = value; }
static void print_ctl_info(AVFilterContext *ctx, int level, LADSPAContext *s, int ctl, unsigned long *map, LADSPA_Data *values, int print) { const LADSPA_PortRangeHint *h = s->desc->PortRangeHints + map[ctl]; av_log(ctx, level, "c%i: %s [", ctl, s->desc->PortNames[map[ctl]]); if (LADSPA_IS_HINT_TOGGLED(h->HintDescriptor)) { av_log(ctx, level, "toggled (1 or 0)"); if (LADSPA_IS_HINT_HAS_DEFAULT(h->HintDescriptor)) av_log(ctx, level, " (default %i)", (int)values[ctl]); } else { if (LADSPA_IS_HINT_INTEGER(h->HintDescriptor)) { av_log(ctx, level, "<int>"); if (LADSPA_IS_HINT_BOUNDED_BELOW(h->HintDescriptor)) av_log(ctx, level, ", min: %i", (int)h->LowerBound); if (LADSPA_IS_HINT_BOUNDED_ABOVE(h->HintDescriptor)) av_log(ctx, level, ", max: %i", (int)h->UpperBound); if (print) av_log(ctx, level, " (value %d)", (int)values[ctl]); else if (LADSPA_IS_HINT_HAS_DEFAULT(h->HintDescriptor)) av_log(ctx, level, " (default %d)", (int)values[ctl]); } else { av_log(ctx, level, "<float>"); if (LADSPA_IS_HINT_BOUNDED_BELOW(h->HintDescriptor)) av_log(ctx, level, ", min: %f", h->LowerBound); if (LADSPA_IS_HINT_BOUNDED_ABOVE(h->HintDescriptor)) av_log(ctx, level, ", max: %f", h->UpperBound); if (print) av_log(ctx, level, " (value %f)", values[ctl]); else if (LADSPA_IS_HINT_HAS_DEFAULT(h->HintDescriptor)) av_log(ctx, level, " (default %f)", values[ctl]); } if (LADSPA_IS_HINT_SAMPLE_RATE(h->HintDescriptor)) av_log(ctx, level, ", multiple of sample rate"); if (LADSPA_IS_HINT_LOGARITHMIC(h->HintDescriptor)) av_log(ctx, level, ", logarithmic scale"); } av_log(ctx, level, "]\n"); }
void LadspaEffect::OnTextCtrl(wxCommandEvent & evt) { LadspaEffect *that = reinterpret_cast<LadspaEffect *>(this); int p = evt.GetId() - ID_TEXTS; float val; float lower = float(0.0); float upper = float(10.0); float range; val = Internat::CompatibleToDouble(that->mFields[p]->GetValue()); LADSPA_PortRangeHint hint = that->mData->PortRangeHints[p]; if (LADSPA_IS_HINT_BOUNDED_BELOW(hint.HintDescriptor)) lower = hint.LowerBound; if (LADSPA_IS_HINT_BOUNDED_ABOVE(hint.HintDescriptor)) upper = hint.UpperBound; if (LADSPA_IS_HINT_SAMPLE_RATE(hint.HintDescriptor)) { lower *= mSampleRate; upper *= mSampleRate; } range = upper - lower; if (val < lower) val = lower; if (val > upper) val = upper; mInputControls[p] = val; that->mSliders[p]->SetValue((int)(((val-lower)/range) * 1000.0 + 0.5)); }
void LadspaEffect::OnSlider(wxCommandEvent & evt) { int p = evt.GetId() - ID_SLIDERS; float val; float lower = float(0.0); float upper = float(10.0); float range; bool forceint = false; LADSPA_PortRangeHint hint = mData->PortRangeHints[p]; if (LADSPA_IS_HINT_BOUNDED_BELOW(hint.HintDescriptor)) lower = hint.LowerBound; if (LADSPA_IS_HINT_BOUNDED_ABOVE(hint.HintDescriptor)) upper = hint.UpperBound; if (LADSPA_IS_HINT_SAMPLE_RATE(hint.HintDescriptor)) { lower *= mSampleRate; upper *= mSampleRate; forceint = true; } range = upper - lower; val = (mSliders[p]->GetValue() / 1000.0) * range + lower; wxString str; if (LADSPA_IS_HINT_INTEGER(hint.HintDescriptor) || forceint) str.Printf(wxT("%d"), (int)(val + 0.5)); else str = Internat::ToDisplayString(val); mFields[p]->SetValue(str); mInputControls[p] = val; }
static int set_control(AVFilterContext *ctx, unsigned long port, LADSPA_Data value) { LADSPAContext *s = ctx->priv; const char *label = s->desc->Label; LADSPA_PortRangeHint *h = (LADSPA_PortRangeHint *)s->desc->PortRangeHints + s->icmap[port]; if (port >= s->nb_inputcontrols) { av_log(ctx, AV_LOG_ERROR, "Control c%ld is out of range [0 - %lu].\n", port, s->nb_inputcontrols); return AVERROR(EINVAL); } if (LADSPA_IS_HINT_BOUNDED_BELOW(h->HintDescriptor) && value < h->LowerBound) { av_log(ctx, AV_LOG_ERROR, "%s: input control c%ld is below lower boundary of %0.4f.\n", label, port, h->LowerBound); return AVERROR(EINVAL); } if (LADSPA_IS_HINT_BOUNDED_ABOVE(h->HintDescriptor) && value > h->UpperBound) { av_log(ctx, AV_LOG_ERROR, "%s: input control c%ld is above upper boundary of %0.4f.\n", label, port, h->UpperBound); return AVERROR(EINVAL); } s->ictlv[port] = value; return 0; }
float LadspaManager::getLowerBound( const ladspa_key_t & _plugin, uint32_t _port ) { if( m_ladspaManagerMap.contains( _plugin ) && _port < getPortCount( _plugin ) ) { LADSPA_Descriptor_Function descriptorFunction = m_ladspaManagerMap[_plugin]->descriptorFunction; const LADSPA_Descriptor * descriptor = descriptorFunction( m_ladspaManagerMap[_plugin]->index ); LADSPA_PortRangeHintDescriptor hintDescriptor = descriptor->PortRangeHints[_port].HintDescriptor; if( LADSPA_IS_HINT_BOUNDED_BELOW( hintDescriptor ) ) { return( descriptor->PortRangeHints[_port].LowerBound ); } else { return( NOHINT ); } } else { return( NOHINT ); } }
/** create a control for float ports */ static GtkWidget * create_float_control (plugin_desc_t * desc, unsigned long port_index) { LADSPA_Data lower; LADSPA_Data upper; GtkWidget *widget; if (LADSPA_IS_HINT_SAMPLE_RATE (desc->port_range_hints[port_index].HintDescriptor)) { lower = desc->port_range_hints[port_index].LowerBound * (LADSPA_Data) sample_rate; upper = desc->port_range_hints[port_index].UpperBound * (LADSPA_Data) sample_rate; } else { lower = desc->port_range_hints[port_index].LowerBound; upper = desc->port_range_hints[port_index].UpperBound; } if (!LADSPA_IS_HINT_BOUNDED_BELOW (desc->port_range_hints[port_index].HintDescriptor)) { lower = (LADSPA_Data) - 100.0; } if (!LADSPA_IS_HINT_BOUNDED_ABOVE (desc->port_range_hints[port_index].HintDescriptor)) { upper = (LADSPA_Data) 100.0; } if (LADSPA_IS_HINT_LOGARITHMIC (desc->port_range_hints[port_index].HintDescriptor)) { if (lower < FLT_EPSILON) lower = FLT_EPSILON; lower = log (lower); upper = log (upper); } widget = gtk_hscale_new_with_range ((gdouble) lower, (gdouble) upper, (upper - lower) / 10.0); gtk_scale_set_draw_value (GTK_SCALE (widget), FALSE); gtk_scale_set_digits (GTK_SCALE (widget), 8); gtk_range_set_increments (GTK_RANGE (widget), (upper - lower) / 1000.0, (upper - lower) / 10.0); g_assert (widget != NULL); return widget; }
//============================================================================== void LadspaPlugin::setParameterReal (int index, float value) { jassert (index >= 0 && index < pars.size ()); const LADSPA_PortRangeHint* hint = & ptrPlug->PortRangeHints [pars [index]]; float lower = hint->LowerBound * (LADSPA_IS_HINT_SAMPLE_RATE (hint->HintDescriptor) ? samplingRate : 1.0f); float upper = hint->UpperBound * (LADSPA_IS_HINT_SAMPLE_RATE (hint->HintDescriptor) ? samplingRate : 1.0f); // @TODO - Handle better lower/upper bound. this is ok for most cases // but in some others it don't if (LADSPA_IS_HINT_TOGGLED (hint->HintDescriptor)) { if (value < 0.5f) normalized [index] = 0.0f; else normalized [index] = 1.0f; } else if (LADSPA_IS_HINT_BOUNDED_BELOW (hint->HintDescriptor) && LADSPA_IS_HINT_BOUNDED_ABOVE (hint->HintDescriptor)) { if (LADSPA_IS_HINT_LOGARITHMIC(hint->HintDescriptor) && lower > 0.0f && upper > 0.0f) normalized [index] = expf(logf(lower) * value + logf(upper) * (1.0f - value)); else normalized [index] = lower + (upper - lower) * value; } else if (LADSPA_IS_HINT_BOUNDED_BELOW (hint->HintDescriptor)) { normalized [index] = value; } else if (LADSPA_IS_HINT_BOUNDED_ABOVE (hint->HintDescriptor)) { normalized [index] = value * upper; } if (LADSPA_IS_HINT_INTEGER (hint->HintDescriptor)) normalized [index] = (float) ((int) normalized [index]); params [index] = value; }
LadspaEffect::LadspaEffect(const LADSPA_Descriptor *data) { mData = data; pluginName = data->Name; buffer = NULL; fInBuffer = NULL; fOutBuffer = NULL; inputs = 0; outputs = 0; numInputControls = 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 = 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_SAMPLE_RATE(hint.HintDescriptor)) val *= 44100; inputControls[p] = val; } } }
/** create a control for integer ports */ static GtkWidget * create_int_control (plugin_desc_t * desc, unsigned long port_index) { int lower = 0, upper = 0; GtkWidget *widget; if (LADSPA_IS_HINT_SAMPLE_RATE (desc->port_range_hints[port_index].HintDescriptor)) { lower = desc->port_range_hints[port_index].LowerBound * (LADSPA_Data) sample_rate; upper = desc->port_range_hints[port_index].UpperBound * (LADSPA_Data) sample_rate; } else { lower = desc->port_range_hints[port_index].LowerBound; upper = desc->port_range_hints[port_index].UpperBound; } if (!LADSPA_IS_HINT_BOUNDED_BELOW (desc->port_range_hints[port_index].HintDescriptor)) { lower = -100.0; } if (!LADSPA_IS_HINT_BOUNDED_ABOVE (desc->port_range_hints[port_index].HintDescriptor)) { upper = 100.0; } if (!(lower < upper)) { if (!LADSPA_IS_HINT_BOUNDED_ABOVE (desc->port_range_hints[port_index].HintDescriptor)) { lower = upper - 100; } else { upper = lower + 100; } } widget = gtk_spin_button_new_with_range ((gdouble) lower, (gdouble) upper, 1.0); gtk_spin_button_set_numeric (GTK_SPIN_BUTTON (widget), TRUE); gtk_spin_button_set_digits (GTK_SPIN_BUTTON (widget), 0); return widget; }
static void plugin_tilde_info (Pd_Plugin_Tilde* x) { unsigned port_index = 0; t_atom at[5]; LADSPA_PortDescriptor port_type; LADSPA_PortRangeHintDescriptor iHintDescriptor; if(!plugin_tilde_have_plugin(x))return; for (port_index = 0; port_index < x->plugin.ladspa.type->PortCount; port_index++) { port_type = x->plugin.ladspa.type->PortDescriptors[port_index]; iHintDescriptor = x->plugin.ladspa.type->PortRangeHints[port_index].HintDescriptor; t_symbol*xlet=gensym("unknown"); t_symbol*type=gensym("unknown"); t_symbol*name=gensym("unknown"); t_float bound_lo=0.; t_float bound_hi=1.; if(LADSPA_IS_PORT_INPUT (port_type)) xlet=gensym("in"); else if (LADSPA_IS_PORT_OUTPUT (port_type)) xlet=gensym("out"); if (LADSPA_IS_PORT_CONTROL (port_type)) type=gensym("control"); else if (LADSPA_IS_PORT_AUDIO (port_type)) type=gensym("audio"); name=gensym(x->plugin.ladspa.type->PortNames[port_index]); if (LADSPA_IS_HINT_BOUNDED_BELOW(iHintDescriptor)) bound_lo=x->plugin.ladspa.type->PortRangeHints[port_index].LowerBound; if (LADSPA_IS_HINT_BOUNDED_ABOVE(iHintDescriptor)) bound_hi=x->plugin.ladspa.type->PortRangeHints[port_index].UpperBound; // post("port#%d: %s %s %s %f..%f", port_index, xlet->s_name, type->s_name, name->s_name, bound_lo, bound_hi); SETSYMBOL(at+0, xlet); SETSYMBOL(at+1, type); SETSYMBOL(at+2, name); SETFLOAT (at+3, bound_lo); SETFLOAT (at+4, bound_hi); outlet_anything (x->control_outlet, gensym ("port"), 5, at); } }
void LadspaEffectDialog::HandleText() { // if we don't add the following three lines, changing // the value of the slider will change the text, which // will change the slider, and so on. This gets rid of // the implicit loop. if (inSlider) return; inText = true; for (unsigned long p = 0; p < numParams; p++) { double dval; float val; float lower = float(0.0); float upper = float(10.0); float range; LADSPA_PortRangeHint hint = mData->PortRangeHints[ports[p]]; if (LADSPA_IS_HINT_TOGGLED(hint.HintDescriptor)) { continue; } dval = Internat::CompatibleToDouble(fields[p]->GetValue()); val = dval; if (LADSPA_IS_HINT_BOUNDED_BELOW(hint.HintDescriptor)) lower = hint.LowerBound; if (LADSPA_IS_HINT_BOUNDED_ABOVE(hint.HintDescriptor)) upper = hint.UpperBound; if (LADSPA_IS_HINT_SAMPLE_RATE(hint.HintDescriptor)) { lower *= sampleRate; upper *= sampleRate; } range = upper - lower; if (val < lower) val = lower; if (val > upper) val = upper; inputControls[ports[p]] = val; sliders[p]->SetValue((int)(((val-lower)/range) * 1000.0 + 0.5)); } inText = false; }
void LadspaEffectDialog::HandleSlider() { // if we don't add the following three lines, changing // the value of the slider will change the text, which // will change the slider, and so on. This gets rid of // the implicit loop. if (inText) return; inSlider = true; for (unsigned long p = 0; p < numParams; p++) { if (targetSlider && targetSlider!=sliders[p]) continue; float val; float lower = float(0.0); float upper = float(10.0); float range; LADSPA_PortRangeHint hint = mData->PortRangeHints[ports[p]]; if (LADSPA_IS_HINT_BOUNDED_BELOW(hint.HintDescriptor)) lower = hint.LowerBound; if (LADSPA_IS_HINT_BOUNDED_ABOVE(hint.HintDescriptor)) upper = hint.UpperBound; if (LADSPA_IS_HINT_SAMPLE_RATE(hint.HintDescriptor)) { lower *= sampleRate; upper *= sampleRate; } range = upper - lower; val = (sliders[p]->GetValue() / 1000.0) * range + lower; wxString str; if (LADSPA_IS_HINT_INTEGER(hint.HintDescriptor)) str.Printf("%d", (int)(val + 0.5)); else str.Printf("%f", val); fields[p]->SetValue(str); inputControls[ports[p]] = val; } inSlider = false; }
void LadspaEffectDialog::OnSlider(wxCommandEvent &event) { int p = event.GetId(); // if we don't add the following three lines, changing // the value of the slider will change the text, which // will change the slider, and so on. This gets rid of // the implicit loop. if (inText) return; inSlider = true; float val; float lower = float(0.0); float upper = float(10.0); float range; bool forceint = false; LADSPA_PortRangeHint hint = mData->PortRangeHints[ports[p]]; if (LADSPA_IS_HINT_BOUNDED_BELOW(hint.HintDescriptor)) lower = hint.LowerBound; if (LADSPA_IS_HINT_BOUNDED_ABOVE(hint.HintDescriptor)) upper = hint.UpperBound; if (LADSPA_IS_HINT_SAMPLE_RATE(hint.HintDescriptor)) { lower *= sampleRate; upper *= sampleRate; forceint = true; } range = upper - lower; val = (sliders[p]->GetValue() / 1000.0) * range + lower; wxString str; if (LADSPA_IS_HINT_INTEGER(hint.HintDescriptor) || forceint) str.Printf(wxT("%d"), (int)(val + 0.5)); else str = Internat::ToDisplayString(val); fields[p]->SetValue(str); inputControls[ports[p]] = val; inSlider = false; }
static void add_port_to_metadata( mlt_properties p, plugin_desc_t* desc, int j ) { LADSPA_Data sample_rate = 48000; LADSPA_PortRangeHintDescriptor hint_descriptor = desc->port_range_hints[j].HintDescriptor; mlt_properties_set( p, "title", desc->port_names[ j ] ); if ( LADSPA_IS_HINT_INTEGER( hint_descriptor ) ) { mlt_properties_set( p, "type", "integer" ); mlt_properties_set_int( p, "default", plugin_desc_get_default_control_value( desc, j, sample_rate ) ); } else if ( LADSPA_IS_HINT_TOGGLED( hint_descriptor ) ) { mlt_properties_set( p, "type", "boolean" ); mlt_properties_set_int( p, "default", plugin_desc_get_default_control_value( desc, j, sample_rate ) ); } else { mlt_properties_set( p, "type", "float" ); mlt_properties_set_double( p, "default", plugin_desc_get_default_control_value( desc, j, sample_rate ) ); } /* set upper and lower, possibly adjusted to the sample rate */ if ( LADSPA_IS_HINT_BOUNDED_BELOW( hint_descriptor ) ) { LADSPA_Data lower = desc->port_range_hints[j].LowerBound; if ( LADSPA_IS_HINT_SAMPLE_RATE( hint_descriptor ) ) lower *= sample_rate; if ( LADSPA_IS_HINT_LOGARITHMIC( hint_descriptor ) ) { if (lower < FLT_EPSILON) lower = FLT_EPSILON; } mlt_properties_set_double( p, "minimum", lower ); } if ( LADSPA_IS_HINT_BOUNDED_ABOVE( hint_descriptor ) ) { LADSPA_Data upper = desc->port_range_hints[j].UpperBound; if ( LADSPA_IS_HINT_SAMPLE_RATE( hint_descriptor ) ) upper *= sample_rate; mlt_properties_set_double( p, "maximum", upper ); } if ( LADSPA_IS_HINT_LOGARITHMIC( hint_descriptor ) ) mlt_properties_set( p, "scale", "log" ); }
void WiredLADSPAInstance::AddGuiControl(t_ladspa_port *PortData) { t_gui_control NewGuiPort; if (LADSPA_IS_HINT_BOUNDED_BELOW(PortData->RangeHint.HintDescriptor)) NewGuiPort.Data.LowerBound = PortData->RangeHint.LowerBound; else NewGuiPort.Data.LowerBound = 0; if (LADSPA_IS_HINT_BOUNDED_ABOVE(PortData->RangeHint.HintDescriptor)) NewGuiPort.Data.UpperBound = PortData->RangeHint.UpperBound; else NewGuiPort.Data.UpperBound = 100; NewGuiPort.Data.Data = new LADSPA_Data; *(NewGuiPort.Data.Data) = GetDefaultValue(&NewGuiPort.Data, PortData->RangeHint.HintDescriptor); NewGuiPort.Descriptor.Descriptor = PortData->Descriptor; NewGuiPort.Descriptor.RangeHint = PortData->RangeHint; NewGuiPort.Descriptor.Name = PortData->Name; NewGuiPort.Descriptor.Id = PortData->Id; _GuiControls[PortData->Id] = NewGuiPort; ConnectMonoInput((float *) NewGuiPort.Data.Data, PortData->Id); }
static mlt_properties metadata( mlt_service_type type, const char *id, char *data ) { char file[ PATH_MAX ]; if( type == filter_type ) { snprintf( file, PATH_MAX, "%s/jackrack/%s", mlt_environment( "MLT_DATA" ), strncmp( id, "ladspa.", 7 ) ? data : "filter_ladspa.yml" ); } else { snprintf( file, PATH_MAX, "%s/jackrack/%s", mlt_environment( "MLT_DATA" ), strncmp( id, "ladspa.", 7 ) ? data : "producer_ladspa.yml" ); } mlt_properties result = mlt_properties_parse_yaml( file ); #ifdef GPL if ( !strncmp( id, "ladspa.", 7 ) ) { // Annotate the yaml properties with ladspa control port info. plugin_desc_t *desc = plugin_mgr_get_any_desc( g_jackrack_plugin_mgr, strtol( id + 7, NULL, 10 ) ); if ( desc ) { mlt_properties params = mlt_properties_new(); mlt_properties p; char key[20]; int i; mlt_properties_set( result, "identifier", id ); mlt_properties_set( result, "title", desc->name ); mlt_properties_set( result, "creator", desc->maker ? desc->maker : "unknown" ); mlt_properties_set( result, "description", "LADSPA plugin" ); mlt_properties_set_data( result, "parameters", params, 0, (mlt_destructor) mlt_properties_close, NULL ); for ( i = 0; i < desc->control_port_count; i++ ) { int j = desc->control_port_indicies[i]; LADSPA_Data sample_rate = 48000; LADSPA_PortRangeHintDescriptor hint_descriptor = desc->port_range_hints[j].HintDescriptor; p = mlt_properties_new(); snprintf( key, sizeof(key), "%d", i ); mlt_properties_set_data( params, key, p, 0, (mlt_destructor) mlt_properties_close, NULL ); snprintf( key, sizeof(key), "%d", j ); mlt_properties_set( p, "identifier", key ); mlt_properties_set( p, "title", desc->port_names[ j ] ); if ( LADSPA_IS_HINT_INTEGER( hint_descriptor ) ) { mlt_properties_set( p, "type", "integer" ); mlt_properties_set_int( p, "default", plugin_desc_get_default_control_value( desc, j, sample_rate ) ); } else if ( LADSPA_IS_HINT_TOGGLED( hint_descriptor ) ) { mlt_properties_set( p, "type", "boolean" ); mlt_properties_set_int( p, "default", plugin_desc_get_default_control_value( desc, j, sample_rate ) ); } else { mlt_properties_set( p, "type", "float" ); mlt_properties_set_double( p, "default", plugin_desc_get_default_control_value( desc, j, sample_rate ) ); } /* set upper and lower, possibly adjusted to the sample rate */ if ( LADSPA_IS_HINT_BOUNDED_BELOW( hint_descriptor ) ) { LADSPA_Data lower = desc->port_range_hints[j].LowerBound; if ( LADSPA_IS_HINT_SAMPLE_RATE( hint_descriptor ) ) lower *= sample_rate; if ( LADSPA_IS_HINT_LOGARITHMIC( hint_descriptor ) ) { if (lower < FLT_EPSILON) lower = FLT_EPSILON; } mlt_properties_set_double( p, "minimum", lower ); } if ( LADSPA_IS_HINT_BOUNDED_ABOVE( hint_descriptor ) ) { LADSPA_Data upper = desc->port_range_hints[j].UpperBound; if ( LADSPA_IS_HINT_SAMPLE_RATE( hint_descriptor ) ) upper *= sample_rate; mlt_properties_set_double( p, "maximum", upper ); } if ( LADSPA_IS_HINT_LOGARITHMIC( hint_descriptor ) ) mlt_properties_set( p, "scale", "log" ); mlt_properties_set( p, "mutable", "yes" ); } if( type == filter_type ) { p = mlt_properties_new(); snprintf( key, sizeof(key), "%d", i ); mlt_properties_set_data( params, key, p, 0, (mlt_destructor) mlt_properties_close, NULL ); mlt_properties_set( p, "identifier", "wetness" ); mlt_properties_set( p, "title", "Wet/Dry" ); mlt_properties_set( p, "type", "float" ); mlt_properties_set_double( p, "default", 1 ); mlt_properties_set_double( p, "minimum", 0 ); mlt_properties_set_double( p, "maximum", 1 ); mlt_properties_set( p, "mutable", "yes" ); } } } #endif return result; }
bool LadspaEffect::SetHost(EffectHostInterface *host) { mHost = host; if (!Load()) { return false; } mInputPorts = new unsigned long [mData->PortCount]; mOutputPorts = new unsigned long [mData->PortCount]; mInputControls = new float [mData->PortCount]; mOutputControls = new float [mData->PortCount]; for (unsigned long p = 0; p < mData->PortCount; p++) { LADSPA_PortDescriptor d = mData->PortDescriptors[p]; // Collect the audio ports if (LADSPA_IS_PORT_AUDIO(d)) { if (LADSPA_IS_PORT_INPUT(d)) { mInputPorts[mAudioIns++] = p; } else if (LADSPA_IS_PORT_OUTPUT(d)) { mOutputPorts[mAudioOuts++] = p; } } // Determine the port's default value else if (LADSPA_IS_PORT_CONTROL(d) && LADSPA_IS_PORT_INPUT(d)) { mInteractive = true; LADSPA_PortRangeHint hint = mData->PortRangeHints[p]; float val = float(1.0); float lower = hint.LowerBound; float upper = hint.UpperBound; if (LADSPA_IS_HINT_SAMPLE_RATE(hint.HintDescriptor)) { lower *= mSampleRate; upper *= mSampleRate; } if (LADSPA_IS_HINT_BOUNDED_BELOW(hint.HintDescriptor) && val < lower) { val = lower; } if (LADSPA_IS_HINT_BOUNDED_ABOVE(hint.HintDescriptor) && val > upper) { val = upper; } if (LADSPA_IS_HINT_DEFAULT_MINIMUM(hint.HintDescriptor)) { val = lower; } if (LADSPA_IS_HINT_DEFAULT_MAXIMUM(hint.HintDescriptor)) { val = upper; } if (LADSPA_IS_HINT_DEFAULT_LOW(hint.HintDescriptor)) { if (LADSPA_IS_HINT_LOGARITHMIC(hint.HintDescriptor)) { val = exp(log(lower)) * 0.75f + log(upper) * 0.25f; } else { val = lower * 0.75f + upper * 0.25f; } } if (LADSPA_IS_HINT_DEFAULT_MIDDLE(hint.HintDescriptor)) { if (LADSPA_IS_HINT_LOGARITHMIC(hint.HintDescriptor)) { val = exp(log(lower)) * 0.5f + log(upper) * 0.5f; } else { val = lower * 0.5f + upper * 0.5f; } } if (LADSPA_IS_HINT_DEFAULT_HIGH(hint.HintDescriptor)) { if (LADSPA_IS_HINT_LOGARITHMIC(hint.HintDescriptor)) { val = exp(log(lower)) * 0.25f + log(upper) * 0.75f; } else { val = lower * 0.25f + upper * 0.75f; } } 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; } mNumInputControls++; mInputControls[p] = val; } else if (LADSPA_IS_PORT_CONTROL(d) && LADSPA_IS_PORT_OUTPUT(d)) { mInteractive = true; mNumOutputControls++; mOutputControls[p] = 0.0; // Ladspa effects have a convention of providing latency on an output // control port whose name is "latency". if (strcmp(mData->PortNames[p], "latency") == 0) { mLatencyPort = p; } } } // mHost will be null during registration if (mHost) { mHost->GetSharedConfig(wxT("Settings"), wxT("BufferSize"), mUserBlockSize, 8192); mBlockSize = mUserBlockSize; bool haveDefaults; mHost->GetPrivateConfig(wxT("Default"), wxT("Initialized"), haveDefaults, false); if (!haveDefaults) { SaveParameters(wxT("Default")); mHost->SetPrivateConfig(wxT("Default"), wxT("Initialized"), true); } LoadParameters(wxT("Current")); } return true; }
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; }
static int af_ladspa_parse_plugin(af_ladspa_t *setup) { int p, i; const LADSPA_Descriptor *pdes = setup->plugin_descriptor; LADSPA_PortDescriptor d; LADSPA_PortRangeHint hint; if (!setup->libhandle) return AF_ERROR; /* only call parse after a succesful load */ if (!setup->plugin_descriptor) return AF_ERROR; /* same as above */ /* let's do it */ setup->nports = pdes->PortCount; /* allocate memory for all inputs/outputs/controls */ setup->inputs = calloc(setup->nports, sizeof(int)); if (!setup->inputs) return af_ladspa_malloc_failed(setup->myname); setup->outputs = calloc(setup->nports, sizeof(int)); if (!setup->outputs) return af_ladspa_malloc_failed(setup->myname); setup->inputcontrolsmap = calloc(setup->nports, sizeof(int)); if (!setup->inputcontrolsmap) return af_ladspa_malloc_failed(setup->myname); setup->inputcontrols = calloc(setup->nports, sizeof(float)); if (!setup->inputcontrols) return af_ladspa_malloc_failed(setup->myname); setup->outputcontrolsmap = calloc(setup->nports, sizeof(int)); if (!setup->outputcontrolsmap) return af_ladspa_malloc_failed(setup->myname); setup->outputcontrols = calloc(setup->nports, sizeof(float)); if (!setup->outputcontrols) return af_ladspa_malloc_failed(setup->myname); /* set counts to zero */ setup->ninputs = 0; setup->noutputs = 0; setup->ninputcontrols = 0; setup->noutputcontrols = 0; /* check all ports, see what type it is and set variables according to * what we have found */ for (p=0; p<setup->nports; p++) { d = pdes->PortDescriptors[p]; if (LADSPA_IS_PORT_AUDIO(d)) { if (LADSPA_IS_PORT_INPUT(d)) { setup->inputs[setup->ninputs] = p; setup->ninputs++; } else if (LADSPA_IS_PORT_OUTPUT(d)) { setup->outputs[setup->noutputs] = p; setup->noutputs++; } } if (LADSPA_IS_PORT_CONTROL(d)) { if (LADSPA_IS_PORT_INPUT(d)) { setup->inputcontrolsmap[setup->ninputcontrols] = p; setup->ninputcontrols++; /* set control to zero. set values after reading the rest * of the suboptions and check LADSPA_?_HINT's later. */ setup->inputcontrols[p] = 0.0f; } else if (LADSPA_IS_PORT_OUTPUT(d)) { /* read and handle these too, otherwise filters that have them * will sig11 */ setup->outputcontrolsmap[setup->noutputcontrols]=p; setup->noutputcontrols++; setup->outputcontrols[p] = 0.0f; } } } if (setup->ninputs == 0) { mp_msg(MSGT_AFILTER, MSGL_WARN, "%s: %s\n", setup->myname, MSGTR_AF_LADSPA_WarnNoInputs); } else if (setup->ninputs == 1) { mp_msg(MSGT_AFILTER, MSGL_V, "%s: this is a mono effect\n", setup->myname); } else if (setup->ninputs == 2) { mp_msg(MSGT_AFILTER, MSGL_V, "%s: this is a stereo effect\n", setup->myname); } else { mp_msg(MSGT_AFILTER, MSGL_V, "%s: this is a %i-channel effect, " "support is experimental\n", setup->myname, setup->ninputs); } if (setup->noutputs == 0) { mp_msg(MSGT_AFILTER, MSGL_ERR, "%s: %s\n", setup->myname, MSGTR_AF_LADSPA_ErrNoOutputs); return AF_ERROR; } if (setup->noutputs != setup->ninputs ) { mp_msg(MSGT_AFILTER, MSGL_ERR, "%s: %s\n", setup->myname, MSGTR_AF_LADSPA_ErrInOutDiff); return AF_ERROR; } mp_msg(MSGT_AFILTER, MSGL_V, "%s: this plugin has %d input control(s)\n", setup->myname, setup->ninputcontrols); /* Print list of controls and its range of values it accepts */ for (i=0; i<setup->ninputcontrols; i++) { p = setup->inputcontrolsmap[i]; hint = pdes->PortRangeHints[p]; mp_msg(MSGT_AFILTER, MSGL_V, " --- %d %s [", i, pdes->PortNames[p]); if (LADSPA_IS_HINT_BOUNDED_BELOW(hint.HintDescriptor)) { mp_msg(MSGT_AFILTER, MSGL_V, "%0.2f , ", hint.LowerBound); } else { mp_msg(MSGT_AFILTER, MSGL_V, "... , "); } if (LADSPA_IS_HINT_BOUNDED_ABOVE(hint.HintDescriptor)) { mp_msg(MSGT_AFILTER, MSGL_V, "%0.2f]\n", hint.UpperBound); } else { mp_msg(MSGT_AFILTER, MSGL_V, "...]\n"); } } return AF_OK; }
static int control(struct af_instance_s *af, int cmd, void *arg) { af_ladspa_t *setup = (af_ladspa_t*) af->setup; int i, r; float val; switch(cmd) { case AF_CONTROL_REINIT: mp_msg(MSGT_AFILTER, MSGL_V, "%s: (re)init\n", setup->myname); if (!arg) return AF_ERROR; /* accept FLOAT, let af_format do conversion */ af->data->rate = ((af_data_t*)arg)->rate; af->data->nch = ((af_data_t*)arg)->nch; af->data->format = AF_FORMAT_FLOAT_NE; af->data->bps = 4; /* arg->len is not set here yet, so init of buffers and connecting the * filter, has to be done in play() :-/ */ return af_test_output(af, (af_data_t*)arg); case AF_CONTROL_COMMAND_LINE: { char *buf; mp_msg(MSGT_AFILTER, MSGL_V, "%s: parse suboptions\n", setup->myname); /* suboption parser here! * format is (ladspa=)file:label:controls.... */ if (!arg) { mp_msg(MSGT_AFILTER, MSGL_ERR, "%s: %s\n", setup->myname, MSGTR_AF_LADSPA_ErrNoSuboptions); return AF_ERROR; } buf = malloc(strlen(arg)+1); if (!buf) return af_ladspa_malloc_failed(setup->myname); /* file... */ buf[0] = '\0'; sscanf(arg, "%[^:]", buf); if (buf[0] == '\0') { mp_msg(MSGT_AFILTER, MSGL_ERR, "%s: %s\n", setup->myname, MSGTR_AF_LADSPA_ErrNoLibFile); free(buf); return AF_ERROR; } arg += strlen(buf); setup->file = strdup(buf); if (!setup->file) return af_ladspa_malloc_failed(setup->myname); mp_msg(MSGT_AFILTER, MSGL_V, "%s: file --> %s\n", setup->myname, setup->file); if (*(char*)arg != '\0') arg++; /* read ':' */ /* label... */ buf[0] = '\0'; sscanf(arg, "%[^:]", buf); if (buf[0] == '\0') { mp_msg(MSGT_AFILTER, MSGL_ERR, "%s: %s\n", setup->myname, MSGTR_AF_LADSPA_ErrNoLabel); free(buf); return AF_ERROR; } arg += strlen(buf); setup->label = strdup(buf); if (!setup->label) return af_ladspa_malloc_failed(setup->myname); mp_msg(MSGT_AFILTER, MSGL_V, "%s: label --> %s\n", setup->myname, setup->label); /* if (*(char*)arg != '0') arg++; */ /* read ':' */ free(buf); /* no longer needed */ /* set new setup->myname */ free(setup->myname); setup->myname = calloc(strlen(af_info_ladspa.name)+strlen(setup->file)+ strlen(setup->label)+6, 1); snprintf(setup->myname, strlen(af_info_ladspa.name)+ strlen(setup->file)+strlen(setup->label)+6, "%s: (%s:%s)", af_info_ladspa.name, setup->file, setup->label); /* load plugin :) */ if ( af_ladspa_load_plugin(setup) != AF_OK ) return AF_ERROR; /* see what inputs, outputs and controls this plugin has */ if ( af_ladspa_parse_plugin(setup) != AF_OK ) return AF_ERROR; /* ninputcontrols is set by now, read control values from arg */ for(i=0; i<setup->ninputcontrols; i++) { if (!arg || (*(char*)arg != ':') ) { mp_msg(MSGT_AFILTER, MSGL_ERR, "%s: %s\n", setup->myname, MSGTR_AF_LADSPA_ErrNotEnoughControls); return AF_ERROR; } arg++; r = sscanf(arg, "%f", &val); if (r!=1) { mp_msg(MSGT_AFILTER, MSGL_ERR, "%s: %s\n", setup->myname, MSGTR_AF_LADSPA_ErrNotEnoughControls); return AF_ERROR; } setup->inputcontrols[setup->inputcontrolsmap[i]] = val; arg = strchr(arg, ':'); } mp_msg(MSGT_AFILTER, MSGL_V, "%s: input controls: ", setup->myname); for(i=0; i<setup->ninputcontrols; i++) { mp_msg(MSGT_AFILTER, MSGL_V, "%0.4f ", setup->inputcontrols[setup->inputcontrolsmap[i]]); } mp_msg(MSGT_AFILTER, MSGL_V, "\n"); /* check boundaries of inputcontrols */ mp_msg(MSGT_AFILTER, MSGL_V, "%s: checking boundaries of input controls\n", setup->myname); for(i=0; i<setup->ninputcontrols; i++) { int p = setup->inputcontrolsmap[i]; LADSPA_PortRangeHint hint = setup->plugin_descriptor->PortRangeHints[p]; val = setup->inputcontrols[p]; if (LADSPA_IS_HINT_BOUNDED_BELOW(hint.HintDescriptor) && val < hint.LowerBound) { mp_msg(MSGT_AFILTER, MSGL_ERR, MSGTR_AF_LADSPA_ErrControlBelow, setup->myname, i, hint.LowerBound); return AF_ERROR; } if (LADSPA_IS_HINT_BOUNDED_ABOVE(hint.HintDescriptor) && val > hint.UpperBound) { mp_msg(MSGT_AFILTER, MSGL_ERR, MSGTR_AF_LADSPA_ErrControlAbove, setup->myname, i, hint.UpperBound); return AF_ERROR; } } mp_msg(MSGT_AFILTER, MSGL_V, "%s: all controls have sane values\n", setup->myname); /* All is well! */ setup->status = AF_OK; return AF_OK; } } return AF_UNKNOWN; }
//============================================================================== void DssiPlugin::setDefaultProgram () { if (ladspa == 0) return; // TODO - keep in a function instead ! for (int i = 0; i < pars.size (); i++) { const LADSPA_PortRangeHint* hint = & ladspa->PortRangeHints [pars [i]]; float lower = hint->LowerBound * (LADSPA_IS_HINT_SAMPLE_RATE (hint->HintDescriptor) ? samplingRate : 1.0f); float upper = hint->UpperBound * (LADSPA_IS_HINT_SAMPLE_RATE (hint->HintDescriptor) ? samplingRate : 1.0f); if (LADSPA_IS_HINT_HAS_DEFAULT (hint->HintDescriptor)) { if (LADSPA_IS_HINT_DEFAULT_0 (hint->HintDescriptor)) { normalized [i] = 0.0f; params [i] = 0.0f; } if (LADSPA_IS_HINT_DEFAULT_1 (hint->HintDescriptor)) { normalized [i] = 1.0f; params [i] = 1.0f; } if (LADSPA_IS_HINT_DEFAULT_100 (hint->HintDescriptor)) { normalized [i] = 100.0f; params [i] = 0.5f; } if (LADSPA_IS_HINT_DEFAULT_440 (hint->HintDescriptor)) { normalized [i] = 440.0f; params [i] = 0.5f; } if (LADSPA_IS_HINT_BOUNDED_BELOW(hint->HintDescriptor) && LADSPA_IS_HINT_DEFAULT_MINIMUM (hint->HintDescriptor)) { normalized [i] = lower; params [i] = 0.0f; } if (LADSPA_IS_HINT_BOUNDED_BELOW(hint->HintDescriptor) && LADSPA_IS_HINT_DEFAULT_MINIMUM (hint->HintDescriptor)) { normalized [i] = lower; params [i] = 0.0f; } if (LADSPA_IS_HINT_BOUNDED_ABOVE(hint->HintDescriptor) && LADSPA_IS_HINT_DEFAULT_MAXIMUM (hint->HintDescriptor)) { normalized [i] = upper; params [i] = 1.0f; } if (LADSPA_IS_HINT_BOUNDED_BELOW(hint->HintDescriptor)) { if (LADSPA_IS_HINT_LOGARITHMIC(hint->HintDescriptor) && lower > 0.0f && upper > 0.0f) { if (LADSPA_IS_HINT_DEFAULT_LOW(hint->HintDescriptor)) { normalized [i] = expf(logf(lower) * 0.75f + logf(upper) * 0.25f); params [i] = 0.25f; } else if (LADSPA_IS_HINT_DEFAULT_MIDDLE(hint->HintDescriptor)) { normalized [i] = expf(logf(lower) * 0.5f + logf(upper) * 0.5f); params [i] = 0.5f; } else if (LADSPA_IS_HINT_DEFAULT_HIGH(hint->HintDescriptor)) { normalized [i] = expf(logf(lower) * 0.25f + logf(upper) * 0.75f); params [i] = 0.75f; } } else { if (LADSPA_IS_HINT_DEFAULT_LOW(hint->HintDescriptor)) { normalized [i] = lower * 0.75f + upper * 0.25f; params [i] = 0.25f; } else if (LADSPA_IS_HINT_DEFAULT_MIDDLE(hint->HintDescriptor)) { normalized [i] = lower * 0.5f + upper * 0.5f; params [i] = 0.5f; } else if (LADSPA_IS_HINT_DEFAULT_HIGH(hint->HintDescriptor)) { normalized [i] = lower * 0.25f + upper * 0.75f; params [i] = 0.75f; } } } } else { normalized [i] = 0.0f; params [i] = 0.0f; } } }
int lp_ladspa_knob_float::init(const LADSPA_Descriptor *descriptor, unsigned long port, int samplerate) { LADSPA_Data f_val, f_low, f_high; if(descriptor == 0){ std::cerr << "lp_ladspa_slider_int::" << __FUNCTION__ << ": pdescriptor is Null\n"; return -1; } pv_samplerate = samplerate; LADSPA_PortRangeHintDescriptor hints; hints = descriptor->PortRangeHints[port].HintDescriptor; LADSPA_PortRangeHint range_hints; range_hints = descriptor->PortRangeHints[port]; if(LADSPA_IS_HINT_BOUNDED_BELOW(hints)){ f_val = range_hints.LowerBound; if(LADSPA_IS_HINT_SAMPLE_RATE(hints) && f_val != 0){ f_val = f_val * (LADSPA_Data)pv_samplerate; } pv_low_val = (double)f_val; f_low = f_val; }else{ // Set a default val pv_low_val = pv_default_low_val; f_low = (LADSPA_Data)pv_default_low_val; } if(LADSPA_IS_HINT_BOUNDED_ABOVE(hints)){ f_val = range_hints.UpperBound; if(LADSPA_IS_HINT_SAMPLE_RATE(hints) && f_val != 0){ f_val = f_val * (LADSPA_Data)pv_samplerate; } pv_high_val = (double)f_val; f_high = f_val; }else{ // Set a default val pv_high_val = pv_default_high_val; f_high = (LADSPA_Data)pv_default_high_val; } if(LADSPA_IS_HINT_LOGARITHMIC(hints)){ pv_is_log = true; // verifiy we have somthing else than 0 if(pv_low_val == 0){ pv_low_val = pv_default_low_val; } if(pv_high_val == 0){ pv_high_val = pv_default_high_val; } // Set the log scale kb_val->setScaleEngine(log10_scale_engine); kb_val->setScale(pv_low_val, pv_high_val); // Set this range to the spinbox sp_val->setRange(pv_low_val, pv_high_val); // Calcule the slider range double d_low, d_high; d_low = log10(pv_low_val); d_high = log10(pv_high_val); // Set range to the slider kb_val->setRange(d_low, d_high); }else{ // Set range to the slider and spinbox kb_val->setRange(pv_low_val, pv_high_val); sp_val->setRange(pv_low_val, pv_high_val); } // Store the range in f_val's f_low = (LADSPA_Data)pv_low_val; f_high = (LADSPA_Data)pv_high_val; // Default values if(LADSPA_IS_HINT_HAS_DEFAULT(hints)){ if(LADSPA_IS_HINT_DEFAULT_MINIMUM(hints)){ pv_def_val = pv_low_val; } if(LADSPA_IS_HINT_DEFAULT_MAXIMUM(hints)){ pv_def_val = pv_high_val; } if(LADSPA_IS_HINT_DEFAULT_LOW(hints)){ if(LADSPA_IS_HINT_LOGARITHMIC(hints)){ f_val = exp(log(f_low)*0.75f + log(f_high)*0.25f); }else{ f_val = (f_low*0.75f + f_high*0.25f); } } if(LADSPA_IS_HINT_DEFAULT_MIDDLE(hints)){ if(LADSPA_IS_HINT_LOGARITHMIC(hints)){ f_val = exp(log(f_low)*0.5f + log(f_high)*0.5f); }else{ f_val = (f_low*0.5f + f_high*0.5f); } } if(LADSPA_IS_HINT_DEFAULT_HIGH(hints)){ if(LADSPA_IS_HINT_LOGARITHMIC(hints)){ f_val = exp(log(f_low)*0.25f + log(f_high)*0.75f); }else{ f_val = (f_low*0.25f + f_high*0.75f); } } if(LADSPA_IS_HINT_DEFAULT_0(hints)){ f_val = 0.0f; } if(LADSPA_IS_HINT_DEFAULT_1(hints)){ f_val = 1.0f; } if(LADSPA_IS_HINT_DEFAULT_100(hints)){ f_val = 100.0f; } if(LADSPA_IS_HINT_DEFAULT_440(hints)){ f_val = 440.0f; } // Set default value pv_def_val = (double)f_val; }else{ pv_def_val = pv_low_val; } txt_name->setText(descriptor->PortNames[port]); // set the middle value set_def_val(); emit_changed(pv_def_val); return 0; }
static GParamSpec * gst_ladspa_class_get_param_spec (GstLADSPAClass * klass, gint portnum) { LADSPA_Descriptor *desc; GParamSpec *ret; gchar *name; gint hintdesc, perms; gfloat lower, upper, def; desc = klass->descriptor; name = gst_ladspa_class_get_param_name (klass, portnum); perms = G_PARAM_READABLE; if (LADSPA_IS_PORT_INPUT (desc->PortDescriptors[portnum])) perms |= G_PARAM_WRITABLE | G_PARAM_CONSTRUCT; if (LADSPA_IS_PORT_CONTROL (desc->PortDescriptors[portnum])) perms |= GST_PARAM_CONTROLLABLE; /* short name for hint descriptor */ hintdesc = desc->PortRangeHints[portnum].HintDescriptor; if (LADSPA_IS_HINT_TOGGLED (hintdesc)) { ret = g_param_spec_boolean (name, name, name, FALSE, perms); g_free (name); return ret; } if (LADSPA_IS_HINT_BOUNDED_BELOW (hintdesc)) lower = desc->PortRangeHints[portnum].LowerBound; else lower = -G_MAXFLOAT; if (LADSPA_IS_HINT_BOUNDED_ABOVE (hintdesc)) upper = desc->PortRangeHints[portnum].UpperBound; else upper = G_MAXFLOAT; if (LADSPA_IS_HINT_SAMPLE_RATE (hintdesc)) { /* FIXME! */ lower *= 44100; upper *= 44100; } if (LADSPA_IS_HINT_INTEGER (hintdesc)) { lower = CLAMP (lower, G_MININT, G_MAXINT); upper = CLAMP (upper, G_MININT, G_MAXINT); } /* default to lower bound */ def = lower; #ifdef LADSPA_IS_HINT_HAS_DEFAULT if (LADSPA_IS_HINT_HAS_DEFAULT (hintdesc)) { if (LADSPA_IS_HINT_DEFAULT_0 (hintdesc)) def = 0.0; else if (LADSPA_IS_HINT_DEFAULT_1 (hintdesc)) def = 1.0; else if (LADSPA_IS_HINT_DEFAULT_100 (hintdesc)) def = 100.0; else if (LADSPA_IS_HINT_DEFAULT_440 (hintdesc)) def = 440.0; if (LADSPA_IS_HINT_DEFAULT_MINIMUM (hintdesc)) def = lower; else if (LADSPA_IS_HINT_DEFAULT_MAXIMUM (hintdesc)) def = upper; else if (LADSPA_IS_HINT_LOGARITHMIC (hintdesc)) { if (LADSPA_IS_HINT_DEFAULT_LOW (hintdesc)) def = exp (0.75 * log (lower) + 0.25 * log (upper)); else if (LADSPA_IS_HINT_DEFAULT_MIDDLE (hintdesc)) def = exp (0.5 * log (lower) + 0.5 * log (upper)); else if (LADSPA_IS_HINT_DEFAULT_HIGH (hintdesc)) def = exp (0.25 * log (lower) + 0.75 * log (upper)); } else { if (LADSPA_IS_HINT_DEFAULT_LOW (hintdesc)) def = 0.75 * lower + 0.25 * upper; else if (LADSPA_IS_HINT_DEFAULT_MIDDLE (hintdesc)) def = 0.5 * lower + 0.5 * upper; else if (LADSPA_IS_HINT_DEFAULT_HIGH (hintdesc)) def = 0.25 * lower + 0.75 * upper; } } #endif /* LADSPA_IS_HINT_HAS_DEFAULT */ if (lower > upper) { gfloat tmp; /* silently swap */ tmp = lower; lower = upper; upper = tmp; } def = CLAMP (def, lower, upper); if (LADSPA_IS_HINT_INTEGER (hintdesc)) { ret = g_param_spec_int (name, name, name, lower, upper, def, perms); } else { ret = g_param_spec_float (name, name, name, lower, upper, def, perms); } g_free (name); return ret; }
LADSPA_Data plugin_desc_get_default_control_value (plugin_desc_t * pd, unsigned long port_index, guint32 sample_rate) { LADSPA_Data upper, lower; LADSPA_PortRangeHintDescriptor hint_descriptor; hint_descriptor = pd->port_range_hints[port_index].HintDescriptor; /* set upper and lower, possibly adjusted to the sample rate */ if (LADSPA_IS_HINT_SAMPLE_RATE(hint_descriptor)) { upper = pd->port_range_hints[port_index].UpperBound * (LADSPA_Data) sample_rate; lower = pd->port_range_hints[port_index].LowerBound * (LADSPA_Data) sample_rate; } else { upper = pd->port_range_hints[port_index].UpperBound; lower = pd->port_range_hints[port_index].LowerBound; } if (LADSPA_IS_HINT_LOGARITHMIC(hint_descriptor)) { if (lower < FLT_EPSILON) lower = FLT_EPSILON; } if (LADSPA_IS_HINT_HAS_DEFAULT(hint_descriptor)) { if (LADSPA_IS_HINT_DEFAULT_MINIMUM(hint_descriptor)) { return lower; } else if (LADSPA_IS_HINT_DEFAULT_LOW(hint_descriptor)) { if (LADSPA_IS_HINT_LOGARITHMIC(hint_descriptor)) { return exp(log(lower) * 0.75 + log(upper) * 0.25); } else { return lower * 0.75 + upper * 0.25; } } else if (LADSPA_IS_HINT_DEFAULT_MIDDLE(hint_descriptor)) { if (LADSPA_IS_HINT_LOGARITHMIC(hint_descriptor)) { return exp(log(lower) * 0.5 + log(upper) * 0.5); } else { return lower * 0.5 + upper * 0.5; } } else if (LADSPA_IS_HINT_DEFAULT_HIGH(hint_descriptor)) { if (LADSPA_IS_HINT_LOGARITHMIC(hint_descriptor)) { return exp(log(lower) * 0.25 + log(upper) * 0.75); } else { return lower * 0.25 + upper * 0.75; } } else if (LADSPA_IS_HINT_DEFAULT_MAXIMUM(hint_descriptor)) { return upper; } else if (LADSPA_IS_HINT_DEFAULT_0(hint_descriptor)) { return 0.0; } else if (LADSPA_IS_HINT_DEFAULT_1(hint_descriptor)) { if (LADSPA_IS_HINT_SAMPLE_RATE(hint_descriptor)) { return (LADSPA_Data) sample_rate; } else { return 1.0; } } else if (LADSPA_IS_HINT_DEFAULT_100(hint_descriptor)) { if (LADSPA_IS_HINT_SAMPLE_RATE(hint_descriptor)) { return 100.0 * (LADSPA_Data) sample_rate; } else { return 100.0; } } else if (LADSPA_IS_HINT_DEFAULT_440(hint_descriptor)) { if (LADSPA_IS_HINT_SAMPLE_RATE(hint_descriptor)) { return 440.0 * (LADSPA_Data) sample_rate; } else { return 440.0; } } } else { /* try and find a reasonable default */ if (LADSPA_IS_HINT_BOUNDED_BELOW(hint_descriptor)) { return lower; } else if (LADSPA_IS_HINT_BOUNDED_ABOVE(hint_descriptor)) { return upper; } } return 0.0; }
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; }
static av_cold int init(AVFilterContext *ctx) { LADSPAContext *s = ctx->priv; LADSPA_Descriptor_Function descriptor_fn; const LADSPA_Descriptor *desc; LADSPA_PortDescriptor pd; AVFilterPad pad = { NULL }; char *p, *arg, *saveptr = NULL; unsigned long nb_ports; int i; if (!s->dl_name) { av_log(ctx, AV_LOG_ERROR, "No plugin name provided\n"); return AVERROR(EINVAL); } if (s->dl_name[0] == '/' || s->dl_name[0] == '.') { // argument is a path s->dl_handle = dlopen(s->dl_name, RTLD_LOCAL|RTLD_NOW); } else { // argument is a shared object name char *paths = av_strdup(getenv("LADSPA_PATH")); const char *separator = ":"; if (paths) { p = paths; while ((arg = av_strtok(p, separator, &saveptr)) && !s->dl_handle) { s->dl_handle = try_load(arg, s->dl_name); p = NULL; } } av_free(paths); if (!s->dl_handle && (paths = av_asprintf("%s/.ladspa/lib", getenv("HOME")))) { s->dl_handle = try_load(paths, s->dl_name); av_free(paths); } if (!s->dl_handle) s->dl_handle = try_load("/usr/local/lib/ladspa", s->dl_name); if (!s->dl_handle) s->dl_handle = try_load("/usr/lib/ladspa", s->dl_name); } if (!s->dl_handle) { av_log(ctx, AV_LOG_ERROR, "Failed to load '%s'\n", s->dl_name); return AVERROR(EINVAL); } descriptor_fn = dlsym(s->dl_handle, "ladspa_descriptor"); if (!descriptor_fn) { av_log(ctx, AV_LOG_ERROR, "Could not find ladspa_descriptor: %s\n", dlerror()); return AVERROR(EINVAL); } // Find the requested plugin, or list plugins if (!s->plugin) { av_log(ctx, AV_LOG_INFO, "The '%s' library contains the following plugins:\n", s->dl_name); av_log(ctx, AV_LOG_INFO, "I = Input Channels\n"); av_log(ctx, AV_LOG_INFO, "O = Output Channels\n"); av_log(ctx, AV_LOG_INFO, "I:O %-25s %s\n", "Plugin", "Description"); av_log(ctx, AV_LOG_INFO, "\n"); for (i = 0; desc = descriptor_fn(i); i++) { unsigned long inputs = 0, outputs = 0; count_ports(desc, &inputs, &outputs); av_log(ctx, AV_LOG_INFO, "%lu:%lu %-25s %s\n", inputs, outputs, desc->Label, av_x_if_null(desc->Name, "?")); av_log(ctx, AV_LOG_VERBOSE, "Maker: %s\n", av_x_if_null(desc->Maker, "?")); av_log(ctx, AV_LOG_VERBOSE, "Copyright: %s\n", av_x_if_null(desc->Copyright, "?")); } return AVERROR_EXIT; } else { for (i = 0;; i++) { desc = descriptor_fn(i); if (!desc) { av_log(ctx, AV_LOG_ERROR, "Could not find plugin: %s\n", s->plugin); return AVERROR(EINVAL); } if (desc->Label && !strcmp(desc->Label, s->plugin)) break; } } s->desc = desc; nb_ports = desc->PortCount; s->ipmap = av_calloc(nb_ports, sizeof(*s->ipmap)); s->opmap = av_calloc(nb_ports, sizeof(*s->opmap)); s->icmap = av_calloc(nb_ports, sizeof(*s->icmap)); s->ocmap = av_calloc(nb_ports, sizeof(*s->ocmap)); s->ictlv = av_calloc(nb_ports, sizeof(*s->ictlv)); s->octlv = av_calloc(nb_ports, sizeof(*s->octlv)); s->ctl_needs_value = av_calloc(nb_ports, sizeof(*s->ctl_needs_value)); if (!s->ipmap || !s->opmap || !s->icmap || !s->ocmap || !s->ictlv || !s->octlv || !s->ctl_needs_value) return AVERROR(ENOMEM); for (i = 0; i < nb_ports; i++) { pd = desc->PortDescriptors[i]; if (LADSPA_IS_PORT_AUDIO(pd)) { if (LADSPA_IS_PORT_INPUT(pd)) { s->ipmap[s->nb_inputs] = i; s->nb_inputs++; } else if (LADSPA_IS_PORT_OUTPUT(pd)) { s->opmap[s->nb_outputs] = i; s->nb_outputs++; } } else if (LADSPA_IS_PORT_CONTROL(pd)) { if (LADSPA_IS_PORT_INPUT(pd)) { s->icmap[s->nb_inputcontrols] = i; if (LADSPA_IS_HINT_HAS_DEFAULT(desc->PortRangeHints[i].HintDescriptor)) set_default_ctl_value(s, s->nb_inputcontrols, s->icmap, s->ictlv); else s->ctl_needs_value[s->nb_inputcontrols] = 1; s->nb_inputcontrols++; } else if (LADSPA_IS_PORT_OUTPUT(pd)) { s->ocmap[s->nb_outputcontrols] = i; s->nb_outputcontrols++; } } } // List Control Ports if "help" is specified if (s->options && !strcmp(s->options, "help")) { if (!s->nb_inputcontrols) { av_log(ctx, AV_LOG_INFO, "The '%s' plugin does not have any input controls.\n", desc->Label); } else { av_log(ctx, AV_LOG_INFO, "The '%s' plugin has the following input controls:\n", desc->Label); for (i = 0; i < s->nb_inputcontrols; i++) print_ctl_info(ctx, AV_LOG_INFO, s, i, s->icmap, s->ictlv, 0); } return AVERROR_EXIT; } // Parse control parameters p = s->options; while (s->options) { LADSPA_PortRangeHint *h; LADSPA_Data val; if (!(arg = av_strtok(p, "|", &saveptr))) break; p = NULL; if (sscanf(arg, "c%d=%f", &i, &val) != 2) { av_log(ctx, AV_LOG_ERROR, "Invalid syntax.\n"); return AVERROR(EINVAL); } if (i < 0 || i >= s->nb_inputcontrols) { av_log(ctx, AV_LOG_ERROR, "Control c%d is out of range [0 - %lu].\n", i, s->nb_inputcontrols); return AVERROR(EINVAL); } h = (LADSPA_PortRangeHint *)s->desc->PortRangeHints + s->icmap[i]; s->ictlv[i] = val; s->ctl_needs_value[i] = 0; if (LADSPA_IS_HINT_BOUNDED_BELOW(h->HintDescriptor) && val < h->LowerBound) { av_log(ctx, AV_LOG_ERROR, "%s: input control c%d is below lower boundary of %0.4f.\n", s->desc->Label, i, h->LowerBound); return AVERROR(EINVAL); } if (LADSPA_IS_HINT_BOUNDED_ABOVE(h->HintDescriptor) && val > h->UpperBound) { av_log(ctx, AV_LOG_ERROR, "%s: input control c%d is above upper boundary of %0.4f.\n", s->desc->Label, i, h->UpperBound); return AVERROR(EINVAL); } } // Check if any controls are not set for (i = 0; i < s->nb_inputcontrols; i++) { if (s->ctl_needs_value[i]) { av_log(ctx, AV_LOG_ERROR, "Control c%d must be set.\n", i); print_ctl_info(ctx, AV_LOG_ERROR, s, i, s->icmap, s->ictlv, 0); return AVERROR(EINVAL); } } pad.type = AVMEDIA_TYPE_AUDIO; if (s->nb_inputs) { pad.name = av_asprintf("in0:%s%lu", desc->Label, s->nb_inputs); if (!pad.name) return AVERROR(ENOMEM); pad.filter_frame = filter_frame; pad.config_props = config_input; if (ff_insert_inpad(ctx, ctx->nb_inputs, &pad) < 0) { av_freep(&pad.name); return AVERROR(ENOMEM); } } av_log(ctx, AV_LOG_DEBUG, "ports: %lu\n", nb_ports); av_log(ctx, AV_LOG_DEBUG, "inputs: %lu outputs: %lu\n", s->nb_inputs, s->nb_outputs); av_log(ctx, AV_LOG_DEBUG, "input controls: %lu output controls: %lu\n", s->nb_inputcontrols, s->nb_outputcontrols); return 0; }