Frodhes 0.9.5: a physically modelled electric piano, vibraphone and marimba for the M-VAVE FM-1. Every note is computed live from the mechanics of the instrument; there are no samples.
Download: frodhes.fwsc below (the same file as frodhes-0.9.5.fwsc; the newest is always at https://github.com/leonardoMirabal/frodhes/releases/latest/download/frodhes.fwsc). Try it first in your browser: https://leonardomirabal.github.io/frodhes/
Install
pip install mido python-rtmidi
python3 tools/fm1_install.py frodhes.fwscIf anything goes wrong, switch the FM-1 off, hold OCT− and switch it on to get the USB rescue, then install again.
New in 0.9.5
- 10 voices on every instrument (Rhodes, VIBES and MARIMBA; 9 before). Up to 9 notes the sound is exactly as
before; with more notes ringing at once (fast playing with the pedal, chords over ringing notes) fewer of them are
cut short. The room comes from making the engines and effects faster, not from simplifying the sound: all 10 struck at once with
every effect on take about 4 ms of the 5.8 ms the FM-1 has per audio block. - A more alive Rhodes.
- The whirl: held notes from E2 to C6 have the slow wobble of a real tine, about 2 dB once or twice a second
(slower low, faster high), and decay in two stages. The pitch stays put (within 1 cent), so it is not a chorus. - Every key a little different: each key has its own small, fixed differences in sustain, level, pickup
position, hammer contact and whirl, as on a real instrument, so chords and runs no longer sound like one note
copied. The tuning is not touched. - The bass strike: a hard-struck low note starts a touch sharp and settles as it rings (about 5 cents at the
hardest on the lowest two octaves, nothing when played softly). - The outer keys' pickups: the lowest keys (up to G#1) and the highest (from C7) sit farther from their
pickups, as on the instrument: a rounder, woodier growl in the deep bass, cleaner top keys. - The damper per register: the bass lets go a little softer, the treble a little crisper.
- The top five keys (G#7 to C8, reached with OCT and TRANSP or over MIDI) used to play an almost pure sine; they
now sound like the rest of the keyboard and grow their bark with velocity.
- The whirl: held notes from E2 to C6 have the slow wobble of a real tine, about 2 dB once or twice a second
- Release velocity (Rhodes): the velocity of a MIDI note-off shapes the damper. A quick lift stops the note
faster and firmer, with a louder knock; a slow lift lets it settle gently. A normal note-off (or none: the FM-1's
keys, the arpeggiator, the sequencer) sounds exactly as before. - The noises (Rhodes NOISE knob): a key-down knock, the hammer's thump through the mechanism, on SUITCASE,
EARLY FELT and BELL DYNO (STAGE 77, a pickup-only sound, has none), and a soft pedal thud when the sustain pedal
(or REC's latched sustain) goes down or up, on every TYPE. Both follow NOISE and how hard you play; none at 0. - The SUITCASE cabinet: its treble now rolls off gently, as a closed four-speaker cabinet does, instead of the low
cut it had. Same level; you hear it in the bright attacks, BELL and the top octaves. - TONE above its middle now changes only the colour, not the loudness (it used to make the note up to 10 dB
quieter), and gets steadily brighter all the way to the top. At and below the middle it is exactly as before. - SPREAD (MIDI CC 105, saved with the preset; no card): spreads the Rhodes across the stereo field by key, low
keys left and high keys right, as if you sat at the instrument. 0 (the default and every factory preset) is the mono
piano as before, 64 a gentle width, 127 the full width of an 88-key piano. VIBES and MARIMBA ignore it. - Key velocity on the FM-1's own keys: the 20 keys F3 to C5 read how firmly each press lands, so playing harder
plays louder and brighter (the top 7 keys, C#5 to G5, cannot measure it and play the average of the recent presses).
The notes sent over USB-MIDI carry it too. The method follows Charles Vestal's fm1-velocity. - SETUP K4 TOUCH: LIGHT, MEDIUM (the default), HEAVY or FIXED (every press at KEY VEL, the old behaviour). A
device setting, kept when you switch off. - Pitch bend on the Rhodes: ±2 semitones from USB-MIDI or the TRS input; held notes glide with the wheel and the
bend adds to TUNE. CC 121 and a USB disconnect reset it. VIBES and MARIMBA ignore it. Based on genkigenki's work
(PR #3). - Five drive types on the DRIVE page's K1 EFFECT: FDRV (the drive as it always was), KHLON (a
clean-blend overdrive), TSH8 (a mid-hump overdrive with tight lows), OHCD (a MOSFET overdrive, from a light
edge up to a crunchy, saturated overdrive over the whole AMOUNT range) and BHLUE (a two-stage soft overdrive).
Each is a model of its circuit, computed live and anti-aliased where it needs it (TSH8, OHCD, BHLUE); every type
plays at the level of the clean sound, and switching type while it sounds crossfades without a click. A DRIVE
knob on PERFORM turned up from OFF brings back the type you chose last. - TAPE, a third delay type (OFF / DIG / ANA / TAPE): a tape echo with one playback head, warm saturating repeats,
the head's EQ, and wow and flutter. TIME is the tape speed, so longer echoes are darker and turning TIME bends the
echoes' pitch for a moment, as on a real tape echo. TONE moves the high roll-off. A user preset saved with TAPE is
named with "TD". - The tremolo's amp law: TREM SHAPE has a second half. 0-64 bends the sine toward a square as before; 65-127 eases
the square back into a sine with an amp's feel: the level falls slower than it comes back, moves evenly in dB (a
deep setting breathes instead of chopping to silence) and gets a little shallower when you play loud. On PAN the
same half gives a slower swing. - The delay, reworked: FDBK alone sets how long the echoes repeat (on DIG and ANA it used to be scaled by MIX)
and MIX alone how loud they are, with the first echo as loud as the dry sound at MIX 64. ANA and TAPE self-oscillate
at the top of FDBK (from about 115) into a held drone kept in bounds by the echo's own saturation; turning FDBK down
lets it die away. DIG's echoes always die. - New factory presets, in two groups. Each instrument comes dry, as the model plays it, with only a gentle
compressor and a trace of room: F01 STAGE 77, F02 SUITCASE, F03 EARLY FELT, F04 BELL DYNO, F13 VIBES (a softer
mallet, a slower motor) and F15 MARIMBA (rings out). And with effects: F05 SUIT TREM (the suitcase with its
vibrato), F06 DRIVEN 77, F07 BALLAD, F08 DYNO 80S, F09 70S PHASER, F10 FUNK WAH, F11 RESO SWEEP, F12 AUTO WAH,
F14 VIBES ECHO (a longer ring, chorus, a dotted-1/8 tape echo, a plate), F16 WOOD ECHO (chorus, a dotted-1/8
digital echo, a hall), and three more Rhodes sounds: F17 TAPE ECHO (a warm piano into the tape echo), F18 DREAM
(felt hammers, a slow pan, chorus, a long dark hall) and F19 RADIO (a hard OHCD drive through a band-pass, like a
small speaker). Every effect, the new drive types, TAPE and the reverb types are used by at least one; the
echoes and filter sweeps follow the tempo. PRESETS browses F01-F19, then U01-U16. Program Change 0-15 loads F01-F16 in this order, 32-34 F17-F19. The Rhodes presets stay within
about 1 LU of F01's loudness (F12's deep band-pass sweep is set a little above it). - Every preset has the compressor on, gently (glue, not squash: -16 dB at 2:1 on the Rhodes with a 5 ms attack
that lets the hammer and the bark through; 1.5:1 with a 9 ms attack on the mallets, so the strike passes before it
acts), and nearly every one a little reverb, HALL or PLATE, with LOW CUT at 150-200 Hz. - Nine starter user presets: until you save your first preset, U01-U09 hold more Rhodes sounds: U01 DARK KEYS,
U02 GLASS BELL, U03 FUNK COMP, U04 DREAM PAD (INFINITE's long bloom, which still dies away so a save never waits),
U05 LO-FI, U06 HARD TREM, U07 SLOW PAN, U08 REEDY and U09 VELVET; U10-U16 start empty. Each has a
gentle compressor and a reverb type that suits it, with echoes on the tempo where they fit. They load like any user
preset, and your first save stores them on the FM-1 together with yours. - Reverb types on the REVERB page's new K1 TYPE: OFF, HALL (the reverb as it always was), PLATE (a
studio plate: dense at once, bright, no echoes to pick out) and INFINITE (a huge space that no room has, with
very long, slowly moving tails). On INFINITE, DECAY from 120 reads SUSTAIN: the tail stops fading and what you
play piles up on it; at the top, 127, FREEZE: what is ringing holds, neither growing nor fading, and what you
play stays dry (the large face shows Z). Either lasts until DECAY comes down again. A preset save waits while one of
them holds the tail (the bottom line says SAVE WAITS: SUSTAIN ON / FREEZE ON) and goes through once the tail has
died away. Every type's top octave is clean: bright overtones no longer fold back into the tail as faint
out-of-tune tones. The reverb runs at half rate, and the steps into and out of it are now sharp half-band filters:
a 15 kHz overtone that came back at 7 kHz only 10 dB down is now 37 dB and more down, and the faint mirror images
above 11 kHz (a 4 kHz tone's only 21 dB down, HALL's too since 0.9.3) are 40 dB and more down for every tone up to
6.9 kHz. A Rhodes or VIBES chord's tail above 11.6 kHz went from 57 to 63 dB under its body. The reverb comes
0.18 ms later; every preset stays within 0.1 LU of its level. Switching the type while the reverb sounds fades the old tail out in a few milliseconds, and the new type
starts empty. OFF lets the tail ring out. A REVERB knob on PERFORM turned up from OFF brings back the type you chose
last. - REVERB 2, a second reverb page right after REVERB: PRE-DELAY (moved from REVERB's K4), SIZE (AUTO, the
default, lets MIX set the size as before; 0.1–10.0 fixes it), MOD (how much the tail moves; 5.0 is the hall as
before) and LOW CUT (OFF, or 20–800 Hz taken out of what goes into the reverb). They work on every type. - PERFORM's four knobs are now DRIVE, FILTER, DELAY, REVERB out of the box, in the order of the effects chain
(they were TREM/WAH, PHASER, FILTER, DELAY). Anything else can still be put on a knob with ASSIGN. - The update screen: while an update installs, the FM-1 shows FRODHES, WRITING and a progress bar with the
percent; after an install that was cut off it says UPDATE MODE / UPDATE FAILED (install again). The screen shows
no website address. (Frodhes is now built on Dinghy 0.4.) - SMK-37 builds (experimental, not tested on hardware by us; back up your flash first: docs/SMK37.md). Each
release now ships them next to the FM-1's:frodhes-smk37-experimental.fwsc(SMK-37 Pro),
frodhes-smk37-elite-experimental.fwsc(SMK-37 Elite) andfrodhes-smk37-mke-experimental.fwsc(MKE-P37). They
play 7 voices and use the keyboard's own controls: all 37 keys with velocity (and SETUP TOUCH), the 16 pads, the
four faders in two banks with soft takeover, the pitch and mod wheels, a sustain pedal. The app layer follows
genkigenki's PR #3.
Changes
- Auto save keeps the FM-1's setup, not the sound. Switched off and on, the FM-1 plays the preset you last loaded
or saved exactly as it is stored: knob, effect and MIDI CC changes made since are not kept, on purpose, so after a
performance it always starts from the original sound (to keep a sound, SAVE it to a user preset). What is saved
about 2 s after you change it, once silent: the preset number, the MIDI page (CHANNEL, TRS IN, CLOCK), KEY VEL,
TOUCH, TUNE, USB VOL, the DISPLAY page (COLOR, BRIGHTNESS, LEDS), the PERFORM assignments, the octave, the scale
(and TRANSP), chord mode, the arpeggiator, the sequencer's BARS, QUANT and SWING (its pattern as before), the
motor's off switch, and the tempo you set by hand (TAP or the TEMPO page's BPM; presets do not hold a tempo). An
external MIDI clock never causes a save, and the tempo it sets is not the one that comes back. Turning knobs writes
nothing to the flash at all. - The MIDI and USB audio name is now "Frodhes" (it was "Felucca"). The FM-1 has a new USB product id, so a Mac or
PC sets it up as a new device by itself (nothing to delete): switch the Frodhes port on once in your DAW. The update
mode keeps its name, "Felucca Update". The installer finds the FM-1 under either name. - Letting a MIDI sustain pedal up (CC 64 below 64) also releases a latched REC sustain, so a real pedal always works
as a pedal. - The TRS MIDI input no longer holds a message back until the next byte arrives.
- Updating from 0.9.4: your settings, user presets and sequencer pattern are read as they are, and the FM-1
comes back on the preset it was left on. What you may notice:- The factory presets are new, F01 and F15 included: F01 STAGE 77 is now dry (no drive) with the compressor
and a trace of hall, so the sound Frodhes starts with changes a little. A user preset you saved from one keeps its
own sound. Program Change 0-15 still loads F01-F16 and 16-31 U01-U16, in the new order; 32-34 load the new F17-F19. - The starter presets U01-U09 appear only on an FM-1 with no saved user presets. If you have saved any, your
bank stays exactly as it is. - The first start plays your last preset as it is stored, not the edited sound you left it on (above).
- The FM-1 remembers which preset it played: saved settings that named a user preset name the same one after
the update. On a test build of this release, TAPE ECHO, DREAM and RADIO were the starters U10-U12; a setting that
named one of them now names F17-F19 (when that user slot is empty), with exactly the same sound. - PERFORM: if you never changed the knob assignment (or it was the old default), the knobs become DRIVE,
FILTER, DELAY, REVERB on the first start; an assignment you changed stays as you set it. - The delay laws: your saved sounds with the delay come out wetter and repeat longer (FDBK no longer scaled
down by MIX, the MIX-64 echo at the dry level). Lower MIX or FDBK a little to get the old sound back. The factory
presets were re-set for the new laws. - DRIVE now comes before the FILTER (COMP, DRIVE, FILTER, TREM/WAH, PHASER, CHORUS, DELAY, REVERB), on the
screen too. A sound with the drive on and the filter closed or resonant can come out up to about 1.5 dB louder and
a little different; with the filter open or off nothing changes. - TREM SHAPE above 64 now plays the amp law; 0-64 is as before.
- TONE above its middle keeps its loudness now, so a saved sound with a high TONE is louder than it was (the
starter presets U02, U03 and U08 are set for this). - KEY VEL is now the velocity of a medium press on the FM-1's keys (with TOUCH FIXED, of every press, as
before). Old settings start with TOUCH MEDIUM and keep their KEY VEL. - OHCD's range: OHCD now covers its whole circuit. If you saved a sound with OHCD on a test build of this
release, AMOUNT above 33 plays hotter (about two thirds of the old value gives the old sound); the presets with OHCD
(F11 RESO SWEEP, F19 RADIO, U05 LO-FI) are set for the whole range.
- The factory presets are new, F01 and F15 included: F01 STAGE 77 is now dry (no drive) with the compressor
- MIDI CC 84 (the drive) now picks the type: 0-63 OFF, 64-75 KHLON, 76-87 TSH8, 88-99 OHCD, 100-111 BHLUE,
112-127 FDRV. 127 is the drive as before; a setup that sent 64 for on now gets KHLON. Saved sounds keep their drive. - MIDI CC 88 (the delay type) now has four bands: 0-31 OFF, 32-63 DIG, 64-95 ANA, 96-127 TAPE. Send 48 for DIG and
80 for ANA (64 used to mean DIG, 127 ANA). Saved sounds keep their delay type. - REVERB's cards are now TYPE, MIX, DECAY, TONE; PRE-DELAY is on REVERB 2. The page count goes from 22 to 23.
- New CCs for the reverb: 95 TYPE (0–31 OFF, 32–63 HALL, 64–95 PLATE, 96–127 INFINITE), 73 SIZE (0 = AUTO), 68
MOD, 69 LOW CUT (0 = OFF). Saved settings and presets from earlier versions load as HALL with REVERB 2 at its
defaults, so they sound exactly as before. - The browser emulator has no key velocity: its keys play at KEY VEL, as before.
- Less CPU, the same sound. Every sound is byte for byte what it was; only the time it takes is less. The hottest
audio loops now run from the FM-1's RAM instead of its flash (no more waits while the flash's cache fills); the
Rhodes voice loops, its pitch-bend retune and its pickup (mono and the stereo one SPREAD uses) do the same work in
fewer steps, and so do the TAPE delay, the wah, the chorus, SPREAD's panning and INFINITE's reverb loop; the filter
that turns the sound into the 48 kHz USB audio is cheaper (the USB stream bit for bit the same). On the FM-1, with
10 voices, every effect on and the reverb on INFINITE, the whole audio interrupt's worst block (3 takes each, before
and after): the Rhodes with SPREAD at 127 and bending 4224-4268 to 3916-3972 µs, VIBES 4144-4216 to 4040-4120,
the Rhodes bending 3752-3772 µs, MARIMBA 3988-4000 µs, of the 5805 µs each audio block has.
Fixed
-
Letting go of a key no longer makes the sound louder ("I press a key and get 2 sounds"). The damper's key-up
thump, which rings the tine at the note's own pitch, had one fixed level set by NOISE; with the FM-1's key velocity
a soft note plays well under it, so the thump came out up to 12 dB louder than the note (30 dB at NOISE 127). It is
now capped at a fixed share of the note: the note's strike force times the level the note still has. The key-up
felt noise and the pedal's thud over sounding notes follow the same rule, and so do VIBES's key-up knock and felt.
A loud note gets a smaller thump than before (v100 about 14 dB down, v127 about 7 dB down at NOISE 48), a soft note
one about 23 dB under it, and release velocity still scales the thump after the cap. NOISE 0, MARIMBA (no damper)
and the pedal's thud into silence are unchanged. -
MARIMBA's low keys are in tune: below C2 and on C2 / C#2 the note sounded slightly flat (up to 5 cents on the
lowest keys, about 1 cent at C2), because the bar and its resonator tube ring as two very close tones and the lower
one carried the pitch. Every MARIMBA key now reads within 1 cent; the keys from C4 up and VIBES are unchanged. -
INFINITE (on the test builds) had a bright band at 10-11.5 kHz, about 8 dB over HALL's, and a faint tone at
11 kHz in its tail. Its top is now damped as HALL's is, and neither is there. -
Tuned down (TUNE below 0, or a bend down), the lowest keys' release rang out of tune (up to 2 semitones on the
Rhodes A0 at the shortest release, more on the VIBES and MARIMBA A0-B0). Now in tune everywhere; TUNE 0 and up is
unchanged. -
The top of the Rhodes TONE knob (above about +3.0) hollowed the note out and dropped it up to 14 dB before it came
back. TONE now gets brighter all the way to +5.0 on every TYPE. -
F3 to A#3: the strike's bell overtone played up to 2.4 dB under its intended level. It is now at its level.
-
The touch wah's level depended on DEPTH (about 2 LU quieter at a low DEPTH, 2 LU louder at a high one), and a
closed, resonant wah lost the high notes (a C7 up to 10 LU). Every note now stays within about 1 LU of the dry
sound (MARIMBA's very short top octave still loses a little). -
The delay's echoes could carry a small step once per audio block when the sound was wider than mono (chorus,
phaser, auto-pan), and the chorus had a fine zipper. Both now glide. -
A very loud signal into the chorus (a hard VIBES chord with the effects up) could come out as a loud click. Fixed.
-
Clicks on the USB audio at full polyphony (a DAW at 44.1 or 48 kHz, the pedal down, every voice playing): the
USB audio could run dry during a long block and repeat a frame. It now keeps one whole block in hand, so the USB
audio reaches the computer 5.8 ms later than before; the headphone jack is unchanged. 0.9.3 and 0.9.4 had this bug.
This is issue 8 on GitHub: the USB audio popping is fixed, the save gap included (below). -
Saving the settings while a computer records the USB audio no longer leaves a gap. Writing the flash used to
hold the FM-1 still for up to about 24 ms, so the recording lost packets; 0.9.4 had the saves wait until the
recording stopped or a minute of silence went by, so a change made while recording could be lost at switch-off. The
FM-1 now writes its flash in short steps (about a quarter of a millisecond each, the flash part paused while the
audio and USB run between them): the settings are saved about 2 s after the last setup change once the sound has died
away, the pattern 1.5 s after, recording or not, and the USB audio carries on without a gap. On the FM-1, recording
at 48 and at 44.1 kHz while the settings were saved: 0 missed and 0 overrun USB packets, the interrupts held off
282 µs at the longest (it was about 24 ms). -
DELAY: switching the delay off or on while echoes ring no longer clicks. The send now fades over one audio block
when DIG, ANA or TAPE is switched off or on (it was cut at once, and the cut came back as a click one delay time
later); an ANA delay switched off rings out as ANA (its tail switched to the DIG sound at once); and a delay
switched back on after its echoes died no longer replays old audio from 1.5 s before (a loud click). -
The sequencer's pattern was lost after its first save: a later change came back as the old pattern at the next
power-on. Every save now sticks. -
F11 RESO SWEEP was about 2 dB louder than the other Rhodes presets. Its LEVEL is now 1.5 dB lower, level with
F01. -
SMK-37 (experimental): the fourth knob card lost its turns and the FX, SEQ, PLAY and REC lights stayed dark. Fixed.
-
Everything synced now follows an external MIDI clock (CLOCK EXT, over USB and the TRS jack). The tempo often
never changed: the FM-1 timed each clock pulse when it got round to reading it, and pulses read together (during
a screen update, or several in one USB packet) reset the count. Each pulse is now timed when it arrives and the
tempo is measured over up to four beats, so the delay SYNC (DIG, ANA and TAPE), the tremolo, phaser, chorus and
filter LFO SYNC and the vibraphone's motor SYNC follow the clock's tempo exactly (40 to 240 BPM, the BPM card's range; a
tempo change within about two beats; a clock outside the range is not followed). -
The synced LFOs are locked to the clock's beats, not only to its tempo: each LFO's cycle starts on
the beat (the phase a reset gives it, so the presets sound as they were set), a cycle of 1/2, a bar or more starts on beat 1 counted from Start, and an LFO out of step
catches up smoothly (or jumps into place while nothing sounds). -
The arpeggiator and the sequencer play on the clock's pulses instead of running on beside them at about the same
tempo: the arpeggiator's steps fall on the pulses, the sequencer moves with each pulse (smoothly in between, never
ahead of the clock), swing, QUANT and recording on the same grid. Start plays bar 1 on the first pulse (again
from bar 1 when the pattern was already playing); Continue carries on from where Stop left it instead of starting
over. -
While a clock leads, PLAY taps and the BPM knob change nothing (they made the tempo jump twice). The clock's tempo
is no longer marked as a changed setting on every small change, never saved, and redrawn only when the BPM shown
changes; CLOCK INT gives the FM-1's own BPM back. A clock out of the 40..240 range is no longer followed half way
(the delay echoed at 750 and 552 ms after 30 and 400 BPM clocks). -
Under a clock the sequencer plays notes that are only late (the main loop busy, even at 240 BPM) instead of dropping
them, holds through a short dropout of the clock and goes on with the song when it comes back. -
Without a clock (CLOCK INT, or no clock coming) the synced LFOs lock to the FM-1's own beats the same way: a tap
on PLAY re-phases them, and a clock that stops hands over to its last beats without a jump. -
Two clocks at once (USB and the TRS jack) no longer add up: the first one is followed and the other ignored until
the first has been silent for half a second. -
Song Position (sent while stopped, when a computer's playhead moves) sets where Continue goes on, from USB and the
TRS jack. Clock pulses dropped while the FM-1 was busy are still counted, and one late pulse no longer moves the
tempo. The automatic saves (the settings and the sequencer's pattern) wait while a clock runs. -
USB clock sent with the single-byte system-common packet code, as some computers do, is accepted too.
-
Notes over the TRS MIDI input could arrive up to about 40 ms late. The input only picked up a short message
every 32 ms; it now does every 0.5 ms. On the FM-1 the time from a note sent to its sound is now 10.6-16.3 ms over
TRS (a spread of 5.7 ms), the same as over USB; before it was 11-52 ms. -
A note played just after a program change could come up to about 140 ms late. The settings save after a
preset change held the FM-1's main loop; it now runs in short slices beside it, at most about 0.6 ms at a time. On
the FM-1 the note after a Program Change is on time (10-21 ms), over USB and over TRS. -
A note played right after you record a sequencer pattern could come up to about 100 ms late. The pattern save
held the FM-1 for a moment; it now runs in short steps beside everything else, like the settings save, and the two
saves never wait on each other. -
A power cut while the setup is being saved no longer loses the whole setup. The setup (the sound last loaded,
octave, tempo, scale, MIDI and the other settings) was kept in one place in the flash, and each save erased it
first: switched off in that fraction of a second (about 2 s after a change), the FM-1 started with the factory
setup. It is now kept in two places and a save writes the older one, so a cut save loses only that last change.
The first start after the update reads the setup the earlier version saved, as it is.
Known in this beta
- F11 RESO SWEEP plays about 1.8 dB quieter than the other Rhodes presets (the level matching allows 1.5). Its filter sweep now locks to the beat, which moved its level a little; it will be matched again in the next update.
Tools
- A real cracks test for the release (
tools/hil_crackle.py,hil_scan.py --only stress_max): minutes of the worst
case on the FM-1, every voice held with every effect heavy, recorded on USB and the headphone jack at once at 48 and
44.1 kHz, its detectors proven on host renders first; it fails on 0.9.4, as it must. - The FM-1 tests in tiers picked from what changed (
tools/test_map.py): the must-pass scenarios (hil_scan.py --tier must, six real-use scenarios) on every release, the full sound scan when an engine or the effects changed. tools/hil_cpu.pymeasures with the USB audio streaming (--usb 44100|48000), reads the firmware's own USB counters
and fails above 4500 µs;tools/cpu_budget.pypredicts the worst block from the measured costs.- The CPU gate: the release's worst cases on the FM-1 (the Rhodes with SPREAD 127 and bending, the Rhodes bending,
VIBES, MARIMBA; 10 voices, every effect on with the heaviest drive, TAPE and the heaviest reverb type, the USB audio
at 48 kHz) are each judged on the highest of 3 takes, and a whole audio interrupt over 4200 µs is now a FAIL
(hil_cpu's own limit stays 4500 µs). The cases that were over 4200 µs before (the Rhodes with SPREAD and
bending, VIBES) need 3 good takes in a row.tools/cpu_check.shruns the same check on a branch before it is
merged (about 10 minutes); the final run (tools/final/run_final_rev.sh) uses the same steps and rule. - New developer tools:
tools/hil_keyvel.py(the key velocity),tools/hil_drive.py(the drive types on the FM-1),
tools/engine_ab.pyandtools/rh_nulltest.py(is an engine change audible),tools/types_ab.py,
tools/rh_whirl.py,tools/tone_level.py,tools/isr_diff.py,tools/font_chars.py;./build.sh --board smk37 [--model elite|mke]andmake test-smkfor the SMK-37;tools/release.py --no-device --device-done FILE;
tools/hil_autosave.py(the settings saved while a computer records: the USB stream stays clean, the flash's
longest interrupts-off stretch, also shown byhil_cpu.pyasflash_off); the CC 116 reply's items 17-20 (the
longest stretch a flash write held the interrupts off, the part's suspend bits, the longest erase's own time and
its start to end). - The reverb types' tests and FM-1 tools:
tools/rev_scan.py(withtests/c/rev_scan.c) runs the reverb on the
firmware's own code for any TYPE (T60 per DECAY, the freeze over minutes of audio, TYPE switches, the tails' end,
the levels and the cost);tools/hil_cpu_rev.py(hil_cpu with every reverb TYPE, the heaviest drive, TAPE and
SPREAD),tools/hil_crackle_rev.py(the cracks test with INFINITE frozen part way),tools/hil_rev_takes.py(the
listening takes on USB and the jack);tools/cpu_budget.pypredicts every reverb TYPE.
Tested
-
Host:
make test,make testv V=8/V=9,make test-smk,make pytest, and Gate R: every render byte for byte
as before except the ones each sound change was meant to move (more than 9 voices, the whirl and per-key
differences, the bass strike, the outer keys' pickups, the damper, the noises, the cabinet, the delay, OHCD, DRIVE
before FILTER, the key-up cap, MARIMBA's low keys, the new preset bank), each listed and checked. Every factory and starter preset level-checked against F01, no clipping or
clicks; the cracks test's detectors proven on host renders (every injected glitch found, none on clean renders).
The reverb types:tests/py/test_rev_types.py(HALL at its defaults is the HALL before, byte for byte; T60 per
DECAY; INFINITE frozen for 10 minutes within 1 dB, no growth, no DC, full-scale bursts; TYPE switches without
clicks and with no old tail; the tails end in exact zero; old presets and settings play as before; every new knob
does what it says; the levels against HALL), the REVERB / REVERB 2 pages' scripts and the card fit scan on every
TYPE, a save waiting under FREEZE and SUSTAIN. The delay switch: DIG, ANA and TAPE off and on four times under held
chords (before the fix the worst kink was up to 70x the steady renders'). The key-up never louder:
tests/py/test_release_never_louder.py(every TYPE x NOISE 0 / 48 / 127 x six velocities x bass / mid / top key,
held 0.2 s and 2 s, with and without the pedal: over 0.6 s after the key-up the level never rises more than 0.5 dB
and no new onset appears; it failed 36 of 72 cases before the fix), and every one of the 27 FM-1 keys pressed at
every scan phase through the real scan and velocity code (1122 presses, one note-on and one note-off each). MARIMBA
every key within 1 cent of its pitch. INFINITE's top band under HALL's. The reverb's top octave
(tests/py/test_rev_images.py, on the firmware's own code, every TYPE): each tone's image from 1 to 6 kHz 40 dB or
more down, a 15 kHz tone's fold 35 dB or more, a bright chord's tail above 11.6 kHz 53 dB or more under its body; it
fails 9 of 10 before the change. The split flash writes (tests/py/test_flash_split.py, on a host model of the
part, FM-1 and SMK-37 layouts, erases of 1-30 ms and programs of 0.1-3 ms: the interrupts off 0.3 ms at most, the
part's suspend rules, the bytes written, the blocking fallback) and the settings saved with the USB stream on
(tests/scripts/usb_rec_save, which fails on the old rule). F17-F19 within 0.1 LU of F01; the saved preset index
carried over from 12, 14 and 16 factory presets and from the test builds' U10-U12; a 0.9.4 settings record. Every preset's chord loudness within
0.3 LU of its target and each preset's predicted CPU under 4200 µs. -
The CPU work: every render byte for byte as before (Gate R, 111 of 111, after each change), host A/B renders of the
Rhodes and VIBES with every effect, TAPE, each reverb TYPE, SPREAD 0 / 60 / 127, pitch-bend sweeps and TYPE
switches mid-note identical, the USB stream's 48 kHz output bit for bit the same;tests/py/test_rh_coef.py,
make test,make pytest,./build.shto the end (no calls out of the RAM loops, the hot-loop checks). On the
FM-1 (tools/cpu_check.sh, 10 voices, every effect on, reverb INFINITE, USB 48 kHz, 3 takes each), the whole
audio interrupt's worst block: the Rhodes with SPREAD 127 and bending 3916-3972 µs (4224-4268 before), the Rhodes
bending 3752-3772, VIBES 4040-4120 (4144-4216 before), MARIMBA 3988-4000 µs: all under the 4200 µs rule. The final run on the release build measures them again. -
FM-1, the final run on the release build (sha256 2ca1d517c430): every effect on with the heaviest
drive (TSH8) and TAPE, 10 voices, the USB audio at 48 kHz (hil_cpu.py --worst --usb 48000): the whole audio
interrupt's worst 3628-3688 µs on the Rhodes (three runs; 3808 while bending), 4164 on VIBES, 4032 on MARIMBA,
of the 4500 µs limit; with SPREAD at 127 3800 µs (3972 while bending). Per reverb type (Rhodes / VIBES /
MARIMBA): HALL 3588 / 4104 / 3972, PLATE 3628 / 4140 / 4020, INFINITE 3688 / 4164 / 4032 µs. No voice shed, the
USB stream clean (no missed, overrun or underrun packets) in all 14 runs. Reading the keys' velocity costs at most
40 µs a block under the stress (27 runs). -
The settings saved while a computer records (
tools/hil_autosave.py, on the split-flash build, at 48 and 44.1 kHz):
the settings saved with the stream on, 0 missed and 0 overrun USB packets, the longest stretch with the
interrupts off 282 µs. -
The must-pass scenarios (
hil_scan.py --tier must): playing live on the headphone jack with no USB stream,
switching presets and TYPEs while notes ring, and every control swept under load pass (the live jack one as the
stress test's takes without the USB stream; the switching and the controls with 0 failures); the update from
0.9.4 (over USB, the settings survive) passes, the saved sound within 0.0 LU of
its level before the update. The key-up never louder on the FM-1 (tools/hil_release_level.py, USB and jack):
0 of 160 key-ups louder, in two runs. -
The stress test (
hil_scan.py --only stress_max, minutes of every voice held with every effect heavy, recorded on
USB and the headphone jack at once): at 48 kHz 0 events (two runs), at 44.1 kHz 0 events, with INFINITE frozen
part way 0 events; the longest block 3812 µs at 48 kHz and 3612 at 44.1 kHz. Before each run its detectors are
proven on host renders: every injected glitch found (10 of 10 for each of 14 kinds, on every instrument), none on
clean renders. Then a soak: eight more stress runs back to back, about 2.5 hours at 48 and 44.1 kHz, 0 events.
The reverb on the jack (tools/hil_rev_takes.py, 11 takes of every TYPE): 0 events; INFINITE frozen for 60 s
holds within 1.25 dB, growing 0.8 dB at most, no DC. -
The headphone jack (Rhodes, VIBES, MARIMBA): pass, the silence at -92.5 dB. The hiss (8-20 kHz under a quiet
note) -99.0 / -99.0 / -99.0 dB (0.9.4: -99.8 / -99.9 / -99.9), a loud chord over the hiss 72.3 / 72.8 / 69.4 dB
(0.9.4: 74.0 / 73.7 / 70.3). The time from a MIDI note to the sound at 48 kHz: 11.5-16.5 ms on the USB, 9.0-13.0 ms on the jack (the USB 2.4-4.3 ms after the jack); at 44.1 kHz: 9.2-15.0 ms on the USB, 7.9 ms on the jack (the USB 2.5 ms after the jack). -
Host:
tests/py/test_midi_clock.py(55 cases; andtest_delay_clock_long.py;test_autosave_setup.py: no settings write while a clock runs): a steady clock at 90 / 120 / 137 BPM over USB and TRS, the main
loop busy 0-30 ms at a time, bursty USB timing (packets every 4 ms, held back up to 15 ms and caught up), TRS
pulses 0-5 ms late, a jump 120 -> 90 and a ramp 90 -> 140, Start / Stop / Continue / Start, 40 / 240 BPM and out
of range, a tap during the clock, two clocks at once, the LFOs on the taps without a clock, the uptime past 4.66 hours, the render holding
the main loop 3 ms a block, one pulse 45 ms late, TRS jitter against the delay time, the main loop held 0.9 and
1.5 s (the ring full), BARS changed under the clock, a 400 ms clock gap, Song Position, the arpeggiator when the
clock stops. Checked: the tempo, the samples a beat and the delay time (within 0.1 %), the
echo a beat after the note on DIG / ANA / TAPE, every synced LFO's phase against the beats sent (within 5 % of a
beat from 2 bars after Start; 1/16 to a bar), the tremolo's period (0.5 %) and its loudest point in the sound, the
arpeggiator's and the sequencer's notes on their pulses (never early, none missed). The busy main loop case
stays at 120.0 BPM with the old code (the clock at 137). Gate R: 109 of 111 renders byte-identical; moved on
purpose and re-saved:scripts/clock(its Start without a clock now waits 100 ms for a first pulse) and
scripts/vibes_motor(its motor SYNC section: the motor now on the FM-1's own beats).make test,make pytest,./build.shto the end.
Not yet tested on the FM-1. -
MIDI over USB and TRS alike (
tools/hil_midi_parity.py: the same MIDI sent over USB and over the TRS jack,
compared event by event): TRS note onsets 10.6-16.3 ms (spread 5.7 ms), the same as USB (11-52 ms before); the
note after a Program Change 10-21 ms on both. The TRS input's buffer is now 256 bytes (82 ms of MIDI), longer than
a flash erase. -
Host: a power cut at every step of a save (the erase's and each write's slices), with the cut step left undone,
done or half done, from a 0.9.4 setup, from either place newer and from none: always the old setup or the new one,
and the next save works. The first start after the update, the save counter's wrap, a corrupted record.
Full manual: https://github.com/leonardoMirabal/frodhes/blob/main/docs/MANUAL.md · Built on Dinghy. GPL-3.0.