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"); }
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; }
CAMLprim value ocaml_ladspa_port_get_default(value d, value samplerate, value n) { CAMLparam1(d); CAMLlocal1(ans); assert(LADSPA_IS_PORT_CONTROL(LADSPA_descr_val(d)->PortDescriptors[Int_val(n)])); const LADSPA_PortRangeHint ri = LADSPA_descr_val(d)->PortRangeHints[Int_val(n)]; LADSPA_PortRangeHintDescriptor h = ri.HintDescriptor; float lower = ri.LowerBound; float upper = ri.UpperBound; float def = 0.; if (LADSPA_IS_HINT_SAMPLE_RATE(h)) { lower *= Int_val(samplerate); upper *= Int_val(samplerate); } if LADSPA_IS_HINT_HAS_DEFAULT(h) { if LADSPA_IS_HINT_DEFAULT_MINIMUM(h) def = lower; else if LADSPA_IS_HINT_DEFAULT_LOW(h) if LADSPA_IS_HINT_LOGARITHMIC(h) def = exp(log(lower) * 0.75 + log(upper) * 0.25); else
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; }
void settings_set_sample_rate (settings_t * settings, guint32 sample_rate) { LADSPA_Data old_sample_rate; LADSPA_Data new_sample_rate; g_return_if_fail (settings != NULL); if (settings->sample_rate == sample_rate) return; if (settings->desc->control_port_count > 0) { unsigned long control; guint copy; new_sample_rate = (LADSPA_Data) sample_rate; old_sample_rate = (LADSPA_Data) settings->sample_rate; for (control = 0; control < settings->desc->control_port_count; control++) { for (copy = 0; copy < settings->copies; copy++) { if (LADSPA_IS_HINT_SAMPLE_RATE (settings->desc->port_range_hints[control].HintDescriptor)) { settings->control_values[copy][control] = (settings->control_values[copy][control] / old_sample_rate) * new_sample_rate; } } } } settings->sample_rate = sample_rate; }
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; }
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" ); }
/** 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 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 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; }
bool LadspaManager::areHintsSampleRateDependent( 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; return( LADSPA_IS_HINT_SAMPLE_RATE ( hintDescriptor ) ); } else { return( false ); } }
LADSPA_Data plugin_desc_change_control_value (plugin_desc_t * pd, unsigned long control_index, LADSPA_Data value, guint32 old_sample_rate, guint32 new_sample_rate) { if (LADSPA_IS_HINT_SAMPLE_RATE (pd->port_range_hints[control_index].HintDescriptor)) { LADSPA_Data old_sr, new_sr; old_sr = (LADSPA_Data) old_sample_rate; new_sr = (LADSPA_Data) new_sample_rate; value /= old_sr; value *= new_sr; } return value; }
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; }
void LadspaEffect::RefreshControls(bool outputOnly) { if (!mParent) { return; } for (unsigned long p = 0; p < mData->PortCount; p++) { LADSPA_PortDescriptor d = mData->PortDescriptors[p]; if (!(LADSPA_IS_PORT_CONTROL(d))) { continue; } wxString fieldText; LADSPA_PortRangeHint hint = mData->PortRangeHints[p]; bool forceint = false; if (LADSPA_IS_HINT_SAMPLE_RATE(hint.HintDescriptor)) { forceint = true; } if (LADSPA_IS_PORT_OUTPUT(d)) { if (LADSPA_IS_HINT_INTEGER(hint.HintDescriptor) || forceint) { fieldText.Printf(wxT("%d"), (int)(mOutputControls[p] + 0.5)); } else { fieldText = Internat::ToDisplayString(mOutputControls[p]); } mFields[p]->SetValue(fieldText); continue; } if (outputOnly) { continue; } if (LADSPA_IS_HINT_TOGGLED(hint.HintDescriptor)) { mToggles[p]->SetValue(mInputControls[p] > 0); continue; } if (LADSPA_IS_HINT_INTEGER(hint.HintDescriptor) || forceint) { fieldText.Printf(wxT("%d"), (int)(mInputControls[p] + 0.5)); } else { fieldText = Internat::ToDisplayString(mInputControls[p]); } // Set the textctrl value. This will trigger an event so OnTextCtrl() // can update the slider. mFields[p]->SetValue(fieldText); } }
int getLADSPADefault(const LADSPA_PortRangeHint * psPortRangeHint, const unsigned long lSampleRate, LADSPA_Data * pfResult) { int iHintDescriptor; iHintDescriptor = psPortRangeHint->HintDescriptor & LADSPA_HINT_DEFAULT_MASK; switch (iHintDescriptor & LADSPA_HINT_DEFAULT_MASK) { case LADSPA_HINT_DEFAULT_NONE: return -1; case LADSPA_HINT_DEFAULT_MINIMUM: *pfResult = psPortRangeHint->LowerBound; if (LADSPA_IS_HINT_SAMPLE_RATE(psPortRangeHint->HintDescriptor)) *pfResult *= lSampleRate; return 0; case LADSPA_HINT_DEFAULT_LOW: if (LADSPA_IS_HINT_LOGARITHMIC(iHintDescriptor)) { *pfResult = exp(log(psPortRangeHint->LowerBound) * 0.75 + log(psPortRangeHint->UpperBound) * 0.25); } else { *pfResult = (psPortRangeHint->LowerBound * 0.75 + psPortRangeHint->UpperBound * 0.25); } if (LADSPA_IS_HINT_SAMPLE_RATE(psPortRangeHint->HintDescriptor)) *pfResult *= lSampleRate; return 0; case LADSPA_HINT_DEFAULT_MIDDLE: if (LADSPA_IS_HINT_LOGARITHMIC(iHintDescriptor)) { *pfResult = sqrt(psPortRangeHint->LowerBound * psPortRangeHint->UpperBound); } else { *pfResult = 0.5 * (psPortRangeHint->LowerBound + psPortRangeHint->UpperBound); } if (LADSPA_IS_HINT_SAMPLE_RATE(psPortRangeHint->HintDescriptor)) *pfResult *= lSampleRate; return 0; case LADSPA_HINT_DEFAULT_HIGH: if (LADSPA_IS_HINT_LOGARITHMIC(iHintDescriptor)) { *pfResult = exp(log(psPortRangeHint->LowerBound) * 0.25 + log(psPortRangeHint->UpperBound) * 0.75); } else { *pfResult = (psPortRangeHint->LowerBound * 0.25 + psPortRangeHint->UpperBound * 0.75); } if (LADSPA_IS_HINT_SAMPLE_RATE(psPortRangeHint->HintDescriptor)) *pfResult *= lSampleRate; return 0; case LADSPA_HINT_DEFAULT_MAXIMUM: *pfResult = psPortRangeHint->UpperBound; if (LADSPA_IS_HINT_SAMPLE_RATE(psPortRangeHint->HintDescriptor)) *pfResult *= lSampleRate; return 0; case LADSPA_HINT_DEFAULT_0: *pfResult = 0; return 0; case LADSPA_HINT_DEFAULT_1: *pfResult = 1; return 0; case LADSPA_HINT_DEFAULT_100: *pfResult = 100; return 0; case LADSPA_HINT_DEFAULT_440: *pfResult = 440; return 0; } /* We don't recognise this default flag. It's probably from a more recent version of LADSPA. */ return -1; }
int pa__init(pa_module*m) { struct userdata *u; pa_sample_spec ss; pa_channel_map map; pa_modargs *ma; char *t; pa_sink *master; pa_sink_input_new_data sink_input_data; pa_sink_new_data sink_data; const char *plugin, *label; LADSPA_Descriptor_Function descriptor_func; const char *e, *cdata; const LADSPA_Descriptor *d; unsigned long input_port, output_port, p, j, n_control; unsigned c; pa_bool_t *use_default = NULL; pa_assert(m); pa_assert_cc(sizeof(LADSPA_Data) == sizeof(float)); if (!(ma = pa_modargs_new(m->argument, valid_modargs))) { pa_log("Failed to parse module arguments."); goto fail; } if (!(master = pa_namereg_get(m->core, pa_modargs_get_value(ma, "master", NULL), PA_NAMEREG_SINK))) { pa_log("Master sink not found"); goto fail; } ss = master->sample_spec; ss.format = PA_SAMPLE_FLOAT32; map = master->channel_map; if (pa_modargs_get_sample_spec_and_channel_map(ma, &ss, &map, PA_CHANNEL_MAP_DEFAULT) < 0) { pa_log("Invalid sample format specification or channel map"); goto fail; } if (!(plugin = pa_modargs_get_value(ma, "plugin", NULL))) { pa_log("Missing LADSPA plugin name"); goto fail; } if (!(label = pa_modargs_get_value(ma, "label", NULL))) { pa_log("Missing LADSPA plugin label"); goto fail; } cdata = pa_modargs_get_value(ma, "control", NULL); u = pa_xnew0(struct userdata, 1); u->module = m; m->userdata = u; u->memblockq = pa_memblockq_new(0, MEMBLOCKQ_MAXLENGTH, 0, pa_frame_size(&ss), 1, 1, 0, NULL); if (!(e = getenv("LADSPA_PATH"))) e = LADSPA_PATH; /* FIXME: This is not exactly thread safe */ t = pa_xstrdup(lt_dlgetsearchpath()); lt_dlsetsearchpath(e); m->dl = lt_dlopenext(plugin); lt_dlsetsearchpath(t); pa_xfree(t); if (!m->dl) { pa_log("Failed to load LADSPA plugin: %s", lt_dlerror()); goto fail; } if (!(descriptor_func = (LADSPA_Descriptor_Function) pa_load_sym(m->dl, NULL, "ladspa_descriptor"))) { pa_log("LADSPA module lacks ladspa_descriptor() symbol."); goto fail; } for (j = 0;; j++) { if (!(d = descriptor_func(j))) { pa_log("Failed to find plugin label '%s' in plugin '%s'.", label, plugin); goto fail; } if (strcmp(d->Label, label) == 0) break; } u->descriptor = d; pa_log_debug("Module: %s", plugin); pa_log_debug("Label: %s", d->Label); pa_log_debug("Unique ID: %lu", d->UniqueID); pa_log_debug("Name: %s", d->Name); pa_log_debug("Maker: %s", d->Maker); pa_log_debug("Copyright: %s", d->Copyright); input_port = output_port = (unsigned long) -1; n_control = 0; for (p = 0; p < d->PortCount; p++) { if (LADSPA_IS_PORT_INPUT(d->PortDescriptors[p]) && LADSPA_IS_PORT_AUDIO(d->PortDescriptors[p])) { if (strcmp(d->PortNames[p], "Input") == 0) { pa_assert(input_port == (unsigned long) -1); input_port = p; } else { pa_log("Found audio input port on plugin we cannot handle: %s", d->PortNames[p]); goto fail; } } else if (LADSPA_IS_PORT_OUTPUT(d->PortDescriptors[p]) && LADSPA_IS_PORT_AUDIO(d->PortDescriptors[p])) { if (strcmp(d->PortNames[p], "Output") == 0) { pa_assert(output_port == (unsigned long) -1); output_port = p; } else { pa_log("Found audio output port on plugin we cannot handle: %s", d->PortNames[p]); goto fail; } } else if (LADSPA_IS_PORT_INPUT(d->PortDescriptors[p]) && LADSPA_IS_PORT_CONTROL(d->PortDescriptors[p])) n_control++; else { pa_assert(LADSPA_IS_PORT_OUTPUT(d->PortDescriptors[p]) && LADSPA_IS_PORT_CONTROL(d->PortDescriptors[p])); pa_log_debug("Ignored control output port \"%s\".", d->PortNames[p]); } } if ((input_port == (unsigned long) -1) || (output_port == (unsigned long) -1)) { pa_log("Failed to identify input and output ports. " "Right now this module can only deal with plugins which provide an 'Input' and an 'Output' audio port. " "Patches welcome!"); goto fail; } u->block_size = pa_frame_align(pa_mempool_block_size_max(m->core->mempool), &ss); u->input = (LADSPA_Data*) pa_xnew(uint8_t, (unsigned) u->block_size); if (LADSPA_IS_INPLACE_BROKEN(d->Properties)) u->output = (LADSPA_Data*) pa_xnew(uint8_t, (unsigned) u->block_size); else u->output = u->input; u->channels = ss.channels; for (c = 0; c < ss.channels; c++) { if (!(u->handle[c] = d->instantiate(d, ss.rate))) { pa_log("Failed to instantiate plugin %s with label %s for channel %i", plugin, d->Label, c); goto fail; } d->connect_port(u->handle[c], input_port, u->input); d->connect_port(u->handle[c], output_port, u->output); } if (!cdata && n_control > 0) { pa_log("This plugin requires specification of %lu control parameters.", n_control); goto fail; } if (n_control > 0) { const char *state = NULL; char *k; unsigned long h; u->control = pa_xnew(LADSPA_Data, (unsigned) n_control); use_default = pa_xnew(pa_bool_t, (unsigned) n_control); p = 0; while ((k = pa_split(cdata, ",", &state)) && p < n_control) { double f; if (*k == 0) { use_default[p++] = TRUE; pa_xfree(k); continue; } if (pa_atod(k, &f) < 0) { pa_log("Failed to parse control value '%s'", k); pa_xfree(k); goto fail; } pa_xfree(k); use_default[p] = FALSE; u->control[p++] = (LADSPA_Data) f; } /* The previous loop doesn't take the last control value into account if it is left empty, so we do it here. */ if (*cdata == 0 || cdata[strlen(cdata) - 1] == ',') { if (p < n_control) use_default[p] = TRUE; p++; } if (p > n_control || k) { pa_log("Too many control values passed, %lu expected.", n_control); pa_xfree(k); goto fail; } if (p < n_control) { pa_log("Not enough control values passed, %lu expected, %lu passed.", n_control, p); goto fail; } h = 0; for (p = 0; p < d->PortCount; p++) { LADSPA_PortRangeHintDescriptor hint = d->PortRangeHints[p].HintDescriptor; if (!LADSPA_IS_PORT_CONTROL(d->PortDescriptors[p])) continue; if (LADSPA_IS_PORT_OUTPUT(d->PortDescriptors[p])) { for (c = 0; c < ss.channels; c++) d->connect_port(u->handle[c], p, &u->control_out); continue; } pa_assert(h < n_control); if (use_default[h]) { LADSPA_Data lower, upper; if (!LADSPA_IS_HINT_HAS_DEFAULT(hint)) { pa_log("Control port value left empty but plugin defines no default."); goto fail; } lower = d->PortRangeHints[p].LowerBound; upper = d->PortRangeHints[p].UpperBound; if (LADSPA_IS_HINT_SAMPLE_RATE(hint)) { lower *= (LADSPA_Data) ss.rate; upper *= (LADSPA_Data) ss.rate; } switch (hint & LADSPA_HINT_DEFAULT_MASK) { case LADSPA_HINT_DEFAULT_MINIMUM: u->control[h] = lower; break; case LADSPA_HINT_DEFAULT_MAXIMUM: u->control[h] = upper; break; case LADSPA_HINT_DEFAULT_LOW: if (LADSPA_IS_HINT_LOGARITHMIC(hint)) u->control[h] = (LADSPA_Data) exp(log(lower) * 0.75 + log(upper) * 0.25); else u->control[h] = (LADSPA_Data) (lower * 0.75 + upper * 0.25); break; case LADSPA_HINT_DEFAULT_MIDDLE: if (LADSPA_IS_HINT_LOGARITHMIC(hint)) u->control[h] = (LADSPA_Data) exp(log(lower) * 0.5 + log(upper) * 0.5); else u->control[h] = (LADSPA_Data) (lower * 0.5 + upper * 0.5); break; case LADSPA_HINT_DEFAULT_HIGH: if (LADSPA_IS_HINT_LOGARITHMIC(hint)) u->control[h] = (LADSPA_Data) exp(log(lower) * 0.25 + log(upper) * 0.75); else u->control[h] = (LADSPA_Data) (lower * 0.25 + upper * 0.75); break; case LADSPA_HINT_DEFAULT_0: u->control[h] = 0; break; case LADSPA_HINT_DEFAULT_1: u->control[h] = 1; break; case LADSPA_HINT_DEFAULT_100: u->control[h] = 100; break; case LADSPA_HINT_DEFAULT_440: u->control[h] = 440; break; default: pa_assert_not_reached(); } } if (LADSPA_IS_HINT_INTEGER(hint)) u->control[h] = roundf(u->control[h]); pa_log_debug("Binding %f to port %s", u->control[h], d->PortNames[p]); for (c = 0; c < ss.channels; c++) d->connect_port(u->handle[c], p, &u->control[h]); h++; } pa_assert(h == n_control); } if (d->activate) for (c = 0; c < u->channels; c++) d->activate(u->handle[c]); /* Create sink */ pa_sink_new_data_init(&sink_data); sink_data.driver = __FILE__; sink_data.module = m; if (!(sink_data.name = pa_xstrdup(pa_modargs_get_value(ma, "sink_name", NULL)))) sink_data.name = pa_sprintf_malloc("%s.ladspa", master->name); pa_sink_new_data_set_sample_spec(&sink_data, &ss); pa_sink_new_data_set_channel_map(&sink_data, &map); pa_proplist_sets(sink_data.proplist, PA_PROP_DEVICE_MASTER_DEVICE, master->name); pa_proplist_sets(sink_data.proplist, PA_PROP_DEVICE_CLASS, "filter"); pa_proplist_sets(sink_data.proplist, "device.ladspa.module", plugin); pa_proplist_sets(sink_data.proplist, "device.ladspa.label", d->Label); pa_proplist_sets(sink_data.proplist, "device.ladspa.name", d->Name); pa_proplist_sets(sink_data.proplist, "device.ladspa.maker", d->Maker); pa_proplist_sets(sink_data.proplist, "device.ladspa.copyright", d->Copyright); pa_proplist_setf(sink_data.proplist, "device.ladspa.unique_id", "%lu", (unsigned long) d->UniqueID); if (pa_modargs_get_proplist(ma, "sink_properties", sink_data.proplist, PA_UPDATE_REPLACE) < 0) { pa_log("Invalid properties"); pa_sink_new_data_done(&sink_data); goto fail; } if ((u->auto_desc = !pa_proplist_contains(sink_data.proplist, PA_PROP_DEVICE_DESCRIPTION))) { const char *z; z = pa_proplist_gets(master->proplist, PA_PROP_DEVICE_DESCRIPTION); pa_proplist_setf(sink_data.proplist, PA_PROP_DEVICE_DESCRIPTION, "LADSPA Plugin %s on %s", d->Name, z ? z : master->name); } u->sink = pa_sink_new(m->core, &sink_data, PA_SINK_HW_MUTE_CTRL|PA_SINK_HW_VOLUME_CTRL|PA_SINK_DECIBEL_VOLUME| (master->flags & (PA_SINK_LATENCY|PA_SINK_DYNAMIC_LATENCY))); pa_sink_new_data_done(&sink_data); if (!u->sink) { pa_log("Failed to create sink."); goto fail; } u->sink->parent.process_msg = sink_process_msg_cb; u->sink->set_state = sink_set_state_cb; u->sink->update_requested_latency = sink_update_requested_latency_cb; u->sink->request_rewind = sink_request_rewind_cb; u->sink->set_volume = sink_set_volume_cb; u->sink->set_mute = sink_set_mute_cb; u->sink->userdata = u; pa_sink_set_asyncmsgq(u->sink, master->asyncmsgq); /* Create sink input */ pa_sink_input_new_data_init(&sink_input_data); sink_input_data.driver = __FILE__; sink_input_data.module = m; sink_input_data.sink = master; pa_proplist_sets(sink_input_data.proplist, PA_PROP_MEDIA_NAME, "LADSPA Stream"); pa_proplist_sets(sink_input_data.proplist, PA_PROP_MEDIA_ROLE, "filter"); pa_sink_input_new_data_set_sample_spec(&sink_input_data, &ss); pa_sink_input_new_data_set_channel_map(&sink_input_data, &map); pa_sink_input_new(&u->sink_input, m->core, &sink_input_data); pa_sink_input_new_data_done(&sink_input_data); if (!u->sink_input) goto fail; u->sink_input->pop = sink_input_pop_cb; u->sink_input->process_rewind = sink_input_process_rewind_cb; u->sink_input->update_max_rewind = sink_input_update_max_rewind_cb; u->sink_input->update_max_request = sink_input_update_max_request_cb; u->sink_input->update_sink_latency_range = sink_input_update_sink_latency_range_cb; u->sink_input->update_sink_fixed_latency = sink_input_update_sink_fixed_latency_cb; u->sink_input->kill = sink_input_kill_cb; u->sink_input->attach = sink_input_attach_cb; u->sink_input->detach = sink_input_detach_cb; u->sink_input->state_change = sink_input_state_change_cb; u->sink_input->may_move_to = sink_input_may_move_to_cb; u->sink_input->moving = sink_input_moving_cb; u->sink_input->volume_changed = sink_input_volume_changed_cb; u->sink_input->mute_changed = sink_input_mute_changed_cb; u->sink_input->userdata = u; pa_sink_put(u->sink); pa_sink_input_put(u->sink_input); pa_modargs_free(ma); pa_xfree(use_default); return 0; fail: if (ma) pa_modargs_free(ma); pa_xfree(use_default); pa__done(m); return -1; }
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; }
//============================================================================== 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; } } }
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; }
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; }
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; }
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; }