Skip to content

About

A software M-VAVE FM-1: FM synth app and VST3/AU plugin with two-way preset and pattern sync over the FM-1+VA firmware

Topics

Resources

Contributing

Stars

36 stars

Watchers

2 watching

Forks

Repository files navigation

Virtual FM-1

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.

Screenshots

The library beside a preset's FM page (FM-1+VA):

The preset list beside the FM page of the selected preset

Felucca: its user presets and projects beside a part's sound, and its own front panel:

Felucca's Library tab: the user presets beside the Sound page

Felucca's Device tab: its screen on the HOME page, its knobs, buttons and keys

At phone size (the iOS app builds from source):

Felucca's Device and Library tabs at phone size

What you need

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

Install

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.exe and 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.gz and run ./install.sh for your own account, or sudo ./install.sh --system for everyone. It installs the Standalone app, the VST3 and the LV2; leave any out with --no-app, --no-vst3 or --no-lv2. ./uninstall.sh removes 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.

Using it

  1. 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.
  2. 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 .trash folder first).
  3. 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.
  4. 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.
  5. 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.
  6. 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.
  7. 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, .syx files 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.

What's in it

  • 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, .syx import 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 .fm1 and .fm1s files 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.

Not done yet

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

Build

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 interface
  • firmwares/ 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/, and felucca/ (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 in engines/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/ and choralroot/ Felucca's, SLOOP's, Melodee's and ChoralRoot's firmware (GPL-3.0, vendored, see their UPSTREAM.md) built as libraries
  • plugin/ 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 panels
  • tests/ see docs/CONTRIBUTING.md; fm1_probe is the command-line check against a real FM-1
  • docs/ contributing, adding a firmware, hardware notes, firmware gaps, AAX plan, iOS, JSON format and a shared protocol proposal for FM-1 firmwares

Credits

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

License

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.

About

A software M-VAVE FM-1: FM synth app and VST3/AU plugin with two-way preset and pattern sync over the FM-1+VA firmware

Topics

Resources

Contributing

Stars

36 stars

Watchers

2 watching

Forks

Releases

Packages

Contributors

Languages