// set the value of the parameter to a float, string or signal property. Once // allocated initially the property cannot be resized. void MLPublishedParam::setValueProperty(const MLProperty& paramProp) { MLProperty::Type type = paramProp.getType(); switch(type) { case MLProperty::kFloatProperty: { const float val = paramProp.getFloatValue(); float clampedVal = clamp(val, mRangeLo, mRangeHi); if (fabs(clampedVal) <= mZeroThreshold) { clampedVal = 0.f; } mParamValue.setValue(clampedVal); break; } case MLProperty::kStringProperty: { mParamValue.setValue(paramProp.getStringValue()); break; } case MLProperty::kSignalProperty: { mParamValue.setValue(paramProp.getSignalValue()); break; } default: break; } }
void MLPluginProcessor::doPropertyChangeAction(MLSymbol propName, const MLProperty& newVal) { int propertyType = newVal.getType(); int paramIdx = getParameterIndex(propName); if (paramIdx < 0) return; float f = newVal.getFloatValue(); switch(propertyType) { case MLProperty::kFloatProperty: { // update DSP engine parameters MLPublishedParamPtr p = mEngine.getParamPtr(paramIdx); if(p) { // set published float parameter in DSP engine. setParameterWithoutProperty (propName, f); // convert to host units for VST f = newVal.getFloatValue(); if (wrapperType == AudioProcessor::wrapperType_VST) { f = p->getValueAsLinearProportion(); } // either enqueue change, or send change immediately to host wrapper if(p->getNeedsQueue()) { p->pushValue(f); } else { AudioProcessor::sendParamChangeMessageToListeners (paramIdx, f); } } } break; case MLProperty::kStringProperty: { // set published string parameter in DSP engine. const std::string& sigVal = newVal.getStringValue(); setStringParameterWithoutProperty (propName, sigVal); } break; case MLProperty::kSignalProperty: { // set published signal parameter in DSP engine. const MLSignal& sigVal = newVal.getSignalValue(); setSignalParameterWithoutProperty (propName, sigVal); } break; default: break; } }
// note: order of properties is important! delays property will set // the number of delays and clear other peoperties. void FDN::setProperty(Symbol name, MLProperty value) { MLSignal sigVal = value.getSignalValue(); int currentSize = mDelays.size(); int newSize = sigVal.getWidth(); if(name == "delays") { // setting number of delays outside of bounds will turn object into a passthru if(!within(newSize, 3, 17)) { // TODO report error newSize = 0; } // resize if needed. if(newSize != currentSize) { mDelays.resize(newSize); mFilters.resize(newSize); mDelayInputVectors.resize(newSize); mFeedbackGains.setDims(newSize); } // set default feedbacks. for(int n=0; n<newSize; ++n) { mFeedbackGains[n] = 1.f; } // set delay times. for(int n=0; n<newSize; ++n) { // we have one DSPVector feedback latency, so delay times can't be smaller than that int len = sigVal[n] - kFloatsPerDSPVector; len = max(1, len); mDelays[n].setDelayInSamples(len); } clear(); } else if(name == "cutoffs") { // compute coefficients from cutoffs int newValues = min(currentSize, newSize); for(int n=0; n<newValues; ++n) { mFilters[n].setCoeffs(biquadCoeffs::onePole(sigVal[n])); } } else if(name == "gains") { mFeedbackGains.copy(sigVal); } }
MLProperty::MLProperty(const MLProperty& other) : mType(other.getType()) { switch(mType) { case MLProperty::kFloatProperty: mVal.mFloatVal = other.getFloatValue(); break; case MLProperty::kStringProperty: mVal.mpStringVal = new std::string(other.getStringValue()); break; case MLProperty::kSignalProperty: mVal.mpSignalVal = new MLSignal(other.getSignalValue()); break; default: mVal.mpStringVal = 0; break; } }
bool MLProperty::operator== (const MLProperty& b) const { bool r = false; if(mType == b.getType()) { switch(mType) { case kUndefinedProperty: r = true; break; case kFloatProperty: r = (getFloatValue() == b.getFloatValue()); break; case kStringProperty: r = (getStringValue() == b.getStringValue()); break; case kSignalProperty: r = (getSignalValue() == b.getSignalValue()); break; } } return r; }
void SoundplaneModel::doPropertyChangeAction(MLSymbol p, const MLProperty & newVal) { // debug() << "SoundplaneModel::doPropertyChangeAction: " << p << " -> " << newVal << "\n"; int propertyType = newVal.getType(); switch(propertyType) { case MLProperty::kFloatProperty: { float v = newVal.getFloatValue(); if (p.withoutFinalNumber() == MLSymbol("carrier_toggle")) { // toggles changed -- mute carriers unsigned long mask = 0; for(int i=0; i<32; ++i) { MLSymbol tSym = MLSymbol("carrier_toggle").withFinalNumber(i); bool on = (int)(getFloatProperty(tSym)); mask = mask | (on << i); } mCarriersMask = mask; mCarrierMaskDirty = true; // trigger carriers set in a second or so } else if (p == "all_toggle") { bool on = (bool)(v); for(int i=0; i<32; ++i) { MLSymbol tSym = MLSymbol("carrier_toggle").withFinalNumber(i); setProperty(tSym, on); } mCarriersMask = on ? ~0 : 0; mCarrierMaskDirty = true; // trigger carriers set in a second or so } else if (p == "max_touches") { mTracker.setMaxTouches(v); mMIDIOutput.setMaxTouches(v); mOSCOutput.setMaxTouches(v); } else if (p == "lopass") { mTracker.setLopass(v); } else if (p == "z_thresh") { mTracker.setThresh(v); } else if (p == "z_max") { mTracker.setMaxForce(v); } else if (p == "z_curve") { mTracker.setForceCurve(v); } else if (p == "snap") { sendParametersToZones(); } else if (p == "vibrato") { sendParametersToZones(); } else if (p == "lock") { sendParametersToZones(); } else if (p == "data_freq_midi") { // TODO attribute mMIDIOutput.setDataFreq(v); } else if (p == "data_freq_osc") { // TODO attribute mOSCOutput.setDataFreq(v); } else if (p == "midi_active") { mMIDIOutput.setActive(bool(v)); } else if (p == "midi_multi_chan") { mMIDIOutput.setMultiChannel(bool(v)); } else if (p == "midi_start_chan") { mMIDIOutput.setStartChannel(int(v)); } else if (p == "midi_pressure_active") { mMIDIOutput.setPressureActive(bool(v)); } else if (p == "osc_active") { bool b = v; mOSCOutput.setActive(b); listenToOSC(b ? kDefaultUDPReceivePort : 0); } else if (p == "osc_send_matrix") { bool b = v; mSendMatrixData = b; } else if (p == "t_thresh") { mTracker.setTemplateThresh(v); } else if (p == "bg_filter") { mTracker.setBackgroundFilter(v); } else if (p == "quantize") { bool b = v; mTracker.setQuantize(b); sendParametersToZones(); } else if (p == "rotate") { bool b = v; mTracker.setRotate(b); } else if (p == "retrig") { mMIDIOutput.setRetrig(bool(v)); sendParametersToZones(); } else if (p == "hysteresis") { mMIDIOutput.setHysteresis(v); sendParametersToZones(); } else if (p == "transpose") { sendParametersToZones(); } else if (p == "bend_range") { mMIDIOutput.setBendRange(v); sendParametersToZones(); } else if (p == "debug_pause") { debug().setActive(!bool(v)); } else if (p == "kyma_poll") { mMIDIOutput.setKymaPoll(bool(v)); } } break; case MLProperty::kStringProperty: { const std::string& str = newVal.getStringValue(); if (p == "viewmode") { // nothing to do for Model } else if (p == "midi_device") { mMIDIOutput.setDevice(str); } else if (p == "zone_JSON") { loadZonesFromString(str); } } break; case MLProperty::kSignalProperty: { const MLSignal& sig = newVal.getSignalValue(); if(p == MLSymbol("carriers")) { // get carriers from signal assert(sig.getSize() == kSoundplaneSensorWidth); for(int i=0; i<kSoundplaneSensorWidth; ++i) { mCarriers[i] = sig[i]; } mNeedsCarriersSet = true; } if(p == MLSymbol("tracker_calibration")) { mTracker.setCalibration(sig); } if(p == MLSymbol("tracker_normalize")) { mTracker.setNormalizeMap(sig); } } break; default: break; } }