Chowdhury-DSP / ChowKick

Kick synthesizer based on old-school drum machine circuits
BSD 3-Clause "New" or "Revised" License
156 stars 16 forks source link

Midi CC / external control of synth parameters #17

Open thegroove opened 2 years ago

thegroove commented 2 years ago

Hi,

Great work on this little plugin, it sounds.. kickass, pardon the pun. I like it so much that I'd like to install it on a standalone plugin host type of machine (self-built x86 box). Upon exploring that idea though, I noticed there's no mention of midi CC or any other form of external control anywhere in the docs or source (that I can find, anyway). Is this indeed missing, and is this something that you plan to implement? Alternatively I may try to implement it myself, I have some c/c++ experience, although I am completely new to Juce and the Juce development process, so I may be biting off more than I can chew in the short term.

jatinchowdhury18 commented 2 years ago

Thanks, glad you're liking the plugin! If you're using a DAW, it's possible to map MIDI controls to individual parameters, but for a standalone thing like you mentioned, we'll need to implement some MIDI CC controls. From my perspective, the process would look something like this:

Here's a rough outline of a class that could maybe do this kind of thing (see also JUCE MidiMessage documentation):

class MidiController
{
public:
    MidiController (AudioProcessorValueTreeState& vts)
    {
        map.insert ({ 16, vts.getParameter ("out_level") }); // map output level to MIDI CC 16
        ... // do other parameters
    }

    void processBuffer (MidiBuffer& messages)
    {
        for (const MidiMessageMetadata mm : midi)
        {
            auto message = mm.getMessage();

            for (const auto& [ccID, param] : params)
            {
                if (message.isControllerOfType (ccID)
                {
                    auto paramVal = param->convertFrom0To1 ((float) message.getControllerValue() / 127.0f);
                    param->setValueNotifyingHost (paramVal);
                }
            } 
        }
    }

private:
    std::unordered_map<int, RangedAudioParameter*> params;
};

Anyway, I have no idea if that will work, but might be worth trying.

Do you have references for other plugins that have this sort of thing implemented? I'd be curious to see how they do it, and how it's documented like in the plugin's user manual or something like that.

Thanks, Jatin