Bubba Machine's audio
Bubba Machine has one goal: the best audio quality the FM-1 allows. This page covers what changed in 0.4.0-beta to get there, what each part costs on the device and, just as plainly, what isn't there yet.
All CPU figures were measured on the author's FM-1 with the firmware console (tools/fm1/traza.py). The details of each measurement are in TRAZA_FM1.md and MOTORES.md (Spanish).
The device
| Processor | JieLi AC791N, two cores at 360 MHz with a single-precision FPU |
| Output | external codec over I2S, 24-bit stereo at 44,117.6 Hz (24 MHz / 544, fixed by hardware) |
| Memory for recorded sound | 116 KiB of flash for sampler takes |
What improved
1. Everything at 44.1 kHz
In 0.3 the engines ran at 22 kHz and every sample was repeated twice to reach the output. That cuts everything above 11 kHz and leaves images (false highs) above it.
Now the engines and the mix run at the codec's real rate, 44,117.6 Hz, with no oversampling. Highs reach 20 kHz and tuning is exact, because it is computed with the true rate, not with 44,100.
2. Floating-point mixing
| 0.3 | 0.4 | |
|---|---|---|
| Mix bus | integer, one division per sample and track | float, gains computed once per block |
| Silent tracks | still computed | skipped |
| Live effects capture (stutter, reverse, tape stop) | 8-bit μ-law | 16-bit |
| Delay | 8-bit μ-law | 16-bit with interpolated reads |
| Mix cost with PLAY | 8.6 % of a core | 7.3 %, computing twice the samples |
Measured on the device, the FPU is 1.5× faster than the 64-bit integer math 0.3 used, so moving to float was both faster and cleaner.
3. Sounds computed live, no low-resolution recordings
0.3 had drum kits recorded at 22 kHz in 8-bit μ-law (nothing above 11 kHz) and low-resolution wavetables. They are all gone. Every sound is now computed on the spot with proven synthesis libraries:
| Engine | What it uses | License |
|---|---|---|
| Modeled drums | kick, snare and hi-hat models from Plaits (Mutable Instruments), in float, plus our own clap, cowbell, resonator, noise and FM percussion | MIT |
| ANALOG | polyBLEP oscillators (anti-aliasing), LP 24/12, BP or HP filter with resonance and drive, ADSR, LFO, sync and ring | own and MIT (Plaits/stmlib) |
| 6-operator FM | msfa, the engine of Dexed and the same base as the factory firmware; all 32 DX7 algorithms | Apache-2.0 |
| ACID | 4-pole ladder filter with resonance, accent and slide | own |
Accent doesn't just raise the level: it changes the hit, like a real drum machine.
4. An output without clicks or steps
- Soft clipper with DRIVE (a polynomial, not a hard cut) and a −1 dBFS ceiling before the codec.
- The MASTER volume ramps inside each block: turning the knob makes no steps.
- When the firmware writes the flash, audio has to stop: it goes out and back with a 5 ms fade, no click.
- Sampler recording goes through a Butterworth filter before dropping to 16 kHz, so highs don't fold back while recording.
- No-interpolation playback (DROP) became LINEAR, and the sampler also has Hermite.
5. Exact timing
The sequencer counts 96 PPQN from the audio sample counter: there is no separate clock to drift, and every note lands on its exact sample inside the block.
6. Performance: what makes room for quality
Computing twice the samples with better engines only fits if the code is fast. What was measured and changed:
| Change | Before | After |
|---|---|---|
| Data cache (SDK setting) | 4 KiB effective | 32 KiB: random reads 6-10× faster |
Audio compiled for speed (-O2) | demo with PLAY: 36.9 % of a core | 27.7 % |
| FM, one voice (E.PIANO) | 6.6 % | 3.3 % |
| ANALOG, one voice | 1757 ns per sample (10 %) | 654 ns (4.1 %): 7 voices fit with no late blocks |
Removing the recorded kits and wavetables made the program 148 KiB smaller and freed 64 KiB of RAM.
What isn't there yet
This is a beta. What limits quality today, plainly:
-
The sampler records at 16 kHz and 8 bits. The FM-1's flash leaves 116 KiB for takes (7.4 s in total); at 16 bits it would be half that. With the filter before recording and the dither in
toma.pyit sounds clean, but it stops around 7 kHz and has 8-bit noise. It is the weakest point and the next one to solve. - The delay runs at 22 kHz: repeats reach 11 kHz, like a tape delay. That is on purpose, so 1.5 s fits in RAM, but it isn't hi-fi.
- The clipper has no oversampling: with very high DRIVE it can alias a little.
- ACID is our own engine, not Open303. The plan is to move to Open303 (MIT) in float.
- msfa's FM is fixed point, like the original DX7. That's part of its character, not a flaw, but it isn't float.
- No reverb, chorus or master compressor yet. Only the soft clipper.
- Audio uses a single core. The second one gives 1.83× (measured); using it is what will allow more voices and effects.
- We haven't measured the analog output (noise, distortion and response of the FM-1's codec and amplifier). Everything above is the digital side.
- Tested on a single FM-1.
What's next
- Audio on both cores.
- Master effects: Mutable Instruments reverb and chorus, tape delay, compressor and leveler.
- ACID with Open303 in float.
- A higher-quality sampler, within what the flash allows.
- Measure the analog output with an audio interface.
See also: sound engines · sound research · FM-1 measurements (Spanish) · changelog.
This page is generated from docs/en/AUDIO.md. Spotted a mistake? Edit the file and send a pull request.