Frodhes, image 1 from its README
1/3
Firmware

Frodhes

Hype: hot · 94

Physically modeled electric piano, vibraphone and marimba without samples.

forM-VAVE FM-1·by@leonardoMirabal

Unclaimed. Is this yours? Sign in with GitHub as @leonardoMirabal to claim it.

Download v0.9.7

frodhes-0.9.7.fwsc· 598 KB· +5 files

GPL-3.0· leonardoMirabal/frodhes·leonardomirabal.github.io/frodhes/·downloads come from the creator’s GitHub releases

466 commits and 9 releases in the last year
9 releases
  1. v0.9.7Frodhes 0.9.7Latest6 files

    Frodhes 0.9.7: 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.7.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.fwsc
    

    If 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.7

    • Install from the browser: the emulator page installs Frodhes on the FM-1 (Chrome or Edge, MIDI with SysEx): Install on your FM-1, Find my FM-1, then Install. It runs the same update as tools/fm1_install.py, checks the package and its sha256 first, and checks the FM-1's identity after the restart. An install that was cut off gets Resume the install. Safari and Firefox get the terminal installer's command instead.

    Changes

    • The headphone jack keeps the full resolution after MASTER: the volume was applied and then cut to 16 bits, which left a tiny rounding error with a small offset (about -95 dBFS, under the FM-1's own hiss). USB audio is unchanged.
    • The USB name carries the model (GitHub #21): the FM-1 is Frodhes FM-1 on the computer (it was "Frodhes"), an SMK-37 Frodhes SMK-37 Pro (Elite, MKE-P37 likewise). It is the name of the MIDI port, the audio input and the USB device. The community firmware flasher now finds the unit for its DOWNLOAD MODE. Each model has a new USB product id, so the computer sets the unit up as a new device by itself. A Mac asks "Allow accessory to connect?" once (allow it); the DAW then sees a new MIDI device, "Frodhes FM-1", and it has to be selected again (switch its port on once where the old one was). The update mode keeps its name, "Felucca Update".

    Fixed

    • Recording over USB at 48 kHz: a loud, bright passage no longer reaches full scale. The 44.1 to 48 kHz resampler could overshoot a passage the limiter kept at its ceiling and clip one sample; above three quarters of full scale it now softens the overshoot instead. 44.1 kHz and the headphone jack are unchanged.
    • SMK-37 (GitHub #17): the CHORD button opens the CHORD page (press again: chord mode on / off) and PARA opens the PHASER page (again: on / off). They were the other way round. Their lights and the screen's hints follow.
    • A held note dying away no longer leaves a faint, fixed distortion under it (GitHub #16): the engines' mix is dithered where it is cut to 16 bits, so its last few bits fall into a steady noise floor (about -96 dBFS, under the headphone jack's own hiss) instead of odd harmonics that stay put while the note fades. Silence is still exact digital zero. Every engine (Rhodes, VIBES, MARIMBA).
    • F11 RESO SWEEP is as loud as the other Rhodes presets: it was about 1.7 LU under F01 (over the 1.5 LU the factory presets keep). Its LEVEL goes up by 1.5 dB; nothing else in it changes.
    • Recording over USB: when the FM-1's USB controller did not answer one status read in time, the audio input could drop one packet of sound (about 1 ms) with no counter showing it. The packet now waits for the next poll instead, and the event is counted (CC 116 item 21). Found by reading the code, not heard in testing.

    Tools

    • tools/fm1_install.py: "FM-1 not found" now suggests naming the port (--port NAME). An FM-1 running Frodhes (its port is called "Frodhes" since 0.9.5, now "Frodhes FM-1") is found without --port; the installer of 0.9.4 and before does not know those names, so update with this one.
    • The device tools send on MIDI channel 8 by default (FRODHES_MIDI_CH=1..16 to change it), so they work with the FM-1's MIDI CHANNEL on 8 or on ALL.
    • tools/hil_crackle.py (the USB repeat check of the monkey and the crackle test): 4 or 5 equal frames where the music itself turns slowly are no longer counted as a repeated USB packet; the 44.1 kHz monkey takes that failed on them now pass, and injected copies are still found.
    • tools/hil_monkey.py: at 48 kHz one sample at full scale fails the take (--old-48k for firmware before this one); a passing take with notes that did not sound is kept (silent-<seed>.npz) to look at.
    • tools/release.py never pushes main (it is protected): the release goes in through a pull request, then tools/release.py <version> --after-merge tags it and checks the published files.
    • CI: the emulator's job runs in Playwright's own image, the generators run once, and the host tests run in five jobs at once (make pytest SHARD=K/N, tools/pytest_shard.py).
    • tools/final/hil_cpu_fx.py (the CPU check): a take that fails on CoreAudio's error -10863 ("cannot do in current context", the first take right after an install) before anything is measured runs once more, on a line of its own. The retry is judged like any take; the failed attempt never counts.
    • tools/hil_crackle.py (the USB repeat check of the monkey and the crackle test): a USB copy repeats the whole stereo frame, so every channel must show it. One channel's evidence alone (a mono passage, or the other channel at its turn) needs 18 dB, and 4 or more equal frames need the wave clearly smoother without them. The host build's own music no longer fails the check, and neither does the FM-1 take it failed (a plateau of the music, every counter clean).
    • tools/hil_monkey.py: a take that fails an audio check is triaged in the same run. The host build plays the same seed and is judged the same way, then one line in the report: HOST TOO (the test or the music), COUNTED (a device counter explains it) or DEVICE ONLY (the event and the counters). The host render is kept next to the take.
    • tools/hil_monkey.py, tools/hil_usb_bench.py and each step of tools/final/run_final_rev.sh record the computer's load before and after: a busy computer starves the recorder.
    • tools/final/run_final_rev.sh: VIBES and MARIMBA get the key-velocity gate's 5-run follow-up after a 3-run FAIL, as the Rhodes does; the 5 runs decide.
    • tools/hil_must.py and tools/hil_cpu.py read the new counter; the gate wants it at 0.

    Tested

    • Host: tests/py/test_uac_fir.py (the firmware's resampler bit for bit against its reference with the knee; a loud 9.5-11 kHz passage at the limiter's ceiling clips without it and not with it), Gate R (every render unchanged).
    • FM-1: tools/hil_monkey.py at 48 kHz, 25 takes: 0 samples at full scale (the gate now fails on one); tools/hil_cpu.py --worst --usb 48000, 3 runs per engine: the whole audio interrupt at most 4016 us.
    • Host: tests/py/test_master_click.py (the MASTER code from platform.c at four knob positions, with USB VOL fixed and following: within one 24-bit step of the exact product, no offset), tests/py/test_isr_tail.py.
    • FM-1: the jack's idle floor as 0.9.6 (-92.5 dBFS): unchanged where the hiss dominates.
    • Host: tests/py/test_smk_app.py (the buttons' matrix codes, their LEDs and the hints), make test-smk; the FM-1 build is byte for byte the same with and without the change. Not on an SMK-37 (none here).
    • Host: tests/py/test_dither.py (a held Rhodes A2: its 3rd and 5th harmonics at the noise floor where they stood at -117 dBFS before; exact zero before and after a note on every engine, SPREAD on); every render's baseline re-saved on purpose (tools/gate_r.py).
    • FM-1: tools/cpu_check.sh, 4 cases of 4 (VIBES at most 4052 us for the whole audio interrupt); the reverb SIZE swept under VIBES with every effect on, at most 4120 us (INFINITE) and 4140 us (PLATE).
    • Host: tests/usb_desc_test.c and tests/py/test_usb_desc.py (the FM-1, the FM-1 without USB audio, the three SMK-37 models and the update loader: product id and name); the installers' tests (terminal and web) find and update a unit on either name. The sound is unchanged: every render byte for byte the same (tools/gate_r.py).
    • Host: tools/hil_scan.py --host --only presets (F11 -1.5 LU re F01 before, +0.0 now), tests/py/test_hil_limits.py; tests/py/test_cpu_gate.py (the -10863 retry); Gate R (no render uses F11: every render unchanged).
    • Host: tests/uac_seq_test.c and tests/py/test_uac_seq.py run the firmware's own 44.1 kHz USB audio path frame by frame for 36 simulated hours (130 million packets, the host's timing jitter, skipped and missing frames, the timer interrupting the audio at every point that matters): no frame repeated or lost without a counter. A planted one-frame copy is caught; a timed-out status read now loses nothing, where the previous release lost the packet.
    • Host: the repeat check finds 0 events on 800 host takes (7 before); of 1-5-frame copies injected at random it finds 1498 of 1880 (1492 before) and 1530 of 1878 on takes not used to tune it (1524 before); its self-test finds every injected glitch. Every render byte for byte the same (tools/gate_r.py).

    Full manual: https://github.com/leonardoMirabal/frodhes/blob/main/docs/MANUAL.md · Built on Dinghy. GPL-3.0.

  2. v0.9.6Frodhes 0.9.66 files

    Frodhes 0.9.6: 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.6.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.fwsc
    

    If anything goes wrong, switch the FM-1 off, hold OCT− and switch it on to get the USB rescue, then install again.

    Changes

    • The manual: the SCALE page's MODE and TRANSP act on the FM-1's own keys; notes from USB-MIDI and the TRS jack play as sent (a DIATONIC / DIA 7TH chord still takes its root onto the scale, from any source).
    • TREM/WAH: on WAH the SHAPE card shows "-" (it does nothing there and keeps its value for TREM and PAN).
    • The manual: the compressor woken from OFF keeps the volume of what you play about the same (a quiet, dying tail comes up, as under any compressor).
    • The browser emulator is published with every release, at the same moment, and shows the version it runs (in the title, the heading, the footer and on the emulated screen).
    • The emulator's knobs turn more evenly: a trackpad swipe or a mouse wheel notch moves them a step or two (a gentle swipe used to jump about 30 steps), and a drag moves one step every 10 pixels.
    • The manual: DELAY MIX also lowers the dry sound a little (−1 dB at the middle, −6 dB at the top), as it always did; REVERB MIX moves in small steps (DECAY and TONE glide); the drive types match the drive off on played phrases, and how a held chord's tail and single notes compare.
    • OCT− and OCT+ together go back to octave 0: hold one and press the other (GitHub issue #15). The first button still steps the octave as before; letting go steps nothing. The same on the SMK-37.
    • Where Frodhes keeps its data: only in flash that no region of the stock firmware's own table uses. The FM-1: the settings and the 16 user presets are one record in two copies (0xFC000, 0xFD000), the pattern at 0xFE000. The SMK-37: 0xEB000-0xF3FFF (the record, the pattern and the update staging), nothing of the stock settings area 0x9D000-0xBFFFF any more (no owner-tag clear). Going back to stock now finds the stock settings as they were.
    • The first start after the update copies 0.9.5's settings, user presets (every slot, every older preset format) and pattern once to the new places, the pattern first and the record last; a power cut before the end repeats the copy at the next start. 0.9.5's sectors are read, never written.
    • A user preset SAVE writes the record (settings and presets) to the copy not in use, then reads it back: a power cut during a SAVE keeps every preset as it was before it.
    • Going back to 0.9.5: it reads its presets and pattern from its old places, as they were when this version was installed (presets saved since are not there). Its settings: as they were, or its defaults once this version has saved twice (0.9.5 does not read the new record). The new record stays, unless 0.9.5 writes over both copies.
    • COMPRESSOR: turning THRESH up from OFF starts it at −16 dB (the presets' setting) with the +2.8 dB make-up, so it comes on at about the same volume (it started at −0.3 dB with the make-up: 2.8 dB louder); CC 106 does the same when THRESHOLD is 0 (it came on without the make-up), and keeps a THRESHOLD already sent with CC 107.

    Fixed

    • With the arpeggiator holding 16 notes (for example the sequencer's pattern feeding it), a new note replaces the oldest one instead of being lost (0.9.5 did the same).

    • A note played while every voice is busy is never lost: a stolen voice that died away during its steal fade, or more new notes in one audio block than voices, dropped the new note (every engine).

    • Moving these under ringing notes, echoes or a reverb tail no longer clicks, steps or bends:

      • the Rhodes TYPE (a short crossfade);
      • REVERB MIX turned down (the tail rang up to 6 dB louder at MIX 0);
      • REVERB MOD (HALL, INFINITE);
      • REVERB SIZE on PLATE and INFINITE (the old size fades into the new one in 0.13 s on PLATE, 0.19 s on INFINITE; it stepped and bent);
      • DRIVE AMOUNT on FDRV and KHLON;
      • TREM <-> WAH;
      • DELAY EFFECT DIG <-> ANA (a crossfade);
      • DELAY TIME on DIG (the old and the new time crossfade) and on ANA (it bends gently, as tape does);
      • a synced delay following a new tempo;
      • the WAH's RATE (the resonance);
      • TAPE's TONE;
      • FX (all effects off) with SPREAD on;
      • LEVEL with FX off;
      • the MASTER knob (it stepped once per audio block).
    • PERFORM: turning the DELAY or TREM/WAH knob up from OFF switches on the type you last used, not the first one.

    • PLATE: a very hot input (the compressor's full make-up into the plate) no longer overflows its input filter.

    • Touch WAH: a very hot input (the compressor's full make-up, the pedal) no longer overflows its filter.

    • A SAVE, and the settings' save, with the drive's KHLON and the tremolo on (as F06 with TREM) waited for ever: the output was silent, but a tiny idle residue under the silence gate never counted as quiet. Saves go through now.

    • SMK-37: the mod wheel adds TREM/WAH depth (VIBES: motor depth) on top of the DEPTH you set, and gives it back at rest. It used to set DEPTH itself, so at rest the effect was on at depth 0 and the preset's DEPTH was lost. What it switched on, it switches off again at rest.

    • SMK-37: the pitch wheel takes its centre once the reading holds still, and widens its range only to what it holds. A spike on the analog inputs (a jack going in, power-on) could leave a bend on or make a full travel bend only a little, until the next power-on.

    • A power-on whose last preset slot is empty now plays the saved sound with its synced LFO and delay rates running. They stayed at zero until the next tempo or rate change, while the panel showed them set.

    • REVERB INFINITE and PLATE: turning MIX no longer bends the pitch of the tail. With SIZE on AUTO, MIX also set the size of the space, and a size change stretches a ringing tail (a held tone went 50 to 250 cents flat while MIX moved). On INFINITE, AUTO is now a fixed 5.0 and MIX sets only the level. On PLATE the AUTO size waits while a tail rings and follows MIX again once the plate is silent, so the presets sound as before. HALL is unchanged.

    • Turning the volume no longer clicks on the jack (SMK-37 K1 in particular; USB was never affected).

    • PHASER: it keeps the level at every DEPTH. At a low DEPTH (0, the default, and up to about 48) the sweep sat still in the middle of the sound as a fixed notch: a chord came out about 4 dB quieter and a single A4 almost 8 dB. Below the middle of DEPTH the sweep now moves up as it narrows (to the top of its range at 0), and the phaser's level follows DEPTH so a chord's loudness matches the phaser switched off everywhere (within 0.1 LU on the host). Turning DEPTH glides, without a zipper.

    • CHORUS: the bass stays full. The chorus' short delay cancelled part of the lowest notes (C2 about 10 dB quieter at DEPTH 64); the chorus now leaves everything below about 200 Hz as it is, and its level is a little steadier across DEPTH (a chord within about 1 dB of the chorus off).

    • CHORUS: turning DEPTH no longer zippers (the delay tap jumped and the mix stepped with each step of the knob).

    • DELAY: turning MIX no longer steps the echoes' level (DIG, ANA and TAPE): it now glides sample by sample.

    • Loading a preset while a chord or a tail rings no longer clicks: the effects it switches fade over instead of switching in one sample, and the Rhodes TYPE crossfades.

    • FILTER: RESO glides; a jump of the cutoff (a MIDI CC 74 jump, a preset) moves at most 1/8 octave a step, so a band-pass no longer clicks and rings over; one TYPE to another crossfades on the running filter instead of passing through the dry sound (HP12 -> HP18 jumped about 21 dB).

    • PHASER: DEPTH and FEEDBK glide; its sweep keeps time while the phaser is off, so it comes back in step.

    • SMK-37 (GitHub #14): MASTER (K1) is kept across power cycles. It goes into the settings record (an append-only field, the record's version unchanged), saved with the other settings 2 s after the last turn and only in silence, never once a detent; at power-on it is back before the first sound. A record from before, or one without the value, starts at the old level (724 of 1023). The FM-1 is unchanged.

    • SMK-37 (GitHub #13): the SUSTAIN pad and REC share one latch. A tap on either switches the sustain you hear on or off, holding either one works as a pedal and letting go releases the latch, and a MIDI pedal let up (CC 64) releases it too. Before, each kept its own latch: REC could not let go of a sustain the pad had latched, nor the other way round.

    • An update from 0.9.5 takes in what 0.9.5 saved (settings, user presets, the pattern), also after going back to 0.9.5 and up again: whatever 0.9.5 saved since the last time is taken in again, and only that.

    • Switching effects under a held chord no longer clicks: PHASER and CHORUS on / off, the WAH on / off, the COMPRESSOR on / off, every FILTER TYPE change and OFF, DRIVE AMOUNT to 0 and back: each fades over about 46 ms with the effect still running (as the drive's and the delay's switches always did).

    • LEVEL glides instead of stepping at each detent.

    Tools

    • CI builds the emulator on every pull request and runs its selftest in Chromium and WebKit; the release workflow builds it from the tag, tests it, and publishes the release only once GitHub Pages serves it.
    • tools/control_sweep.py: every control (115 of them) swept and moved under a ringing chord, judged for clicks (against the same render without the move), zipper, level jumps, pitch and stuck states; tests/py/test_manual_claims.py checks the manual's promises of glides and steady levels the same way.
    • tools/monkey.py: seeded random play on the host (notes, the pedal, knobs, buttons, presets, MIDI), with checks for lost notes, clicks, overflows (sanitizer builds), silence after all notes off, never louder after the key-up, and settings that survive a power cycle; failures are shrunk to a few events. --focus-xfade aims at the controls with a crossfade, --shed N adds the overload's voice shedding. tools/hil_monkey.py plays the same streams on the FM-1 and judges the USB recording with the glitch detector.
    • tools/coverage.sh (with coverage_sum.py): line and condition coverage of the host tests.
    • tools/hil_usb_bench.py: a bench build (APP_DEFS=-DFELUCCA_UAC_TONE=1 or 2, never in a normal build) that sends a known wave through the USB audio path, to tell a lost or repeated USB frame from the music.
    • tools/hil_crackle.py: a repeated-frame event is counted only where the wave around it is predictable and well over the music's own quiet plateaus (fewer false alarms on noisy music; real copies are still found).

    Tested

    • Host: tests/scripts/arp_full.txt (the arpeggiator fed past 16 notes: the newest note plays, the oldest leaves), Gate R (the new script's render added; every other render unchanged).
    • Host: tests/py/test_steal_race.py, tests/py/test_switch_clicks.py (the cases above; each fails on 0.9.5), tests/py/test_control_sweep.py (REVERB SIZE on PLATE and INFINITE: no bend, no click), tests/py/test_delay_time_change.py, tests/py/test_overflows.py (under ASan + UBSan), tests/py/test_monkey.py, tests/py/test_persistence.py (a save with KHLON + TREM, then a power cycle; a record naming an empty slot), tests/scripts/perform_wake.txt, scale_midi.txt, wah_shape.txt, quiet_gated.txt, tests/smk/wheels.txt and wheel_pedal.txt (make test-smk; the pedal plugged in at power-on, a spike as it goes in), tests/smk_wheel_test.c, the control sweep (tools/control_sweep.py) and the manual's claims with their expected failures removed, make test, make pytest, Gate R.
    • Host: a held 440 Hz tone in INFINITE FREEZE with MIX swept from 64 to 120: the tail stays within 0.2 cents of the same take with MIX held (it was up to 180 cents flat); the same on a ringing PLATE tail (it was up to 188 cents flat). INFINITE on AUTO renders the same as SIZE 5.0, sample for sample; PLATE on AUTO with MIX changed while silent renders as the fixed size, and every HALL and PLATE render is unchanged (Gate R).
    • Host: tests/py/test_master_click.py (the platform's MASTER pass on the app's output, single detents and fast spins at low, mid and full volume: the largest second difference within 1.5x of the same audio at a steady gain; 0.9.5's pass 5-28x).
    • Host: tests/py/test_mix_levels.py (the chorus DEPTH, phaser DEPTH and delay MIX zipper, the chorus' bass and level, the phaser's level at every DEPTH, the chorus' pitch while DEPTH moves; it fails on the code before), make test, make pytest, Gate R (re-saved: the chorus and phaser renders move on purpose), ./build.sh.
    • Host: tests/scripts/oct_reset.txt (both orders, from either end, single presses still step; fails on 0.9.5) on the FM-1 and the SMK-37 builds, make test, make test-smk.
    • Host: preset loads under a held, pedalled chord (F01 to F02, F06, F07, F09, F11 and F12, F07 / F09 to F01, F11 to F19): the largest second difference around the load 0.8-6.5x the same chord without it (the click limit is 10x); the control sweep's FILTER and PHASER cases.
    • Host: tests/py/test_smk_host.py (turned, saved, switched off and on: the same level; an old record: 724; K1 turned every 500 ms for 5 s: no flash write while it turns, one settings save 2 s after the last detent), tests/smk/encoders.txt (K1's detents reach MASTER), make test-smk, make test; the FM-1 firmware is byte for byte the same (sha256 of the fwsc before and after).
    • Host: tests/smk/sus_shared.txt (both orders, holds, CC 64, a note ringing and released), tests/smk/pedal.txt, make test-smk, make test; the FM-1 firmware is byte for byte the same (sha256 of the fwsc before and after).
    • Host: tests/set_ab_test.c (FM-1 and SMK-37: a power cut at every call of a save and of the migration's commit, three ways, from every start; the copies alternating; a save plus a power cycle; the flash model fails the test on any write outside the store), tests/smk_flash_test.c, tests/py/test_store_migration.py (a full 0.9.5 bank in v3, v2 and v1 format, every field compared; no old data; a corrupt bank; a migration cut two ways; the SMK-37 only under its owner tag), tests/py/test_persistence.py, tests/py/test_smk_host.py, make test, make test-smk.
    • Not tested on hardware:
      • The FM-1 from V15: the update staging stays at 0xE0000 (the end of V15's settings area, which its factory settings leave erased; 0.9.5 and Felucca staged there too). Whether V15's own updater stages exactly there is not proven. From V16 (no V15 settings marker at 0x93000) it stages at 0xA9000-0xADFFF, a gap in V16's table.
      • The SMK-37: the staging moved to 0xEF000-0xF3FFF. Where the chip's boot code looks for the update record after a power cut during an install is not known for the SMK-37 (docs/SMK37.md).
      • MKE-P37: every install erases 0x9C000, the first sector of its stock settings area (docs/SMK37.md).
    • Host: tests/py/test_store_migration.py (up from 0.9.5, back to 0.9.5 with a save there, up again: the setup and the pattern 0.9.5 saved come back; what 0.9.5 did not change stays), tests/py/test_hil_store_migration.py.
    • Host: tests/py/test_switch_clicks.py, a differential click check (the largest second difference around the change against the same render without it, under 10x; the old ones were 14-307x), and the compressor's wake level.

    Full manual: https://github.com/leonardoMirabal/frodhes/blob/main/docs/MANUAL.md · Built on Dinghy. GPL-3.0.

  3. v0.9.5Frodhes 0.9.56 files

    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.fwsc
    

    If 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.
    • 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) and frodhes-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.
    • 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.py measures with the USB audio streaming (--usb 44100|48000), reads the firmware's own USB counters and fails above 4500 µs; tools/cpu_budget.py predicts 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.sh runs 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.py and tools/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] and make test-smk for 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 by hil_cpu.py as flash_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 (with tests/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.py predicts 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.sh to 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; and test_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.sh to 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.

  4. v0.9.4Frodhes 0.9.42 files

    Frodhes 0.9.4: a physically modelled Fender Rhodes, 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.4.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.fwsc
    

    If 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.4

    • MARIMBA, a concert marimba. A sixth TYPE (ALGORITHM, or K1 on the main page): rosewood bars tuned 1 : 4 : 10, each over its tube, struck by yarn or rubber mallets, computed like the vibraphone (no samples). The low notes ring longer and swell for a moment just after the strike (the long tubes), the top ones are short and dry. Five octaves, C2 to C7, are the real instrument's; every other MIDI note plays too.
      • Its own VOICE pages: VOICE 1/2 STRIKE, MALLET (SOFT, MED, HARD, RUBBER), TUBE, WEIGHT; VOICE 2/2 RING, MUTE, NOISE, TUNE. The main page's middle cards are MALLET and TUBE.
      • MUTE instead of a damper (a marimba has none): your hand at the key-up. 0 lets every note ring out (the MARIMBA presets start there), up stops it sooner. The pedal still holds; All Notes Off stops everything. It is the same setting as VIBES' DAMPER (CC 103), so a sound saved on one keeps its value on the other.
      • No motor: no motor page (SELECT goes from VOICE 2/2 to COMPRESSOR), and the motor's CCs 47–51 change nothing on MARIMBA (they are kept for VIBES).
      • Two new presets: F15 MARIMBA (rings out, a little reverb) and F16 MRMB SOFT (soft yarn, a heavier mallet, more reverb and a little delay). Program change 14 / 15.
      • RING above its middle (64) makes the low notes ring longer, not louder: as RING rises the notes are turned down, the low ones the most (at 127 about 6–9 dB from C2 to G3, 3 dB at C4), so the hardest strike with the loudest mallet and tube still stays just under full scale instead of being squashed by the output limiter. At 64 and under nothing changes.
      • Its level is set 2.5 dB above the Rhodes types, as VIBES, but every strike is held under −0.5 dBFS (the top bars' roll-off and RING's ceiling), so a chord comes out about 1.5 LU under the Rhodes F01 (measured on the FM-1: −1.50 LU on USB, −1.48 on the jack).
    • DISPLAY page (GLO four times): COLOR, the screen's colour, AMBER as before and then 25 pastel hues around the colour wheel, from PEACH through the pinks, violets, blues, cyans and greens to LEMON, GOLD and MANGO; BRIGHTNESS, for a dark room: the screen and every light dimmed together, 10 to 1; LEDS, which keys light (none, the played keys, the played keys and the scale's root keys glowing faintly, or every key lit for playing in the dark, a played key going dark). Kept with the settings. After an update the FM-1 looks as before: AMBER, BRIGHTNESS 10 and ROOTS are 0.9.3's screen and key lights.
    • Notes over MIDI light their keys, from USB and the TRS jack, as the FM-1's own keys do.
    • DISPLAY LEDS: a fifth mode, SCALE, after ALL. As ALL, but only the keys of the scale are lit: the keys, white and black, whose own note is in the scale (SNAP and DEGREE alike). A played scale key goes dark; the keys outside the scale stay dark, also when pressed. With no scale on it looks as ALL. Saved LEDS settings keep their meaning.
    • DISPLAY COLOR: RED, a full red, appended after MANGO (27 steps). Saved COLOR settings keep their colour.

    Changes

    • Settings and user presets saved by 0.9.3 carry over, and the FM-1 comes back on the sound it was left on.
    • MIDI CC 79 (the bar TYPEs): 0–95 selects VIBES as before (0 and 64 included), 96–127 now selects MARIMBA (in 0.9.3 every value selected VIBES). CC 80 still picks the four Rhodes types.
    • 16 factory presets (F01–F16); Program Change 0–15 loads them, 16–31 the user presets U01–U16 as before. The preset number saved by 0.9.3 (14 factory presets) is moved once, so you come back on the same sound.
    • The start screen reads ELECTRIC PIANO + VIBES + MARIMBA.
    • Less flash for the same sound: the bar instruments' pulse-rate table is stored in 16 bits (every value fits, nothing changes in the sound), about 17.6 kB less flash; the image (with the DISPLAY page) is 487,848 B of the 581,564 B available.
    • The developer CCs 9 (the mode cap) and 116's bar replies (112 / 113) work on MARIMBA as on VIBES.
    • MARIMBA's MALLET card: its steps re-spaced between the detents (SOFT, MED, HARD, RUBBER stay where they were), so no key's level jumps at the changes of mallet family; VIBES' MALLET is unchanged.

    Fixed

    • A note held through a TYPE change to another engine (a Rhodes type to VIBES or MARIMBA and back, or VIBES to MARIMBA), whose sound the change fades out, stayed silent when struck again before being let go (a second MIDI note-on, or an FM-1 key on a note MIDI still held). It now plays on the new type. 0.9.3 had this too.
    • Key lights under the sustain pedal: a key let go before the pedal went down no longer lights again when the pedal goes down (its note was only in its silent damped tail, or a MARIMBA bar ringing on). Under the pedal a key stays lit only for a note the pedal holds: one held when the pedal went down, or played while it was down, as long as it still sounds. Rhodes, VIBES and MARIMBA.

    Tools

    • tools/marimba_va.py (Gate VA-M: the marimba's model against its numbers before any C), tools/marimba_scan.py (the host scan, the rolls and stress cases, the musicality checks M1–M7), tools/hil_scan.py --marimba (the FM-1 suites over USB and the jack), tools/hil_cpu.py --engine marimba, tools/mrb_ref_measure.py (numbers only from reference recordings, never copied, played or embedded); tools/gen_bars.py builds both bar types (--vibes-only still writes 0.9.3's header); tools/hil_jack.py: a tail that ends by its own decay is judged at its end, the after-mute check high-passed at 20 Hz.
    • tools/hil_scan.py on MARIMBA: a failing row that matches one of tools/marimba_scan.py's known, user-decided items (KNOWN / KNOWN_CARDS) is reported KNOWN with its reason (listed after the suite's table and in the json), not FAIL; a USB-jack mismatch still flags it.
    • tools/hil_scan.py measures fixed (the sound was right, the measure was not): PHASER SPEED 0 and CHORUS SPEED 0 on a long take against a DEPTH 0 reference (VIBES and MARIMBA), MARIMBA's CHORUS SPEED 50 / 127 by the same band; MARIMBA's NOISE contact by the host gate's measure; MARIMBA's DRIVE TONE read clear of the 44.1 -> 48 kHz resampler's image, and on the jack only above the jack's own harmonic floor; MARIMBA's DELAY DIG vs ANA judged by the tape's wow and flutter in the echoes' timing (a marimba's echoes have too few overtones for ANA's darker loop to show in their spectrum).
    • tools/hil_scan.py's USB recorder: the 13–27 ms "gaps" in long runs' USB recordings were the recorder's own stall (cutting a take copied the whole block log under a lock), not the FM-1; a cut now copies only its own part.
    • tools/bar_scan.py --type 5 scans MARIMBA against its own spec; tools/gen_bars.py --marimba-offset-add DB --out DIR writes an A/B header for listening to another MARIMBA level (never the default tables).
    • tools/manual_shots.py makes the MARIMBA screenshots; the emulator's ?selftest&marimba.
    • tools/release.py's FM-1 step tests MARIMBA too: hil_cpu --engine marimba (<= 4500 us, nothing shed), hil_scan --marimba --source both (the voice suites every row, KNOWN rows passing; the effect suites their clicks, takes, drift, bypass and level rows), hil_jack --engine marimba (the jack connected, the tails' silence gate, the idle floor) and vib_sampleback --engine marimba (Gate VD-M on every key). hil_scan's MARIMBA level row now expects the measured −1.5 LU re the Rhodes (±1).
    • tools/bar_scan.py: the strike windows (and S1's guards) start at the audio block a strike sounds in; S8 / S9 (the cards) are MARIMBA-aware (its short notes); MARIMBA's S10 also measures G3, C4 and E4.

    Tested

    • Host: make test, make pytest (the MARIMBA tests: Gate VA-M, every card and control audible, the scan and the musicality checks, the compatibility with 0.9.3 settings, the held-key fix), every Rhodes and VIBES render byte for byte as in 0.9.3 (tests/baselines/renders.sha256), Gate VB-M (the firmware's MARIMBA against its reference model, 23 cases: held notes from C1 to C8, MUTE, no tube, a roll, the pedal; this caught the top note C8 playing about 5 dB too quietly, fixed before release).
    • FM-1 (the final development build of this branch; the release build is checked again before publishing): tools/hil_cpu.py --worst, nine low notes at full velocity with the pedal and every effect on: 4.1–4.2 ms of the 5.8 ms per audio block on the Rhodes, 3.4 ms on VIBES, 3.4–3.5 ms on MARIMBA, under the 5.0 ms where the voice guard would act. The Rhodes and VIBES scans as for 0.9.3; the MARIMBA scan over USB and the headphone jack (every voice, decay, roll and effect row; the remaining rows are the known, decided items); the jack: hiss and idle floor as the Rhodes', no audible gate on MARIMBA's tails; every key C2–C7 recorded back and compared with the model (pitch, decay, bloom, overtones).

    Full manual: https://github.com/leonardoMirabal/frodhes/blob/main/docs/MANUAL.md · Built on Dinghy. GPL-3.0.

  5. v0.9.3Frodhes 0.9.31 file

    Frodhes 0.9.3: a physically modelled Fender Rhodes and vibraphone for the M-VAVE FM-1. Every note is computed live from the mechanics of the instrument; there are no samples.

    Download: frodhes-0.9.3.fwsc below. Try it first in your browser: https://leonardomirabal.github.io/frodhes/

    Install

    pip install mido python-rtmidi
    python3 tools/fm1_install.py frodhes-0.9.3.fwsc
    

    If 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.3

    • VIBES, a vibraphone. A fifth TYPE (ALGORITHM, or K1 on the main page): aluminium bars struck with mallets, each with its tuned tube, computed like the Rhodes (no samples).
      • VOICE becomes STRIKE, MALLET (soft, yarn, cord, rubber), TUBE, WEIGHT; DECAY becomes RING, DAMPER, NOISE, TUNE.
      • The motor: press LFO, turn K1 to MOTOR (after WAH). LFO again switches it off and on. Rate 0.5–10 Hz, or synced to the tempo.
      • Two new presets: F13 VIBE MOTOR and F14 VIBES DRY (program change 12 / 13; CC 79 picks VIBES).
      • It plays 2.5 dB louder than the Rhodes, so a struck bar doesn't sound weaker or closer to the jack's hiss.
      • The VOICE cards: STRIKE (where the mallet hits), MALLET (SOFT, YARN, CORD, RUBBER), TUBE (the resonator), WEIGHT (the mallet's mass); a harder strike is louder and brighter. DECAY: RING, DAMPER, NOISE (the mallet's tick and the damper's touch), TUNE. The MOTOR page (ON, DEPTH, SPEED, SHAPE; on by itself when the TYPE turns to VIBES, off on its K1 stays off).
    • FILTER with its own LFO (two new pages): OFF, LP12, LP18, HP12, HP18, BP, NOTCH; 30 Hz–16 kHz, resonance, LFO up to ±4 octaves (sine, tri, saw, ramp, square, S&H; free or synced, free or retriggered by each note). PERFORM's K3 is now the filter's cutoff. CC 70–78.
    • Battery in the top line, next to the tempo: three segments (a bolt while USB powers the FM-1). The levels are a first estimate; SETUP's bottom line shows the raw reading.
    • MIDI clock: CLOCK is INT or EXT (the default). On EXT the FM-1 follows clock from USB or TRS, and MIDI Start / Continue start the sequencer, Stop stops it.

    Changes

    • Buttons: PLAY taps the tempo on every page, ARPEGGIO too (start / stop on SEQUENCER only, and only while the arpeggiator is off); the arpeggiator's HOLD is SEL on the ARPEGGIO page and, while the arpeggiator is on, on every page (SEL is DELAY again when it is off). EDIT opens CHORD, and again switches chord mode on / off (lit while on). SEQ goes straight to the SEQUENCER (no CHORD page on the way; lit while it plays). VOICE is reached with SELECT.
    • SEQUENCER moved after LFO in the page order (... CHORD, ARPEGGIO, LFO, SEQUENCER, ASSIGN ...).
    • The FILTER is on by default: LP18, fully open (16 kHz), so PERFORM's K3 closes it straight away. Fully open it does not touch the sound at all (the same as off, to the sample). Your user presets keep what they saved.
    • Page order: PERFORM, FRODHES, VOICE, DECAY, then the effects, TEMPO ... LFO, ASSIGN, SETUP, MIDI. The instrument pages are together; ASSIGN moved next to SETUP.
    • A new screen look: larger, anti-aliased text, every value the same size. A card tells its kind at a glance: an amount is a fader that fills with warm amber, a selector lights one block per option up to its choice, an ON / OFF switch shows a lit dot. The VOICE pages follow the engine (VOICE 1-2 on the Rhodes, VOICE 1-3 on VIBES).
    • Factory presets level-matched: F01–F12 all play at about F01's loudness, so browsing doesn't jump in volume.
    • The touch wah keeps its level: a closed wah on a high chord no longer drops by up to 14 dB, and a low one no longer gets louder. It only colours the sound now.
    • The CHORUS and PHASER SPEED cards show the rate that actually plays, 0.25–6 Hz (they showed twice the rate; the sound is the same).
    • The first boot (or settings that can't be read) plays F01 STAGE 77, as the header says. It used to play bare defaults.
    • PHASER no longer jumps in level when switched on: the bass is no longer lifted (the mix is lower, the feedback no longer resonates on the bass, and a low shelf keeps low notes at their level: measured with a loudness model, never more than about one audible step louder) and its two sides are 30° apart instead of 90°, so a mono sound does not suddenly turn very wide. It sounds a little different (closer to the middle, the low notes no longer boosted).
    • DRIVE and REVERB have their own pages (DRIVE after FILTER: ON, AMOUNT, TONE, MIX; REVERB the last effect: MIX, DECAY, TONE, PRE-DELAY; CC 82–84, 92–94). The main page's middle cards belong to the engine: TONE / BELL on the Rhodes (DRIVE and REVERB moved to their pages), MALLET / MOTOR on VIBES.
    • Presets: 64 parameters per preset (96-byte records); banks saved by 0.9.2 load and are converted.
    • 9 voices instead of 8, on the Rhodes and on VIBES: a 10th note takes over the quietest released one. The cheaper engine pays for it: nine low notes at full velocity with the pedal and every effect on take about 4.0-4.2 ms of the 5.8 ms per audio block on the Rhodes, 3.5 ms on VIBES (measured on the FM-1), and no note is cut.
    • The audio engine is much cheaper: the Rhodes' worst audio block went from 4.99 ms to 3.6 ms (of 5.8 ms), VIBES from 3.4 to 3.1 ms (the motor fix made it a little cheaper), with the Rhodes sound bit-identical (the Rhodes voice loops and the effects rewritten; checked on the host and by recordings on the FM-1).
    • The battery shows in the header (the last item, right of the tempo), with a bolt on USB power.
    • The PHASER and CHORUS run at full precision: the phaser added a faint broadband noise (about 55 dB under the note), heard as air and "more volume" when switched on.

    Fixes

    • DRIVE was barely audible (a single note never reached the clipping); its top half now really drives (low settings, as the presets use, are unchanged).
    • The DELAY's echoes came out weaker under the chorus or phaser; they keep their level now.
    • The DELAY at high MIX x FEEDBACK grew forever (to the limiter); its loop gain is now under 1 at any setting.
    • LFO SYNC set over MIDI (CC 77) kept the free rate.
    • PRESETS turned past the last saved user preset jumped back to F14.
    • CHORD INVERSION 3RD on a three-note chord played the 2ND again; it is the root position an octave up.
    • The compressor's THRESH card showed "-0"; the manual described COMP ATTACK backwards and listed a COLOR setting that does not exist.
    • All Notes Off (CC 123 / 120) left notes whose note-off got lost "held": that note was then dead and the arpeggiator kept playing it.
    • A burst of more than 32 notes at once (a DAW sending a big chord, a fast pattern) lost the rest: missing or stuck notes.
    • The tremolo's SHAPE above 1.4 made the gain chatter (F12 AM TREMOLO too).
    • The cards round their numbers instead of cutting them (1.486 s showed 1.4S, now 1.5S; +11.8 dB showed +11, now +12).
    • A Rhodes note whose voice was taken over at the moment it was released could keep sounding (stuck).
    • VIBES: with the MOTOR on, a held note grew louder over the seconds and switching the motor off under a chord jumped up; the level and the ring are now the same with the motor on or off.
    • After undoing a preset load (hold SAVE) the header still named the preset just loaded.
    • All Notes Off right after a note played while every voice was busy could leave that note stuck (Rhodes and VIBES); and a low Rhodes note could keep ringing very quietly (about -80 dBFS) for up to 40 s after a panic. After All Notes Off every tail now ends within 8 s.
    • The CHORUS fed a very hot signal (big loud chords on a loud TYPE, about twice full scale before the limiter) could overflow and put out a full-scale crack of the wrong sign; it now stays exact.

    Full manual: https://github.com/leonardoMirabal/frodhes/blob/main/docs/MANUAL.md · Built on Dinghy. GPL-3.0.

  6. v0.9.2Frodhes 0.9.21 file

    Frodhes 0.9.2: a physically modelled Fender Rhodes electric piano for the M-VAVE FM-1. Every note is computed live from the mechanics of a Rhodes (hammer, tine, tonebar, pickup); there are no samples.

    Download: frodhes-0.9.2.fwsc below. Try it first in your browser: https://leonardomirabal.github.io/frodhes/ (new look, with every button labelled)

    Install

    pip install mido python-rtmidi
    python3 tools/fm1_install.py frodhes-0.9.2.fwsc
    

    If 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.2

    • ENV opens the PHASER (press again: on / off; the light shows it) and SEL opens the DELAY (press again: on / off).
    • The compressor's THRESH is its switch: OFF at 0, turn it up and the compressor comes on, with makeup gain that keeps the volume the same.
    • Chorus, decay and the compressor are reached with SELECT (chorus and delay can also be brought in from the PERFORM knobs).
    • The web emulator looks like the FM-1, every button and knob is labelled with what it does, and the labels follow the page (for example PLAY = HOLD on the arpeggiator page). A short guide sits beside it.

    Full manual: https://github.com/leonardoMirabal/frodhes/blob/main/docs/MANUAL.md · Built on Dinghy. GPL-3.0.

  7. v0.9.1Frodhes 0.9.11 file

    Frodhes 0.9.1: a physically modelled Fender Rhodes electric piano for the M-VAVE FM-1. Every note is computed live from the mechanics of a Rhodes (hammer, tine, tonebar, pickup); there are no samples.

    Download: frodhes-0.9.1.fwsc below. Try it first in your browser: https://leonardomirabal.github.io/frodhes/

    Install

    pip install mido python-rtmidi
    python3 tools/fm1_install.py frodhes-0.9.1.fwsc
    

    If 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.1

    • TRS MIDI In (#1): the FM-1's 3.5 mm TRS MIDI input works, for DAWless setups. Notes, CCs, program changes and MIDI clock come in exactly as over USB.
    • MIDI page (press GLO three times): CHANNEL (ALL or 1–16, for USB and TRS alike; the FM-1 sends its notes on it), TRS IN on / off, CLOCK.
    • Sequencer, a pattern recorder on the SEQ button:
      • Play notes or chords and they loop over 1–16 bars.
      • QUANT (off to 1/16T) and SWING apply as the pattern plays, so you can change them at any time.
      • Record live with overdub, or step by step while it's stopped: notes go on the cursor's step, and holding the keys while turning ALGORITHM makes them longer.
      • UNDO the last pass, ERASE by holding keys, DELETE a step, or hold SEQ to clear everything.
      • The screen shows what plays now and next in big letters, plus the bar as 16 cells. ALGORITHM moves step by step and PRESETS bar by bar.
    • Chord mode (CHORD page, SEQ button): one key plays a chord. Use DIATONIC to follow the SCALE page, or pick a fixed shape (MAJ, MIN7, SUS4…), with inversion, voicing and strum.
    • The phaser is now reached with SELECT (or its PERFORM knob), as the SEQ button opens CHORD and SEQUENCER.

    Full manual: https://github.com/leonardoMirabal/frodhes/blob/main/docs/MANUAL.md · Built on Dinghy. GPL-3.0.

  8. v0.9.0Frodhes 0.9.01 file

    Frodhes 0.9.0: a physically modelled Fender Rhodes electric piano for the M-VAVE FM-1. Every note is computed live from the mechanics of a Rhodes (hammer, tine, tonebar, pickup); there are no samples.

    Download: frodhes-0.9.0.fwsc below. Try it first in your browser: https://leonardomirabal.github.io/frodhes/

    Install

    pip install mido python-rtmidi
    python3 tools/fm1_install.py frodhes-0.9.0.fwsc
    

    If 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

    • PERFORM, the new first page: four knobs for playing. By default they are the dry / wet of trem/wah, phaser, chorus and delay, and turning one up switches that effect on. On the ASSIGN page you choose what each knob plays (27 choices). HOME switches between PERFORM and the main page.
    • Arpeggiator on the ARP button: up, down, up-down, as played or random; 1/4 to 1/32 locked to the tempo (tap tempo and MIDI clock too); 1 to 4 octaves; gate. PLAY on its page switches HOLD, which keeps the arpeggio going after you let go of the keys.
    • Compressor gain-reduction meter, like a hardware compressor's.
    • Scales: SNAP now moves a note to the nearest scale note, and the root's keys glow dimly so you can find the keynote.
    • Big chords keep every note: 8-note chords no longer lose notes.
    • Headphones: the volume no longer flutters when headphones are plugged in. A new USB VOL setting on SETUP keeps the USB audio at full level whatever the MASTER knob does.
    • A start screen, and the main page is titled FRODHES.

    The DELAY page is now reached with SELECT (or from its PERFORM knob), since ARP opens the arpeggiator.

    Full manual: https://github.com/leonardoMirabal/frodhes/blob/main/docs/MANUAL.md · Built on Dinghy. GPL-3.0.

  9. v0.8.1Frodhes 0.8.11 file

    Frodhes 0.8.1: a physically modelled Fender Rhodes electric piano for the M-VAVE FM-1. Every note is computed live from the mechanics of a Rhodes (hammer, tine, tonebar, pickup); there are no samples.

    Download: frodhes-0.8.1.fwsc below (package identity FM-1_958).

    Try it first in your browser: https://leonardomirabal.github.io/frodhes/

    Install

    pip install mido python-rtmidi
    python3 tools/fm1_install.py frodhes-0.8.1.fwsc
    

    If anything goes wrong, switch the FM-1 off, hold OCT− and switch it on to get the USB rescue, then install again.

    What's in it

    • Four instrument types: Stage 77, Suitcase, Early Felt, Bell Dyno. The tone, bark, bell, hammer, decay, release and noise are all adjustable.
    • Effects: compressor, drive, tremolo / auto-pan / wah, phaser, chorus, delay (digital / analog) and reverb. Each effect keeps about the same volume when you switch it on, and FX switches all of them off and on at once.
    • The compressor has 4 knobs (threshold, ratio, attack, makeup) and new in 0.8.1: a gain-reduction meter on its page, like a hardware compressor.
    • A look-ahead limiter, so big chords stay clean on the USB audio and the headphone jack alike.
    • Tap tempo with MIDI clock sync, scales (snap / degree), a sustain pedal on REC, and 12 factory plus 16 user presets.
    • One page per section, with four cards for the four knobs. See the manual.

    Built on Dinghy. GPL-3.0.