# Map juce::Sliders to a midi controller knob?

**URL:** <https://forum.juce.com/t/map-juce-sliders-to-a-midi-controller-knob/45356>\
**Category:** Audio Plugins\
**Created:** [April 5, 2021, 7:38am UTC](https://forum.juce.com/t/map-juce-sliders-to-a-midi-controller-knob/45356 "2021-04-05T07:38:26Z")\
**Posts on this page:** 18\
**Page:** 1

<div class="post-metadata">

**Author:** ![PhilJungschlaeger](https://sea2.discourse-cdn.com/flex026/user_avatar/forum.juce.com/philjungschlaeger/32/8513_2.png) [@PhilJungschlaeger](https://forum.juce.com/u/PhilJungschlaeger)\
**Post date:** [April 5, 2021, 7:38am UTC](https://forum.juce.com/t/map-juce-sliders-to-a-midi-controller-knob/45356/1 "2021-04-05T07:38:26Z")

</div>

I am looking for a convenient way to let the user midi map sliders and buttons of my plugin to an external midi controller. It should be similar to the midi mapping functionality in Abelton.

I just found [this juce tutoial](https://docs.juce.com/master/tutorial_handling_midi_events.html)… but it seems cumbersome, to manually connect everything. So is there a better way to go?

---

<div class="post-metadata">

**Author:** ![benvining](https://sea2.discourse-cdn.com/flex026/user_avatar/forum.juce.com/benvining/32/9922_2.png) [@benvining](https://forum.juce.com/u/benvining)\
**Post date:** [April 9, 2021, 7:10pm UTC](https://forum.juce.com/t/map-juce-sliders-to-a-midi-controller-knob/45356/2 "2021-04-09T19:10:34Z")

</div>

> [@PhilJungschlaeger](#):
>
> It should be similar to the midi mapping functionality in Abelton

this _is_ how most Juce plugins would handle this.

Basically, you don’t _directly_ handle midi mapping in your plugin. You create a parameter visible to the host that the host can automate, and then the user can use the _host’s_ automation features to control your plugin’s parameters.

So, for example, if you create a juce::Slider and connect it to a juce::RangedAudioParameter, then in Ableton you will be able to use the normal system of Midi map → click on a parameter → move a midi controller. Then when you move your midi controller, the host will be controlling your plugin’s RanngedAudioParameter, which will make your juce::Slider move.

---

<div class="post-metadata">

**Author:** ![HowardAntares](https://sea2.discourse-cdn.com/flex026/user_avatar/forum.juce.com/howardantares/32/4629_2.png) [@HowardAntares](https://forum.juce.com/u/HowardAntares)\
**Post date:** [April 9, 2021, 7:43pm UTC](https://forum.juce.com/t/map-juce-sliders-to-a-midi-controller-knob/45356/3 "2021-04-09T19:43:44Z")

</div>

Our older software captures MIDI CC messages, and allows mapping those messages to specific parameters. But these days, the approach mentioned above (using the DAW’s automation features to handle MIDI control of parameters) is probably the way to go.

---

<div class="post-metadata">

**Author:** ![PhilJungschlaeger](https://sea2.discourse-cdn.com/flex026/user_avatar/forum.juce.com/philjungschlaeger/32/8513_2.png) [@PhilJungschlaeger](https://forum.juce.com/u/PhilJungschlaeger)\
**Post date:** [April 10, 2021, 10:21am UTC](https://forum.juce.com/t/map-juce-sliders-to-a-midi-controller-knob/45356/4 "2021-04-10T10:21:17Z")

</div>

Okay, thank you.  
However in my plugin, I have variuos combinations of properties which are dependend on the plugin state. Therefore I am adding and deleting properties/juce::values to a simple ValueTree. I need a way to also midi controlle them.

Alternatively, I could prepare all possible combinations as parameters in a AudioProcessorValueTreeState as you propose, but it would be 20.000 combinations… Or is there actually a way, to add and delete parameters in the AudioProcessorValueTreeState? That would be extremly awesome!

---

<div class="post-metadata">

**Author:** ![zac](https://avatars.discourse-cdn.com/v4/letter/z/87869e/32.png) [@zac](https://forum.juce.com/u/zac)\
**Post date:** [April 10, 2021, 8:44pm UTC](https://forum.juce.com/t/map-juce-sliders-to-a-midi-controller-knob/45356/5 "2021-04-10T20:44:15Z")

</div>

For what it’s worth, if you’re going to make a standalone version of your plugin, you might want to offer midi mapping within it. In this case you’ll have to set up a way of handling this yourself. The same is true if you want to use MIDI to modify things which aren’t easily represented by parameters.

I’d suggest making some sort of abstraction which connects a Value to a MIDI CC. We did this with an RAII mechanism which looks quite a bit like the JUCE attachment classes, but pairs with an object owned by the processor which takes the midi input, looks for CC messages, and modifies the value.

---

<div class="post-metadata">

**Author:** ![benvining](https://sea2.discourse-cdn.com/flex026/user_avatar/forum.juce.com/benvining/32/9922_2.png) [@benvining](https://forum.juce.com/u/benvining)\
**Post date:** [April 10, 2021, 8:46pm UTC](https://forum.juce.com/t/map-juce-sliders-to-a-midi-controller-knob/45356/6 "2021-04-10T20:46:01Z")

</div>

That’s a great point. Is custom MIDI CC mapping also a good idea for mobile versions, or is it less applicable there?

---

<div class="post-metadata">

**Author:** ![benvining](https://sea2.discourse-cdn.com/flex026/user_avatar/forum.juce.com/benvining/32/9922_2.png) [@benvining](https://forum.juce.com/u/benvining)\
**Post date:** [April 10, 2021, 9:18pm UTC](https://forum.juce.com/t/map-juce-sliders-to-a-midi-controller-knob/45356/7 "2021-04-10T21:18:16Z")

</div>

Here’s a quick little Midi CC mapper class I drafted since I was thinking about it. Would something like this work?

> <https://github.com/benthevining/Shared-code/blob/main/bv_SharedCode/misc/MidiMapping.h>

---

<div class="post-metadata">

**Author:** ![zac](https://avatars.discourse-cdn.com/v4/letter/z/87869e/32.png) [@zac](https://forum.juce.com/u/zac)\
**Post date:** [April 10, 2021, 9:26pm UTC](https://forum.juce.com/t/map-juce-sliders-to-a-midi-controller-knob/45356/8 "2021-04-10T21:26:10Z")

</div>

Looks good at first glance. One of the things we did however was to make connections to a Value instead of a Parameter, primarily because there were a few things in our upcoming product which needed to work with a controller, but weren’t really meaningful in automation (or for which saved/loaded automation data didn’t make sense). This worked for us because a good chunk of our backend uses Value, although obviously this doesn’t make sense for something that can’t be controlled by one.

Nonetheless, that should work for making a standalone of a plugin with parameters MIDI mappable, as long as there’s some user facing way to change which controller maps to which parameter ( 😢)

---

<div class="post-metadata">

**Author:** ![benvining](https://sea2.discourse-cdn.com/flex026/user_avatar/forum.juce.com/benvining/32/9922_2.png) [@benvining](https://forum.juce.com/u/benvining)\
**Post date:** [April 10, 2021, 9:27pm UTC](https://forum.juce.com/t/map-juce-sliders-to-a-midi-controller-knob/45356/9 "2021-04-10T21:27:34Z")

</div>

awesome, thanks for your input!

> [@zac](#):
>
> some user facing way to change which controller maps

ugh, yeah… that’s the less fun part about adding this feature haha.

But it does seem worth it, so I’ll figure something out…

---

<div class="post-metadata">

**Author:** ![daniel](https://sea2.discourse-cdn.com/flex026/user_avatar/forum.juce.com/daniel/32/790_2.png) [@daniel](https://forum.juce.com/u/daniel)\
**Post date:** [April 10, 2021, 10:01pm UTC](https://forum.juce.com/t/map-juce-sliders-to-a-midi-controller-knob/45356/10 "2021-04-10T22:01:34Z")

</div>

My PluginGuiMagic has that functionality built in. A little box that shows the last nudged CC and that you can drag onto any knob to control its parameter.  
Thanks for the idea to control non parameter values as well, I will add that to my list…

 ![Screenshot 2021-04-10 at 23.59.50](https://us1.discourse-cdn.com/flex026/uploads/juce/original/2X/f/fa52d56a17519a7359b34a451bfb61dcc9e5b997.png)

> <https://github.com/ffAudio/foleys_gui_magic/blob/master/State/foleys_MidiParameterMapper.cpp#L57>

---

<div class="post-metadata">

**Author:** ![refusesoftware](https://sea2.discourse-cdn.com/flex026/user_avatar/forum.juce.com/refusesoftware/32/20561_2.png) [@refusesoftware](https://forum.juce.com/u/refusesoftware)\
**Post date:** [April 11, 2021, 8:14am UTC](https://forum.juce.com/t/map-juce-sliders-to-a-midi-controller-knob/45356/11 "2021-04-11T08:14:28Z")

</div>

> [@zac](#):
>
> One of the things we did however was to make connections to a Value instead of a Parameter…

A Value that’s part of a ValueTree, or one that’s a member by itself?

In any case, Value is not thread-safe, so there are potential pitfalls there, depending on how it’s used. (And I think in standalone apps, MIDI inputs are on their own threads?)

---

<div class="post-metadata">

**Author:** ![daniel](https://sea2.discourse-cdn.com/flex026/user_avatar/forum.juce.com/daniel/32/790_2.png) [@daniel](https://forum.juce.com/u/daniel)\
**Post date:** [April 11, 2021, 11:47am UTC](https://forum.juce.com/t/map-juce-sliders-to-a-midi-controller-knob/45356/12 "2021-04-11T11:47:00Z")

</div>

Good shout. Not only where you use the value but where it is set from is important to consider…

> [@refusesoftware](#):
>
> (And I think in standalone apps, MIDI inputs are on their own threads?)

potentially. In the plugin standalone target it is the audio thread, because it is handled in processBlock(). Impossible to say for all other standalone apps

---

<div class="post-metadata">

**Author:** ![refusesoftware](https://sea2.discourse-cdn.com/flex026/user_avatar/forum.juce.com/refusesoftware/32/20561_2.png) [@refusesoftware](https://forum.juce.com/u/refusesoftware)\
**Post date:** [April 11, 2021, 4:52pm UTC](https://forum.juce.com/t/map-juce-sliders-to-a-midi-controller-knob/45356/13 "2021-04-11T16:52:10Z")

</div>

> [@daniel](#):
>
> In the plugin standalone target it is the audio thread, because it is handled in processBlock(). Impossible to say for all other standalone apps

Right you are. I was thinking of non-plugin standalones, where you would use the `MidiInputCallback` class for MIDI. In that case, MIDI comes in on “a high-priority system thread”… I just couldn’t remember if each MIDI device is given its own thread, or if input for all devices comes in on a single thread.

---

<div class="post-metadata">

**Author:** ![zac](https://avatars.discourse-cdn.com/v4/letter/z/87869e/32.png) [@zac](https://forum.juce.com/u/zac)\
**Post date:** [April 11, 2021, 10:06pm UTC](https://forum.juce.com/t/map-juce-sliders-to-a-midi-controller-knob/45356/14 "2021-04-11T22:06:10Z")

</div>

Yes, good point. We realized this as well and call the actual set methods on the message thread regardless of where the callback comes from.

---

<div class="post-metadata">

**Author:** ![refusesoftware](https://sea2.discourse-cdn.com/flex026/user_avatar/forum.juce.com/refusesoftware/32/20561_2.png) [@refusesoftware](https://forum.juce.com/u/refusesoftware)\
**Post date:** [April 12, 2021, 1:32am UTC](https://forum.juce.com/t/map-juce-sliders-to-a-midi-controller-knob/45356/15 "2021-04-12T01:32:13Z")

</div>

OK, and how do you access those values from the audio thread? Is there an atomic acting as an intermediate value holder?

---

<div class="post-metadata">

**Author:** ![zac](https://avatars.discourse-cdn.com/v4/letter/z/87869e/32.png) [@zac](https://forum.juce.com/u/zac)\
**Post date:** [April 12, 2021, 1:53am UTC](https://forum.juce.com/t/map-juce-sliders-to-a-midi-controller-knob/45356/16 "2021-04-12T01:53:32Z")

</div>

They never are accessed on the audio thread. Our processor does calculations which rely on those values on the message thread whose results are stored in an atomic pointer which points to an array which is used by the audio thread.

---

<div class="post-metadata">

**Author:** ![refusesoftware](https://sea2.discourse-cdn.com/flex026/user_avatar/forum.juce.com/refusesoftware/32/20561_2.png) [@refusesoftware](https://forum.juce.com/u/refusesoftware)\
**Post date:** [April 12, 2021, 4:55am UTC](https://forum.juce.com/t/map-juce-sliders-to-a-midi-controller-knob/45356/17 "2021-04-12T04:55:24Z")

</div>

Ah, I see. Sounds clever! Are you using Value::Listeners to trigger those calculations when new CC data arrives?

---

<div class="post-metadata">

**Author:** ![zac](https://avatars.discourse-cdn.com/v4/letter/z/87869e/32.png) [@zac](https://forum.juce.com/u/zac)\
**Post date:** [April 12, 2021, 5:29am UTC](https://forum.juce.com/t/map-juce-sliders-to-a-midi-controller-knob/45356/18 "2021-04-12T05:29:09Z")

</div>

> [@refusesoftware](#):
>
> Ah, I see. Sounds clever!

Not especially, just what the product calls for.

> [@refusesoftware](#):
>
> Are you using Value::Listeners to trigger those calculations when new CC data arrives?

Yes, but called from an asyncUpdater.
