devlog > midi
Rabbit holes with GUI animations
Captain's Log: Stardate 78011.8
Rabbit holes, rabbit holes everywhere. Today I started with an easy task: make the built-in simple velocity modulation amount for Exciters adjustable, so that it can be disabled when it is not wanted (for example when relying entirely on MPE channel pressure for loudness control).
The basic task actually was super simple and I was done in an hour. But then I realized that the GUI animations weren't taking into account the velocity sensitivity, so things looked wrong when you had it disabled. I went to fix that, and... then I realized that really the 3D display needed to animate things based on the fully-modulated Exciter loudness, so that if you had the loudness mapped to channel pressure, you'd see e.g. an oscillator speed up and slow down as you pushed harder/softer.
This was a somewhat more complex problem, but fortunately I had already built tooling for collecting modulation state so that it could be displayed elsewhere (for example, the modulated Y rotation of a microphone is displayed in 3D). I got a pretty decent version of this working, but it took longer than I had originally planned for the "simple" task of making velocity sensitivity adjustable.
The only issue now is that while velocity is in the range [0, 1], the modulation amount is unbounded and not normalized, so depending on how you modulate e.g. the gain on an oscillator, you can make it spin REALLY fast. But for now this seems pretty acceptable.
MIDI note off modulation
Captain's Log: Stardate 78009.3
Nothing too exciting today -- I mostly continued working on improving the voice instancing and MPE support.
The biggest bug I fixed had to do with noises that would appear when the user moved the slider that adjusts how many voice instances are available. When the slider was increased, you'd get clanking noises from the model, and it was obvious that somehow the new instances were not being initialized properly. This turned out to be really simple; basically there was a little bit of state about whether an entity had been initialized that was not being stored per-instance but only per-entity. So this was a simple fix and now the noises no longer occur.
I also implemented support for MIDI note OFF velocity as a modulation source. I had simply overlooked this before when I added note ON velocity. Now the MidiVelocity modulator sub-type offers "Velocity Phase" as an option where you can choose Note On Velocity or Note Off Velocity, and I added a golden test for this.
Polishing up MPE/polyphony support
Captain's Log: Stardate 78006.4
With the basic new web site up and running, today I went back to working on Anukari itself. I'll probably alternate back and forth between the website and the product code, mostly based on what I feel most motivated to work on.
I got MPE support working really well today. Actually, it worked shockingly well to start with, given that I wrote the code without an MPE controller to test against. Once I got the ROLI Seaboard, I only found a couple bugs. The biggest thing was that I was allocating voice instances based on the LRU note irrespective of whether the note was on or off. This led to bad playability when e.g. you hold down a root note and play a melody on top. You really want to steal instances from notes that are OFF before you steal from a note that is ON. Fixing this made things completely playable.
Now I'm going through and polishing odds and ends for both regular instanced polyphony and MPE. Things like making sure the GUI widgets that let you pick notes/channels change their appearance/behavior based on what mode the synthesizer is in, and making sure that the GUI "Reset" button resets all the new state, etc. There are a lot of little details like this that I need to clean up.
One slightly larger thing I need to fix has to do with Exciters that have hard-coded support for MIDI velocity. For example, oscillators are hard-coded to always set their gain based on note ON velocity. This is handy, but it doesn't play well with MPE, where often velocity would be used just to change something about the attack, and then channel pressure would completely control the gain. However, I don't want to throw out the hard-coded velocity stuff entirely, because in singleton mode it is really nice to not have to wire up velocity modulation manually every time. And on it goes... 😄