surge-synthesizer / conduit

The Surge Synth Team Conduit Plugin Suite
Other
13 stars 4 forks source link

Commented code, function diagram, or refactor needed for plugin value commincation #94

Closed elanhickler closed 6 months ago

elanhickler commented 6 months ago

After having looked through the code there's a lot going on in terms of how values are communicated throughout the plugin.

I am requesting code to be commented or a code diagram in order to accomplish this goal or perhaps consider this a feature request.

  1. Knobs respond linearly with mouse movement
  2. Tooltip readout displays user-friendly string
  3. REAPER's envelope system displays the same user-friendly string
  4. Ability to type in user-friendly units for REAPER's envelope point such a decibel value and translate that to DSP object value such as amplitude
  5. Pass in a curve function to optionally manage knob non-linear sensitivity.

Comments should indicate what kind of value is being received and where it is going and what kind of conversion is needed. Is this a user input string? Is this a value string readout from REAPER? Is this sending/receiving a 0 to 1 value or a min to max value? (it's min to max as I learned). Is this being called because of a user knob movement or an envelope? Is this value coming from the xml patch or going to it? etc.

So far I've managed to get a working communication and agreement between REAPER's envelope system, knob tooltip readout, and the dsp value with these functions

struct ParameterPrototypeDecibels : public ParameterPrototypeBase {
    double patchToDsp(double v) const override { return dbToAmp(v); }
    double dspToPatch(double v) const override { return ampToDb(v); }

    double stringToValue(string_view v) const override { return stringToDouble(v); }
    string valueToString(double v) const override { return std::to_string(v); }

    string displayString(double v) const override { return limitDecimals(valueToString(v), 3, 2, 2) + " dB";}
}

I feel like this should be the limit of this class. It works perfectly and is easy to understand. The only thing missing is the knob scaling. I don't know how to integrate it without causing value communication mismatches. I'm not sure what functions to override, to edit, to handle in my class, etc.

elanhickler commented 6 months ago

nomenclature

list of functions having to do with value communication that could use comments

editor_base.h

void onIdle();
// inherits from Continuous which holds various functions to communicate values about its connected parameter
struct D2QContinuousParam 
{
        // value retrieved gets sent to widgets for painting
        float getValue() const override;
        // what kind of value should be converted to string?
        std::string getValueAsStringFor(float f) const override;
        // linear minmax value position coming from interface interactions such as moving a knob
        // used in ContinuousParamEditor.cpp and DraggableTextEditableValue
        void setValueFromGUI(const float &fi) override;
        // what is a model?
        void setValueFromModel(const float &fi) override;

        // from Continuous base class
        virtual std::string getValueAsStringFor(float) const;
        virtual std::string getValueAsString() const;

         // def/min/max is used by UI widgets, so translation of linear to mapped is needed
        float getDefaultValue() const override;
        float getMin() const override;
        float getMax() const override;
};
// called when a knob needs to display its value and gets its value from ui communications bundle
void updateTooltip(uint32_t, float)
// call setValueFromModel, I don't know anymore about this function
void onIdle()

clap-base-class.h

// has a clause that sets default value which needs to be communicated to the dsp objects
void configureParams(); 
// assigns def/min/max for parameter info (what kind of values should these be? dsp? linear? user?)
bool paramsInfo(clap_id, clap_param_info) const noexcept; 
// object that holds parameter values (what kind of values?)
std::unordered_map<clap_id, float *> paramToValue;
// does this do any value communication?
void paramsFlush(const clap_input_events *, const clap_output_events *) noexcept override;
// transfers patch.params to xml and calls virtual void onStateRestored()
bool stateSave(const clap_ostream *) noexcept override;
// transfers xml patch values to path.params and calls virtual void onStateRestored()
bool stateLoad(const clap_istream *istream) noexcept override;
// object used for paramTo functions
std::unordered_map<clap_id, float *> paramToValue;
// what kind of value is stored here? what functions put values in paramToValue object?
bool paramsValue(clap_id, double *) noexcept override;
// converts incoming value to output display string. Is it solely for display? what kind of value is it converting?
bool paramsValueToText(clap_id, double, char *, uint32_t) noexcept override;
// holds values to communicate and transfer between audio and ui threads
struct UICommunicationBundle
{
        // push to and read from events some of which communicate value changes
        SynthToUI_Queue_t toUiQ;
        UIToSynth_Queue_t fromUiQ;
};
// calls fromUiQ.pop and process events some of which communicate value changes
uint32_t handleEventsFromUIQueue(const clap_output_events_t *);
// also called by handleEventsFromUIQueue() and pops messages from UiQ and calls updateValueFromUI
void refreshUIIfNeeded()
// overwrites a value in patch.params[index] based on clap_id converted to index
// called by handleEventsFromUIQueue() and gets a value from a UiQ event
void doValueUpdate(clap_id, float);
// calls updateParamInPatch() which calls doValueUpdate() and also pushes event to UiQ (for changing the corresponding knob position)?
bool handleParamBaseEvents(const clap_event_header *evt);

plugin.hxx

// how does this communicate with conduit? what kind of value is converting?
line 928: return self.paramsValueToText(param_id, value, display, size);
// how does this communicate with conduit? what kind of value is converting?
line 960: if (!self.paramsTextToValue(param_id, display, value));
elanhickler commented 6 months ago

Proposal for value communication echosystem

image

elanhickler commented 6 months ago

figured it out