A software M-VAVE FM-1: a Standalone app and VST3/AU plugin that plays the FM-1's FM engine, edits every sound setting, runs its sequencer and arpeggiator, and syncs presets and patterns with the hardware, much as Yamaha's Expanded Softsynth Plugin does with the Montage M and MODX M. Pull or push the preset you're playing, send an edit to the synth without saving it, or sync the whole 128-preset library in either direction.
Each instance is set to one of the FM-1's firmwares: M-VAVE's own, baud girl's FM-1+VA, Felucca, Hügelton's multi-engine firmware, SLOOP, isod89's groovebox built on Felucca, or Melodee, Kerem Kilic's multi-engine firmware built on Felucca. The plugin runs Felucca, SLOOP and Melodee from their own source, with their screen, front panel, sequencer and projects. It also plays FM1 Open, M-VAVE's own open firmware, from its source, and pulls from and sends to an FM-1 running it (no Live), and ChoralRoot, Quixotic7's chord instrument built from Felucca, from its source, syncing its backup with an FM-1 running it.
It works on its own as a synth too; the FM-1 is only needed for syncing.
Not affiliated with M-VAVE, baud girl or Hügelton Instruments. Use at your own risk.
The library beside a preset's FM page (FM-1+VA):
Felucca: its user presets and projects beside a part's sound, and its own front panel:
At phone size (the iOS app builds from source):
- macOS 11 or later (Apple Silicon or Intel), Windows 10/11 (64-bit) or Linux (x86-64, built on Ubuntu 24.04; X11 and ALSA).
- To sync with a synth: an M-VAVE FM-1 on USB running baud girl's FM-1+VA firmware (101; 0.97, 0.96, 0.93 and 0.94 too), Felucca 1.6.1 (1.6 too, untried; 1.0 to 1.5.1 pulled from only; one on 1.0.3 syncs with an instance set to Felucca 1.0.3), SLOOP 2.7 (2.6 too, without Live; 2.3 to 2.5 pulled from only) or Melodee 1.4.1 (1.4.0 synced as 1.4.1, untried; its Synth only build is not supported; 0.12 to 1.3.6 pulled from only; one on 0.13 or 1.1.0 syncs with an instance set to that release) or ChoralRoot 0.23 (0.24-beta1 synced as 0.23; its backup only) or M-VAVE's FM1 Open V12 (pull and send, no Live). On M-VAVE's own firmware the plugin still plays and edits sounds, but cannot read anything back from the synth.
Download the installer for your system from the Releases page.
- macOS: open
Virtual-FM-1-…-macOS.pkg. The Installation Type step lists the Standalone app, the VST3 plugin and the Audio Unit plugin, all ticked; untick any you don't want. The installer is not signed yet, so macOS will say it cannot verify it: open System Settings › Privacy & Security and click Open Anyway. - Windows: run
Virtual-FM-1-…-Windows.exeand choose the Standalone app and/or the VST3 plugin. Windows SmartScreen may warn about an unknown publisher: click More info › Run anyway. - Linux: unpack
Virtual-FM-1-…-Linux-x86_64.tar.gzand run./install.shfor your own account, orsudo ./install.sh --systemfor everyone. It installs the Standalone app, the VST3 and the LV2; leave any out with--no-app,--no-vst3or--no-lv2../uninstall.shremoves them. Syncing with an FM-1 on Linux has not been tested with the hardware yet.
Then rescan plugins in your host. It appears as Virtual FM-1 by Bockage. Logic needs a restart to pick up a new Audio Unit.
- Connect the FM-1 with USB and switch it on. The Standalone app finds it by itself; in a plugin, click Find FM-1 (or pick its MIDI ports and Connect). The line beside it shows the synth's firmware and version. Set the firmware menu at the top to the one your FM-1 runs.
- Pull all 128 (Library tab, Sync page) copies the synth's presets into
the plugin. The library is shared by the Standalone and every plugin
instance in every host, so you do this once. Until then it holds the stock
presets: M-VAVE's, with baud girl's VA packs in D01-D32. Import loads
either stock bank again (every slot; the library as it was goes to its
.trashfolder first). - Pick a preset in the list to play it. Pull what the FM-1 is playing loads the synth's current sound, unsaved changes included.
- Edit in the FM (or VA) and Effects & Envelope pages beside the list. Changes stay unsaved until Store, as on the FM-1; Revert drops them.
- Send to FM-1 plays your sound on the synth without saving it there; Live (top bar) sends every change as you make it. Store to FM-1 saves the preset on the synth. Push changed writes every preset that differs.
- The Sequencer tab pulls and pushes patterns; Arpeggiator works like the FM-1's. Both follow your host's tempo and transport. Settings holds the pitch-bend range, the MIDI channel the plugin plays, the on-screen keyboard's velocity and Hardware character (the FM-1's 16-bit output and softer high end), saved with the project, with Save as default for new instances.
- Export... saves presets as JSON: one, a group (Shift- or Cmd-click the
list), a bank, all 128, or everything with the patterns. The Sequencer
tab's Export... saves one pattern or all 16, as JSON or as a MIDI
file. Import... reads them back,
.syxfiles too, and puts a MIDI file's notes into the selected pattern.
Every sound setting is a host parameter, so it can be automated, and a host project saves its own current preset, edits, patterns and arpeggiator.
- Engine: the same FM engine the FM-1 uses (Google's msfa, the core of Dexed), 12 voices, matched to the hardware where it was measured: pitch, per-preset transpose, velocity response, detune and LFO speed.
- FM Editor in Dexed's layout: six operators, algorithm diagram, pitch envelope, LFO.
- Effects and envelope: the FM-1's filter, reverb, delay, distortion, chorus and phaser in each preset's chain order, its global ADSR, and the per-note filter FM presets gained in FM-1_092. Settings sync exactly; the effects' sound is an approximation of the firmware's.
- Sequencer: 16 patterns of up to 64 steps, up to nine notes a step, ratchet, chance, gate, transpose, accent, Tie & Slide per step and per note, per-pattern Chain, swing, step recording and real-time recording.
- Arpeggiator: Up, Down, Inclusive, Exclusive, Random, Order and Repeat over 1 to 4 octaves.
- Sync: identify, pull and push one preset or all 128, push only what
changed, send unsaved edits, show a preset on the synth,
.syximport and export (FM-1+VA backups, DX7 banks and voices). - JSON presets and patterns: a readable, editable format for backups and
for writing sounds and patterns by hand or by script, with a JSON Schema
editors can check against. See
docs/JSON-FORMAT.md. - MIDI out: what the sequencer and arpeggiator play leaves the plugin as MIDI, so a host can route it to the synth as well.
- Felucca 1.6.1, built from its source: its thirteen engines on four parts, each part's parameters in an editor and as host parameters. Its Library tab lists the 32 user presets and four projects to load, save, rename and erase; its Device tab shows its own screen, buttons, knobs and keys, so its sequencer, projects and user presets work as on the device. Its projects and user presets are kept in the library as the file Felucca's web editor uses for backups. With an FM-1 running Felucca 1.6.1: pull everything, send everything, or keep both in step live (tried with an FM-1 on 1.6.1); the Sequencer tab carries steps' ratchets, nudges and conditions, parameter locks and songs with a slot per track. Felucca 1.0.3 stays beside it, its own firmware choice, for the projects made with it: a project saved with 1.0.x opens on it, and it syncs fully with an FM-1 still on 1.0.3.
- SLOOP 2.7, built from its source the same way: its twelve engines (FM6,
PHYS and NOISE among them) on three parts and a drum track, each with its
INSERT, in the same editor and as host parameters, Library and Device tabs.
Its projects, user presets, FM6 bank, SYN drum kits and MIDI setup are kept in
the library as the file SLOOP's web editor uses for backups
(
SLOOP/SLOOP device.json). With an FM-1 running SLOOP 2.7: pull, send and live, as with Felucca; one on 2.3 to 2.5, which cannot read 2.6's projects, is pulled from only. - Melodee 1.4.1, built from its source the same way: its engines on four
parts, PROPHET (with Sequential's Prophet-5 factory programs), CZ-1 (with
Casio's CZ-1 tones), FM6, SID (with its C64 models) and the 808, 909, SID KIT
and SID DIGI DRUM kits, three insert effects and three sends on each part into
a shared return of three effects, each with its TONE, its 32 pattern banks, in
the same editor and as host parameters, Library and Device tabs. Its projects,
its shared U001-U384 preset bank and its settings are kept in the library as
the file Melodee's web editor uses for backups (
Melodee/Melodee device.json; one from 1.3 is taken and its preset banks moved into the shared bank, as the FM-1 does it). With an FM-1 running Melodee 1.4.1: pull, send and live, a part's own CZ-1 tone or PROPHET patch included (tried with an FM-1 on 1.4.1). An FM-1 on 1.3, which cannot read 1.4's projects, is pulled from only. Melodee 0.13 and Melodee 1.1.0 stay beside it, each its own firmware choice, for the projects made with them (1.0 retired 0.13's LOFI, PHASE, VOICE and NOISE; 1.2 removed 1.1's delay, reverb, chorus and slicer): a project saved with one opens on it, and it syncs fully with an FM-1 still on that release. - FM1 Open V12, M-VAVE's own firmware (m-vave/fm1_open),
built from the open source of its browser preview: its eight tracks and six
sound sources (DX7-style FM, 303 bass, 808 drums, PSG, Pluck, the sampler with
its demo samples), its sequencer and its 16 demo projects, played on its own
front panel and screen (the Device view). Its projects are saved with your
host's project. With an FM-1 running FM1 Open V12 (its FM-1 tab): pull or send
the project it plays (and keep it in one of its 16 slots), a track's sound,
a slot loaded and pulled, and its sample bank. The project a Send replaces, and
the sample bank a sample Send replaces, are saved in the library first
(
FM1 Open/Backups, as.fm1and.fm1sfiles M-VAVE's workbench imports); what a slot held before a Send saves into it is not kept. A sample Send cannot be stopped once writing starts (FM1 Open erases its bank first). No Live: FM1 Open has no message for one value changed, and a sound sent whole would cut what plays. Tried with an FM-1 running V12: Pull, Send, a track's sound, the slots' names and the sample bank (saving into a slot not yet). - ChoralRoot 0.23, Quixotic7's chord instrument built from Felucca
(Quixotic7/ChoralRootFM1),
built from its source as its own emulator builds it: played on its own front
panel and screen (the Device tab). Its Sync page pulls from and sends to an
FM-1 running it what its backup carries (the sound pool, favourites, loop
slots, CZ-1 banks and FM6 bank; each side keeps its settings), the FM-1's own
backed up to the library first (
ChoralRoot/Backups), and restarts it after a Send as its own page does. While it restarts it leaves USB: the app connects to it again by itself, a plugin when asked (Find FM-1). Its stored objects are kept in the file its page uses for backups (ChoralRoot/ChoralRoot device.json). Tried with an FM-1 running 0.23.
- Virtual Analog presets sync but play through the FM engine. baud girl has announced her firmware's source; the VA engine waits for it.
- Some settings have no MIDI control on the synth (the FM filter, distortion type, effect order), so they reach it only with Store to FM-1.
- Ties, ratchet, chance and accent stay in the plugin; how the synth stores them is not known yet. Per-pattern Chain can be read from the synth but not written.
- Knob assignments and mono/glide are kept as stored but not edited.
- AAX (Pro Tools) is planned; see
docs/AAX.md. - iPad and iPhone: the app and AUv3 build from source and sync with the
FM-1 over USB-C, but are not distributed; see
docs/IOS.md. - Felucca and SLOOP: their user sample slots are empty.
- Melodee: its Sequencer tab edits, pulls and sends the pattern bank each part plays (the Sync page's Pull and Send carry all of them).
- FM1 Open: no Live with an FM-1 running it, no host parameters, and its clock is its own (not the host's tempo); its sample bank is its demo bank until one is pulled from an FM-1. It runs the code of M-VAVE's browser preview, whose sound M-VAVE says may differ from the device's.
- ChoralRoot: its protocol has only its backup, so no host parameters, Live, sound copies or patterns; what it plays now (its session) is not saved with the host's project.
docs/FIRMWARE-GAPS.md lists each gap and what to
look for in baud girl's source once it is published.
Requires CMake 3.22+, a C++20 compiler and Ninja on macOS (brew install cmake ninja), or Visual Studio 2022 on Windows. The Felucca, SLOOP and Melodee
engines need Clang and Python 3 (on Linux, configure with CC=clang CXX=clang++; on Windows, Visual Studio's ClangCL toolset: cmake -B build -G "Visual Studio 17 2022" -A x64 -T ClangCL, with "C++ Clang tools for Windows"
installed); built without them, the plugin leaves them out. JUCE 9.0.3 is a submodule:
git clone --recurse-submodules https://github.com/jbschooley/Virtual-FM-1
cd Virtual-FM-1
cmake -B build -G Ninja -DCMAKE_BUILD_TYPE=Release
cmake --build build
ctest --test-dir build
The plugins are copied into your user plug-in folders after building
(-DFM1_COPY_PLUGIN=OFF to skip). scripts/package-macos.sh and
scripts/installer.iss build the installers. CI builds, tests and packages
on macOS, Windows and Linux for a version tag (making a draft release), or
when started by hand. docs/CONTRIBUTING.md explains
the tests and the rules for working with a real FM-1;
docs/ADDING-A-FIRMWARE.md how the firmwares fit
in and how to add one.
Source layout:
core/the MIDI link, the sync session and the firmware profile interfacefirmwares/the firmware list and each firmware's releases (Firmwares.cpp), and one folder per firmware:fm1_common/the FM-1 protocols stock and FM-1+VA share (no JUCE),fm1_stock/,baudgirl_fm1va/, andfelucca/(its profile and its sync over its editor protocol, Felucca's, SLOOP's and Melodee's)engines/the sound, without JUCE:dx7/msfa (Apache-2.0, from Dexed; changes inengines/dx7/msfa/NOTICE.md) and the voice, envelope and filter code around it;fm1_fx/the FM-1's effects, the Hardware character stage and the rate converter;felucca/,sloop/,melodee/andchoralroot/Felucca's, SLOOP's, Melodee's and ChoralRoot's firmware (GPL-3.0, vendored, see theirUPSTREAM.md) built as librariesplugin/the processor, editor, parameters, library, sequencer and arpeggiator, and Felucca's editor, host parameters and device file;plugin/dexed_ui/Dexed's look-and-feel and panelstests/seedocs/CONTRIBUTING.md;fm1_probeis the command-line check against a real FM-1docs/contributing, adding a firmware, hardware notes, firmware gaps, AAX plan, iOS, JSON format and a shared protocol proposal for FM-1 firmwares
- baud girl for the FM-1+VA firmware, whose read-back protocol makes two-way sync possible.
- Leo Kuroshita (Hügelton Instruments) for Felucca, which the plugin builds from its source with its author's agreement, its sample pack included.
- isod89 for SLOOP, which the plugin also builds from its source.
- Kerem Kilic for Melodee, which the plugin also builds from its source.
- Quixotic7 for ChoralRoot, which the plugin also builds from its source.
- Google's music-synthesizer-for-android (msfa) and Dexed by Pascal Gauthier and contributors, for the FM engine and the editor's look.
- Reverse-engineering work on the FM-1 by AL-255, ip2k, aroum and kagaimiq.
- Built with JUCE.
GPL-3.0-or-later (see LICENSE). Third-party code and its licenses are listed
in THIRD_PARTY.md: msfa is Apache-2.0, the Dexed UI parts
are GPL-3.0-or-later, Felucca, SLOOP, Melodee and ChoralRoot are GPL-3.0-only, JUCE is used under the AGPLv3 and the VST3 SDK is under
the MIT licence. Melodee and ChoralRoot include Casio's CZ-1 tones and Sequential's Prophet-5
programs as sound data, with no licence granted; see THIRD_PARTY.md.



