This isn’t specific to grain clouds and perhaps it may be time to update the title of the post 
Modulation Matrix
This is a bit of dive into building a modulation matrix. I wanted something that provided some quick switching between modulation states or playability that we find with a modulation matrix made famous by, though not exclusive to, EMS. There isn’t anything particularly difficult about this in Kyma so much of this post may be fairly 101 so to compensate, I provided a starting kym for the capytalk version a custom granular engine discussed above. 
Background
Before we get to the matrix implementation let’s quickly review some different approaches to mixing of sources. Here are those that we’ll cover:
- Sum Mix
- Wrap Mix
- Fold Mix
- Self-normalizing Mix
- Product Mix
These are likely fairly well understood by most but I want to highlight them again as a way to encourage people to look beyond summing mixers as I know we all tend to default to those for that vast majority of our use cases but when it comes to modulate wrapping mixers offer a lot and in some contexts normalizing mixers are very handy.
Sum Mixer (with Clip)
This is likely the most common approach. Input two or more signals are added together and if the sum is greater than -1 to 1, the signal clips. The straightforward nature of this makes it easy to understand what is happening though the likelihood of clipping increases with the number of sources. Thankfully, Kyma mixers include a global input gain that will scale all inputs down so you can easily normalize the mix without having to individually adjust each individual level.
Wrap Mix
The AddWrap and GainWrap prototype takes the sum of the input and if the value exceeds the -1 to 1 range, the signal wraps back around the other side. 1.5 becomes -0.5 for example. This is designed specially for index sounds where you want to mix a number of signals but can also be used for modulating signals. One example would be a sample start where you want to wrap back around to earlier in the file instead of saturate at the end point. Another example would be panning.
Fold Mix
Similar to AddWrap except that when the signal hits the boundary, it reflects back. This is also known as a wavefolder. Example: 1.25 becomes 0.75. The signal continues to reflect if the range exceeds -2 to 2. Due to the method of implementation, there is a practical limit to the number of reflections at least in the implementation I posted on the community library for download. If you need more than 255 folds, you may want to consider another approach.
The Fold/Flip/Reflect approach is also useful for panning. Both Fold or AddWrap can be useful for spreading values so the values don’t clip out at one. For example, say you have 4 voices and you want each voice to have a spread from the other, but you’ll also be modulating that spread or perhaps the center value. Using an add wrap mixer can help keep the spread ratio while using fold wrap will potentially cluster the spread around the ends without them all clipping to -1 or 1.
Normalizing Mix
A normalizing mixer automatically scales down the inputs based on the input values. In the summing mixer, you can manually adjust the input scale down and it will adjust all the scales. If you don’t want to manually adjust those, we can create a quick formula to adjust the input based on the level. This may be useful in a performance setting where you may be making adjustments quickly but want to guard against clipping the signal.
There are two basic formulas, one for signals that are likely to be correlated and one for uncorrelated signals.
Correlated. Using a 4 input example:
1/ ((!Level_1 + !Level_2 + !Level_3 + !Level_4) vmax: 1)
Nice and easy. Basically we add the input levels together and if it is greater than one, we scale the mixer input by the sum total. If all 4 levels were 1, then the scale would be 1 / 4 or 0.25. We added the vmax capytalk so that the divisor never drops below 1.
Uncorrelated. Using a 4 input example:
1/ ((!Level_1 + !Level_2 + !Level_3 + !Level_4) sqrt vmax: 1)
Uncorrelated signals assume that it is unlikely that the signals will stack in a why so the peaks align to saturate the range beyond -1 to 1. Audio signals are uncorrelated. Modulation sources may be uncorrelated but it depends.
Auto-normalizing mix
Rather than adjust based on your fader values, you could auto adjust based on the signal. This requires you determine how you want the signal to adjust. In this case, you measure the input with the slew-rate or bidi follower and then mix multiple followers together in the same formula as above. Here, release value matters but if you are using this for modulation, you may want to adjust it a lot like you adjust compressors where the release fits within the overall tempo and rhythm of the piece. You can definitely run the risk of having the modulate swell in and out or be a bit unpredictable but perhaps that fits with your intent.
Product Mix
Not sure what this is called formally, but the idea here is that the input signals are fed into a product rather than summed.
Example capytalk
(!ModOn_1 true: (ModSource1) false: 1) → Product
(!ModOn_2 true: (ModSource2) false: 1) → Product
This passes a 1 to the product if the ModSource is disabled. As soon as you enable it by having the ModOn value go positive, it passes the mod source to the product.
The challenge here is that you find yourself quickly reducing the RMS down towards 0, especially as the input sources increase, but that could be just the desired effect you seek.
Matrix Mixer
Returning to the matrix mixer. There is a prototype for matrix mixers in Kyma. This takes a set of inputs with the ability to route the inputs to a given output. There are 4 and 8 channel versions. Then using the channel selector, we can route the output to our modulation destination.
Here is an example:
In this example, we wanted an auto-normalizing matrix so we didn’t clip our modulating mix. Rather than repeat the pattern to define the normalizing behavior, we use a script to calculate the to divisor total and generate the control events.
Example files
Here is are two kym files. One is of the matrix mixer above and another is a capyrate version of a custom granular engine. With the capyrate version, I left places for you to insert your own jitter sources. See above for some ideas and examples.
KatainCore-CapyRate.kym (308.5 KB)
ModulationMatrix.kym (205.3 KB)
The matrix mixer creates a highly playable way to switch between different sources and create different mixes quickly but one thing that I discovered is that it isn’t the most efficient use of resources especially when replicated. In talking with the some others, the theory is that by using output routing, we forego some of the optimization benefits within Kyma complier.
In the screenshot above you can see how I am routing the sources to the duration length, sample start, filter, pan, etc.
Other
I highly recommend that you sign-up for Alan Jackson’s Patreon. He has been releasing a new set of modules each month. This month includes some extremely handy files including a number of modules for building a sample rate granular engines, a sample rate clock divider, ASR, DAC, and more. Also included is an implementation of a Blippoo Box by Ian Fenton.
Alan is also providing one-on-one coaching and has been an invaluable resource to creating modules, especially sample rate versions of complex things that may have only been easily accomplished at Capyrate before. He is responsible for talking my brute force approach to the matrix mixer and turning it into an easier to maintain script.