Posted on

WaveBoy 0.65 Firmware Released!

0.65 is now available!

This update is huge! While it does not have any front facing changes, some of the internals have been completely overhauled. Most notably, there is a completely new pitch tracking solution which is much easier to calibrate and significantly more accurate. Numerous speed and efficiency improvements have been put in place as well which have also helped the pitch accuracy, and have significantly improved the alternate audio modes.

The pitch tracking improvements have made this release, in my mind, the most significant since we launched the WaveBoy. We’ll dive into that in a bit, though there is one downside I need to tackle first. The 0.65 upgrade will require folks re-calibrate the pitch for their own WaveBoy. I was wanting to avoid this, but there was just no way I could see to convert the old calibration to the new method. The new method is completely different.

To help with this, I made a quirky video to walk folks through the process:

It should be an easy process to follow, though do follow the instructions in the WaveBoy manual carefully and be sure to backup to SD card first. The process only takes a few minutes and no longer requires a tuner. The automatic settings should be good enough for most folks, though a tuner can still be used to further dial in the tracking.

Now to elaborate on the change. We’ve been slowly working on the first multi-voice WaveBoy-adjacent sound solution for the Commander X16 called the TurboWave X1688. It takes it name from the TurboGrafx-16 which had a 6-voice / 5-bit cyclic wavetable solution. Sound familiar? Though that project is in early stages, it is the first multi-voice variant of our variable/pitch-based DAC setup. While it is for the X16 now, I hope to have a standalone MIDI synthesizer version which may or may not be in a Eurorack form-factor as well (but as MIDI). That project has already paid dividends for WaveBoy as well, as I have discovered better ways of doing things on the WaveBoy. As an aside, TurboWave will probably be what we call our sound card and MIDI devices based on our DAC approach. WaveBoy is what we will call our pure Eurorack variable DAC modules.

Anyways, one of the things I learned from working on TurboWave is how to improve the pitch tracking. The TurboWave doesn’t have to worry about analog-to-digital (ADC) conversions and can use an internal pitch table which is always consistent. I am using the RP2350 for the TurboWave in RISCV mode which does not have a floating-point unit. This got me thinking, if I wanted to make a WaveBoy variant (such as the WaveBoy Advance or Micro) and use the RP2350/RISCV, I would not be able to use fast floating point. So I needed a solution that only required integer math but also let me deal with pitch calibration (due to all ADCs needing calibration). The way WaveBoy figured out pitch from the V/Oct + Pitch knob was by using the MIDI pitch to note calculation. This is a heavyweight task, even with the MCU’s floating-point unit (partly because the pow() function cannot use single-precision floating point and the ARM chip used only supports single-precision).

Instead, I decided to lean into the pitch-table idea for WaveBoy. Instead of direct pitch, though, it’s a table of ADC values. The ADCs on the WaveBoy goes from 0-4096 values. To derive pitch, there are 2 ADCs in play (V/Oct and the pitch knob). Thus the table is larger than just the 5 octave range of the V/Oct so that the user can tune across an 8 octave range. This is much MUCH more efficient. Originally I avoided doing this because I thought such a table would eat up too much flash. Turns out it is a chunk but it’s not as bad as I expected.

But since ADCs are non-linear and require calibration (something the TurboWave doesn’t have to worry about), just having the table won’t give us perfect tracking. To fix that, I had to change to a different calibration process. The previous process revolved around those (expensive) pitch to note calculations. The new one adjusts the offset within the pitch table. So, for instance, when calibrating note C-4, the WaveBoy can compare the ideal value in the table to the seen value on V/Oct and compute a difference. The pitches in between notes use the calibration values of those notes (in a sort of closest match fashion).

But there’s even more! The original tuning solution would have probably worked were it not for a bug in the firmware I have been trying to squash since WaveBoy was first released. At higher pitches, the WaveBoy would tend to go flat. This suggested to me that the timer was drifting but I could not figure out where or why. After *cough* years I finally found it. I originally used an open source library to help me figure out how to use the timers for the SAMD51 (the MCU that powers the ItsyBitsy M4 and thus the WaveBoy). That library used the Arduino map() function to calculate counter values. This was called after the timer interrupt fired. For “slow” timers, this isn’t a problem. But the DACs on WaveBoy have to go really fast and calling the map() function that many times was causing the timer to lag which meant the resulting pitch was lower than it should have been. That library was super helpful of note and am very glad it exists! It’s just that my use case requires having to spend as minimal a time as absolutely possible in my callback. So I moved to my own libraries, streamlining them to the essentials. I just hadn’t, until now, realized how inefficient map() was.

The new timer approach now just does a simple counter reset. This coupled with using DMA for the wave and noise modes has made the DAC output process much more efficient and eliminating the pitch drift. The sample mode does not currently use DMA (due to how buffering works) though the counter improvements have helped sample-pitch tracking as well. This benefits the alt-audio modes too as they now function properly across most of the pitch range. At the extremes they tend to wig out (due to array references rolling). I left those in because that seems fun and exploitable for weird sounds.

This doesn’t even cover all the firmware changes but is, perhaps by far, the biggest feature. This was a lot of work but I’m incredibly happy with the results. It’s almost like a new module! I hope folks enjoy it!

As always, if you run into any issues, or have any thoughts or concerns, don’t hesitate to reach out to us! In the meantime, we hope everyone has a joyful rest of the holiday season!

– Tim