Unified Plaits alt firmware

Hi everyone - I’m hereby releasing the latest iteration of my alt firmware for Plaits. I’m starting this new thread because the old thread now has quite a bit of information in it that is out of date, and I don’t seem to be able to edit old posts, so I think it’s best to start fresh.

This new version of the alt firmware unifies all the extra features I added in prior versions (e.g. frequency locking, octave switching, aux crossfade, cv control of decay, etc) into one firmware where all the options are configurable in a menu. In other words you can now install this one firmware and switch on and off any combination of the various alt functionalities without having to install a new firmware (and without me having to publish every possible permutation separately). For more details on features, usage, and the download link, please check out the README!

As always I’ve done my best to test this out but please let me know if you run into any issues, thanks!


CV control over the LPG filter response might be a handy addition, maybe as a yellow mode for the Model input? That way you’ll be able to control both filter amount and decay.

Thanks again for all your hard work, this is awesome!

@jeaux sure thing, it has been added. Just remember that the MODEL input is bipolar whereas LEVEL is not!

1 Like

Question for the crowd - how important is it to people to be able to recalibrate the module without first reverting to the stock firmware? I had disabled that capability in the original frequency lock firmwares but recently added it back, and I’m now I’m thinking of removing it again to get back some space. Recalibrating is not something I have ~ever felt the need to do but I’m curious if other folks ever do. The reason I’m asking is that this firmware is getting pretty stuffed to the gills (the binary it produces has to be 256KiB max and it’s it’s now up to 255.97KiB :grimacing:) and that’s after already having trimmed the fat almost everywhere I could think of. I had one more option I was thinking of exposing (the ability to switch between the original chord bank and the alternative one by Jon Butler), but it would necessitate removing something (calibration). Let me know your thoughts!

Only thing I can think of is if someone sells their Plaits and the new owner can’t load the original firmware.

I don’t want to give you false hopes, but occasionally one forgets a little f somewhere and floats get cast to doubles, which adds bloaty emulated double precision routines (since the STM32F3 can only do single precision natively). Have you checked for that? make -f plaits/makefile disassemble and search for __aeabi_f2d in build/plaits/plaits.lss – it’s a sign such unholy conversions are happening.


Other low-hanging fruits:

  • The sine LUT is currently 1280(+4) float sample long, I doubt there will be much difference if you halve its size (2560 bytes gained). Linear interpolation is performed. Max error between the extra samples and an interpolated one: 2e-5.
  • The two wavefolder LUTs are currently 512(+4) float sample long, you could also halve them (2048 bytes gained). Hermite interpolation is used when lookups are performed. Max error: 1.9e-3 on OUT, 1.1e-2 (at a single peak, the second largest error is 1e-3) on AUX.
  • Very few waveforms from the wavetables have energy at the last harmonic (T = 2 samples). In fact, most of the waves are either generated by additive synthesis from a limited number of partials, or by upsampling to 256 samples waves from Braids which are originally 128 sample long. Keeping them 128(+4) sample long should be fine. (49512 bytes gained).

Of course, you might decide to use this reclaimed space for other interesting things :). And I’m sure there are people who will hear the 2e-5 error on some models and call it “a digital cold sounding abomination”, and praise the warmth and the detailed, vibrating highs of the original lookup tables :smiley:


Definitely run into this one. @pichenettes, please correct me if this is a bad idea, but I’ve started adding -Wdouble-promotion to line 214 of makefile.inc to check for it.

1 Like

Oh, that’s good to know! I’ll have to make sure it doesn’t trigger spurious warnings.

1 Like

@pichenettes thanks so much for the tips! I’ll experiment with those and see how much extra space that buys me.

Holy smokes this compiler flag is the best thing ever! I just found 100+ instances in some firmware I’ve been working on where the compiler was promoting floats to doubles because I forgot the .f. I had no idea it did that. I always wondered why @pichenettes so explicity placed .f everywhere.

Thanks to both of you for sharing that info!

Annnnnnnnd that just dropped my CPU usage by about 5%. Thanks for making my week ya’ll :two_hearts:

1 Like

Not exactly sure what the cake emoji refers to but if I’m interpreting correctly: Happy Birthday Émilie :birthday:

1 Like

For anyone following along who might be thinking of doing something similar in their own firmwares, I was able to pull off Émilie’s idea around halving the sine LUT, it’s a bit nontrivial so sharing here to save you some time: halving the size of the sine LUT by lylepmills · Pull Request #19 · lylepmills/eurorack · GitHub

Also, here’s how to rebuild the resources.cc/h files after making whatever updates in the python files (haven’t seen this documented anywhere so making note of it)
python stmlib/tools/resources_compiler.py plaits/resources/resources.py

1 Like

make -f plaits/makefile resources also does the trick! It’s not a good idea to manually change resources.h, I would suggest moving kSineWavetableSize somewhere else.

Ahh good callout thanks, fixed

Hi everyone, wanted to let you know I’ve added two more features (comprising three more options) to the firmware - a suboscillator (thanks to @bloc for the initial idea here) and the ability to switch to an alternative chord bank for the chord engine (thanks to Jon Butler for conceiving of this!). All details in the README!


Thx for building this feature im loading it right now and will have some sync fun this sunday.

I have a new chord table I’ve created if there is space, if it would work, and if you aren’t burned out on this project yet :grinning:.

It is based on functional harmony, neo-Riemannian inversion, and some quartal theory as well. Instead of Frequency defining the root and Harmonics defining chord type, Frequency would define the key and Harmonics would define the scale position the chord is built from. At 12 o’clock Harmonics sets a perfect 5th on the tonic. Moving clockwise cycles through various major key chords advancing by thirds through dominant chords and eventually to more obscure quartal chords at the extream. Counter clockwise moves through corresponding minor key chords. Each minor key chord is a neo-Riemannian reflection of the corresponding major chord, that way setting the knob at 12 and inverting a cv offset will reflect the chord produced, if that makes sense.

Anyway enough theory, here’s the table. The note examples are for the keys of C major/minor and the root of each chord is bold.


Thanks @jeaux for the alt chord table, it definitely looks like a worthy addition. I was just barely able to squeeze it into the firmware without cutting anything else out, but I want to make sure I understood how it’s supposed to work (some of the theory went over my head) - could I ask you to test it out before I put it into the main release? Basically after reading through your message a couple of times I just ignored most of it and tried to just code the chord table that you provided :laughing:, but I want to make sure I’m not missing any nuances of how it’s supposed to work.

Also, out of curiosity, where did you get it?

If you don’t mind testing, here is a download link for a version of the firmware with your table included as a third (yellow) option for the chord table.