FSVR, Formant Synthesizer Virtual Rack, is a software reconstruction of the Yamaha FS1R as a plugin and a console synth: its firmware logic rewritten in C++ from the decompiled ROM, four parts, 32 channels, the filter, both LFOs, pan, the three effect blocks, performances and Fseq playback. CLAP, VST3, VST2 and standalone on Windows, macOS and Linux, an AU on macOS and a 32-bit VST2 with a DXi on Windows, with an editor for every parameter the unit has, a bank manager for your own .syx libraries and Import Audio for Fseqs.
Download the latest build: https://github.com/musicastudio/FSVR/releases/latest (no installer, no dependencies).
Licensed GPL-3, see LICENSE and NOTICE.md.
Discord: https://discord.gg/6sXu3GmkNm
The tone generator, the filter, the CPU-side firmware logic and everything that feeds them now match rgwan's FS1R inside the measurement, file by file. The one thing left is the effects layer, VOP3-2: its 87 algorithms are still modelled from the Data List rather than measured. See FS1R vs FSVR.
FS1R Hardware Recording
fs1r_demo02_hardware.mp4
FSVR (v0.4.2)
fs1r_demo02_engine.mp4
FS1R Hardware Recording
fs1r_demo01_hardware.mp4
FSVR (v0.4.2)
fs1r_demo01_engine.mp4
In 2025 Zhiyuan Wan (rgwan) created the rgwan/fs1r_firmware_RE repository to study the hardware and software on the Yamaha FS1R synthesizer. That project extracted the SH7044's 256 KB internal flash through a hooked UART, dumped the 2 MB external EPROM, dumped the PLG150-DX ROM, captured the board's UART traffic, and published a Ghidra project with the boot, loader, flash and LCD code already named.
The progress of this work was shared on the yamahamusicians.com forum.
Just over a year later in September 2026, James Hansen (jameshansen) created this repository, after analyzing and attempting to create the FS1R in software based on the material in rgwan's repository using a custom approach where the firmware files were decompiled with Ghidra into a database that can be read and explored by a coding AI agent.
Today, jameshansen and rgwan are collaborating on this project to improve the accuracy of the engine and bring it as close to the FS1R as possible.
AI coding agents and frontier LLMs have played a large role in making this project possible. The initial recreation was created using Claude Fable 5.1, with much of the ongoing analysis and engine improvements being assisted with Claude Opus 5. As part of the collaborative process, developers on the project can now use these tools via Discord.
The current largest missing feature is true recreation of the effects and filters. We have approximations but we are working on improving the accuracy. This is the key difference in sound between the real unit and FSVR.
- A patched firmware has been created to poke memory on a real FS1R to read registers and values.
- The AN1x and PL150-AN run the AN engine on a VOP3. The EX5 keyboard runs the exact same AN engine on a MB91103PF (Fujitsu FR20), which is understood and documented. This is our "rosetta stone" helping us to understand the VOP3 code.
- The AI Coding Agent now has realtime access to an FS1R running the patched firmware, able to continuously work to understand the VOP3.
Where it stands, 2026-09-24: everything but the effects is done. Against rgwan's unit the synthesis engine matches close to 1:1. Every constant that models the two custom chips is measured off a recording or a register session rather than guessed, and every file in the 38-file capture set outside the three effect files sits inside the measurement: the amplitude EG, the formant window and its skirt on all seven forms, the noise formant, FM and feedback, detune, the velocity law, the per-voice filter and its EG, LFO1 and LFO2, pan and the output stage. The one remaining gap is VOP3-2, the effects DSP: reverb, variation, insertion and the master EQ are modelled from the Data List and read 17 to 29 dB against real impulse responses. Until that chip's program is decoded or its blocks measured against a register session, a performance with its effects on will differ from the unit in its reverb and effect tails and nothing else. docs/fidelity_plan.md has the numbers per file.
The FS1R (1998) is Yamaha's formant-shaping FM synth: 8 operators per voice, 32 channels, four parts, and a second oscillator type that generates a formant with a shaped spectral window instead of a sine. Its tone generator is the YMP706, a QFP128 part used in exactly two products, the FS1R and the PLG150-DX board. There is no public register documentation for it and no emulation of it anywhere.
FSVR is a rewrite of that logic, not an emulation of the processors on the board. The SH7044 is not emulated and its firmware does not run here. tools/build_fs1r_ghidra.py imports the EPROM into Ghidra as SH-2 and decompiles it, and the note-on path, the tick pipeline, the parameter conversion tables and the 88-algorithm routing table are read straight out of that code and ported to C++. The two custom chips cannot be treated that way, since nobody has register semantics for the YMP706 or an instruction set for the YSS236, so they are models, and every constant behind them sits in src/fs1r/chips/cal.h where calibrating against a recording of a real unit is one table edit.
Three words carry the status of each piece below. Read is lifted out of the decompiled firmware, its tables or the board, and needs no calibration. Measured is a model whose constants came off a recording of rgwan's unit rather than off a guess. Modelled is inferred from the DX7 lineage, Yamaha's formant synthesis patent (US5610354) or the Data List, and marked INFERRED in the source.
The practical result is that patches, performances and Fseqs load and play with the same parameter interpretation the hardware uses, because the same logic computes them. What still differs from a real unit lives inside the two custom chips.
A short list of places FSVR behaves differently on purpose is kept in docs/Differences.md, with the firmware address behind each one where there is one. The engine has one entry: a part's filter switch is live here, so turning the filter on or off reaches the notes already sounding, where the unit latches that switch per note at note-on and only its cutoff and resonance follow a held note. The rest are the plug-in's additions, things the unit never had: user libraries without the unit's memory limits and Import Audio.
-
SH7044 CPU, SH-2 at 28 MHz with 256 KB of internal flash. Read, and verified against the unit. The firmware's logic is rewritten in C++: the note-on path, the 192.3 Hz MTU2 tick, the CMT1 Fseq frame timer and every conversion table. rgwan ran a debug monitor over the whole capture set on 2026-09-18 and read the voice image back segment by segment, so the CPU side is checked byte for byte, 240,476 checks over 802 segments with no mismatch. Running the real firmware on an emulated SH-2 core (gearmulator has one with the SH7040 peripherals) stays on the list as a second opinion, not as a replacement.
-
YMP706-F tone generators, two of them, 16 channels each on an 8-bit write-only bus. CPU side read, chip side modelled and largely measured. There is no register documentation and no die shot, and the chip is too rare for one, so it stays a model. Everything the CPU computes for it is read from the firmware: all 88 algorithms, the DX7 VCED and ACED conversion, frequency words, EG rate and level conversion, velocity curves and attenuation, level key scaling, EG bias, note shifts, part detune, master tune, bend, the software pitch EG, LFO1 and LFO2, portamento, the mono modes with priorities and legato, note and velocity limits, part volume, expression and balance, and pan. What the chip does with those values breaks down as follows.
- The amplitude EG. Measured. The rate law holds to 0.6 % over 38 measured rates and the level register is 0.376287 dB a step, a halving every sixteen. The attack's shape, its floor, the hold's length and the key rate scaling were all DX7 guesses and all wrong until two envelope recordings settled them; shape error over a hundred segments went from 5.45 dB rms to 0.58. The key code law is a table measured at every one of its 37 key codes, and the hold does not scale with it. docs/aeg.md.
- FM, feedback and the modulation index. Measured. 3.369 cycles at full level, off two sideband sweeps and confirmed by
03_fm's own spectra; feedback is0.5 * 2^(fb - 7). - Detune. Read, and it needs no constant at all. It is not a fixed step but the EPROM's own key scaled
FRMDETtable, matched over six octaves to half a cent, which took a vibrato off demo song 2 that the unit does not have. docs/detune.md. - The voiced formant window. Measured. The window is a time set by the bandwidth byte, the skirt doubles a
sin^pexponent per step, and there are two window shapes: symmetric onall2,odd2andres2, asin^prise on asin^2fall onall1,odd1,res1and the formant.all1andall2are that window alone, read by phase. All six harmonic forms land inside 0.5 to 1.8 dB of the unit's line amplitudes at every skirt, and the formant's skirt sweep at 0.44 dB of band shape. docs/skirt.md, docs/formant.md. - The noise formant, the unvoiced operator. Measured, 2026-09-21 and 2026-09-22. Two digital one-poles with different coefficients on white noise, both read off the register and the skirt at three centres, a two-sample mean on the output, a level table and a threshold resonance. Level error over the four unvoiced files is 0.2 to 1.05 dB and the octave bands agree inside 0.5 dB to 16 kHz. The resonance carrier's amplitude and the noise it cuts are read against the register at four settings (2026-09-24). docs/noise.md.
- Amplitude modulation sensitivity. Measured: the chip's AM word is seven bits and the sensitivity is a 3-bit shift-and-add, {0,1,2,4,5,6,7,8}/8.
- Which write starts a note. Unknown. 0xFC/0xFD goes out before the registers load and nothing says what the chip makes of it.
-
YSS236-F / VOP3-1, the per-voice filter, at 0x800200. CPU side read, response measured. Yamaha's VOP3 is the same programmable DSP that is the synthesis engine of the AN1x, AN200 and PLG150-AN; the FS1R has two, and this one sits in a channel-level loop off both tone generators. The CPU's whole side of it is read out of the firmware: sixteen filter channels mapped to parts, a dirty flag per parameter group, and closed-form conversions for cutoff, resonance, type and input gain. The response is measured off
15_filter: the corner is17.4 * 2^(byte / 12)to 0.098 octaves rms, the three lowpasses are taps off one 4-pole ladder whose feedback goes as the cube of resonance table A, and HPF, BPF and BEF a 2-pole state-variable filter, 24, 18, 12 and 12 dB per octave to a decibel. The filter EG is stepped segment by segment by the CPU and run by the chip; its rate law came off the CPU's own stage word over the debug monitor and its depth scale off one recording.tools/extract_vop3.pyhas the microcode out intodocs/vop3/, register by register, but the instruction set is undecoded. -
YSS236-F / VOP3-2, the effects, at 0x800000. Parameter encoding read, algorithms modelled. The one remaining gap in the engine. Reverb (17 types), variation (29), insertion (41) and the master EQ in the XG topology, with the part dry and send levels and the insertion switch, in
src/fs1r/chips/vop3_effects.h. The parameter encoding is read rather than guessed, recovered out of the 360 preset performances and matching every documented default. The 87 algorithms themselves are modelled from the Data List, and were measured against real impulse responses for the first time on 2026-09-21, at 16.9, 27.2 and 28.8 dB over eighty-four segments, in a set where most files agree with the unit inside half a decibel.tools/extract_vop3_2.pyhas that chip's two images out intodocs/vop3_2/. Decoding the VOP3 instruction set is the only route to bit-exact effects and a bit-exact filter; it is open research on the scale of a full DSP core, and the modelled effects ship regardless. -
The board around them. Read. One 24.576 MHz crystal runs the audio side and the main Sanyo LC78834M DAC is the I2S master at exactly 48 kHz, so the engine runs at 48 kHz whatever the host rate and resamples on the way out. The recording tap is that DAC's I2S input, after both DSPs and before the analogue volume pot, which is what makes a recording's absolute level comparable. The output path's fixed gain, the hard clip on the channel accumulator and the filter loop's insertion loss are all numbers off that tap.
docs/research.md2.0.1 and section 8 have the clocking and the CS2 decode.
All read from the firmware and its tables, and all finished.
- Factory data. The 1408 preset voices, 384 performances and 90 formant sequences out of the EPROM, plus the voice (608 bytes), performance (400), Fseq and system bulk layouts and the DX7 VCED and ACED maps. Extracted into
presets/and built into the plugin, so the patch browser needs no EPROM image. The unit'sInternal Perform BankandInternal Voice Bankare copies its factory set routines make from the presets into NVRAM, so FSVR has no fixed internal banks; the plug-in keeps a user library of .syx files instead, as many performances, voices and Fseqs as you import or store. - Fseq playback. Frame timing on its own timer, every loop mode with the direction the loop points imply, the start offset, the performance start delay, scratch mode from controller destination 47, MIDI clock sync at all five speed ratios, and the voice Fseq switches.
- Controller sets. The whole matrix out of three firmware functions: the source bit order, the bipolar and raw source conversions, the clamped sum, the three scalers and which of the 48 destinations uses each, the per-part gate, and the destinations that edit a part byte instead of contributing an offset. The voice's own Formant and FM control matrix with it.
- MIDI and sysex. The whole parameter map in both directions, bulk dumps and parameter changes in and out, dump and parameter requests answered with checksummed replies, RPN 0-2, the ten NRPN 01 xx part parameters, bank select and program change in both performance and multi modes, MIDI clock and active sensing.
Against rgwan's digital recording of the built-in demo, which the unit plays from its own EPROM so the same byte stream drives both, with the effects in the path on both sides: median envelope correlation 0.976, worst 0.912, mean band error 5.0 dB and tilt 2.0 dB. Against the 38 frozen capture files, twenty-seven agree with the unit inside half a decibel of level; the velocity law, the EG decay to a level, the modulator chain and the second and third links of it are inside a tenth, and the eleven that do not are the three effect files, two whose number is a scoring artifact below 100 Hz, two at frame and LFO rates the analyzer cannot align, two at 1.2 and 1.7 dB, and the two session-4 files whose level column measures a decay window and an 8 kHz noise offset rather than a level.
Nothing in cal.h is a guess any more, and nothing outside the effects is open. The last three modelling items closed on 2026-09-24 off data already recorded: the window family behind the "1" forms and the formant, the all1/all2 construction, and the key code table at the demo drum's note; the fourth hardware session the same day then read that table at every semitone, found the EG hold does not scale with it, and read the unvoiced resonance carrier against the bandwidth register. docs/fidelity_plan.md has the per-file table; STATUS.md carries the KNOWN / INFERRED / UNKNOWN lists and the open work; FS1R.unlock/captures/fs1r_capture_session4.py holds the one register dump still to run, the per-channel arrays, which the engine is not waiting on.
Known issue: performances that layer two parts of a voice with all eight unvoiced operators live (A020 Vox Morph is the extreme) are heavy, about half a desktop core at 8 notes and more than a laptop i7 has to give. docs/performance.md has the measurements and the fixes in order of cost.
What is left is the effects layer, VOP3-2: 87 algorithms modelled from the Data List, 17 to 29 dB against real impulse responses over eighty-four segments. It is a rebuild of each block from the microcode or a measurement of each against a register session, and it is the last piece. Tiers 0 to 3 and 5 are done, so the engine, the library and console split, the plugin in every format with its editor, the licence and CI are all in, and Tier 4, fidelity and verification, is complete outside the effects.
The latest release, also on musica.studio, has an installer for Windows, macOS and Linux that puts every format in place, and each format as its own zip, FSVR-<OS>-<format>.zip: CLAP, VST3, VST2 and standalone everywhere, an AU for Logic Pro on macOS, and on Windows FSVR-Windows-VST2-32-DXi.zip, a 32-bit VST2 carrying a DXi (Cakewalk's older plug-in format, registered with regsvr32). The macOS builds are universal, Apple silicon and Intel in one binary. No dependencies. docs/plugin_guide.md is the user guide.
Every push to main builds the same set through GitHub Actions, so a build for an OS you do not own is always one Actions run away, including on a fork. .github/workflows/build.yml is four jobs:
- engine, on
windows-latest,ubuntu-latestandmacos-latest. Plain CMake with no downloads, thenctest, which runs the effect and engine self checks everywhere. UploadsFSVR-console-windows. - plugin, on Windows x64, Windows x86, Linux and macOS. Installs the X11, ALSA, JACK and PulseAudio headers on Linux, configures with
-DFSVR_BUILD_PLUGIN=ON, runs the plug-in's own checks (check_plugin,check_gui) on the 64-bit legs, and uploadsFSVR-plugin-windows,FSVR-plugin-windows-x86,FSVR-plugin-linuxandFSVR-plugin-macos, each holding every format for that platform. - installer, on Linux. Checks out musicastudio/Installer, packs the plug-in artifacts into it and builds
FSVR-Windows-Installer.exe,FSVR-MacOS-Installer.zip,FSVR-Linux-InstallerandFSVR-MacOS-Update(the bare binary the macOS updater runs), at the version inCMakeLists.txt. - release, on a
v*tag only. Splits the plug-in artifacts into one zip per format, named as FM8.plus names its own (FSVR-Windows-VST2-64.zip,FSVR-Windows-VST2-32-DXi.zip,FSVR-MacOS-AU.zipand so on), adds the installers, the console andSHA256SUMS.txt, and attaches them to a GitHub release. The installers' updater never reads GitHub: musica.studio mirrors each release and serves the update from there.
CMake 3.24 or later everywhere, C++17. The engine, the console and the self checks need no dependencies:
cmake -B build/cmake -S . # fs1rLib, test_effects, bin/render_capture, and bin/fsvr_console on Windows
cmake --build build/cmake --config Release
ctest --test-dir build/cmake -C Release # the self checksThe plug-in adds one flag. Its first configure downloads the CLAP SDK and clap-wrapper, which fetches the VST3 and AU SDKs, RtAudio and RtMidi, and Import Audio's decoders (dr_libs and stb_vorbis), so it needs the network once:
cmake -B build/plugin -S . -DFSVR_BUILD_PLUGIN=ON
cmake --build build/plugin --config Release
ctest --test-dir build/plugin -C Release -R plugin # the plug-in's own checkOn Linux install libx11-dev libasound2-dev libjack-jackd2-dev libpulse-dev pkg-config first (Debian and Ubuntu names). On Windows a second build with -A Win32 makes the 32-bit VST2 with the DXi in it.
Every format lands in a folder of its own under bin/: bin/CLAP, bin/VST3, bin/VST2 and bin/Standalone, bin/AU on macOS, which is the only plugin format Logic Pro loads, and bin/VST2 32-bit and DXi from the 32-bit build. The 1408 factory voices, the 384 factory performances and the 90 preset formant sequences are built into the plugin, so its browser needs no EPROM image.
On Windows build.bat is the shortcut, MSVC x64 out of the VS 2022 Professional vcvars64:
build.bat bin\fsvr_console.exe, the console
build.bat test build and run the self checks
build.bat plugin every plug-in format, 64-bit and 32-bit, then check_plugin and check_guiEverything meant to be run lands in bin/; objects and the test binaries go to build/.
bin/fsvr_console is the test harness on top of the engine library. It is Windows only, since it uses WinMM for MIDI and waveOut for audio, but its offline render path needs no devices at all.
fsvr_console -l list MIDI ports
fsvr_console asks for a MIDI input once, remembers it in bin\fsvr_console.ini
fsvr_console -m 0 -o 0 -v presets\native\000_Ballad_EP.syx
fsvr_console -v presets\dx7\004_Pianotone1.syx DX7-format presets, converted the way the firmware does
fsvr_console -r <eprom.bin> -p 128 ROM voice, 0-255 native and 256-1407 the DX7 banks
fsvr_console -r <eprom.bin> -P 0 ROM performance 0-383 with its voices and Fseq
fsvr_console -r <eprom.bin> -P 0 -f 29 override the Fseq with preset Fseq 1-90
fsvr_console -v presets\native\128_BagPipe.syx -w test.wav -n 60 -d 3 offline render, no devices neededOptions. -m MIDI input, -o MIDI output for dump and parameter replies, -c force all parts onto one MIDI channel (the default is each part on its own receive channel), -v a sysex file holding FS1R voice, performance or Fseq bulk dumps or a DX7 VCED dump, with -p picking the n-th dump in the file, -r a 2 MB EPROM image with -p voice, -P performance and -f Fseq, -g output gain, -w offline render with -n note, -n2 a second note a third of the way in, -cc num=val control changes sent before the note, -d seconds, -mono part 1 mono with full-time portamento, -selftest the engine self check. FS1R_DEBUG=1 prints the computed register values at every note on.
MIDI. Notes, bend, both aftertouches, the control numbers the system table assigns to KN1-4, MC1-4, FC, BC, Formant and FM, CC5/65 portamento, CC7 volume, CC10 pan, CC11 expression, CC64 sustain, CC91/94 sends, CC120/121/123/126/127, RPN 0-2, the ten NRPN 01 xx part parameters, bank select and program change in both performance and multi modes, MIDI clock, active sensing, FS1R bulk dumps and parameter changes across the whole map, and dump and parameter requests answered. The performance's controller sets route the sources to the destinations.
The EPROM image the -r examples take is rgwan's dump with its 16-bit words byte-swapped into CPU order, kept outside this repo in ../FS1R_DISASM/roms/. FSVR does not ship it, and nothing but the -r paths needs it.
python tools/check_wav.py test.wav 60 # pitch, harmonics and envelope of one render
python tools/regress.py # the whole fixed preset list against the stored referenceEngine. No Windows, no host, no GUI. This is what the plugin links. The tree says where a claim comes from, which is the thing to know before changing anything in it.
src/fs1r.hthe public header,fs1r::Device. The only one the plugin includessrc/fs1r/hardware.hthe FS1R's own numbers, read off the board. Facts, never tunedsrc/fs1r/internal.hthe engine's shared declarations, includingstruct Synth
src/fs1r/firmware/ is KNOWN, rewritten from the disassembly, and every claim in it cites a FUN_ address. A disagreement with a real unit is a bug here, not a calibration.
patch.cppvoice, performance and part data as the firmware decodes it, with the DX7 conversioncontrollers.cppthe eight controller sets, the three scalers and the 48 destinationsnotes.cppnote on and off, operator setup, pitch, portamento, and the 192.3 Hz tickfseq.cppformant sequence playback;midi.cppMIDI in and sysex in and out;rom.cppEPROM and sysex loadingtables.hthe EPROM's conversion tables, bytools/extract_tables.py;algorithms.hthe 88-algorithm routing table
src/fs1r/chips/ is INFERRED, because neither custom chip has public register documentation. These are claims about the hardware, changed by measuring against a recording and never by taste.
cal.hthe calibration surface, every modelled constant in one placeymp706.cppthe tone generator: operators, envelopes, the formant window, and the render pathvop3_filter.hVOP3-1's filter;vop3_effects.hVOP3-2's reverb, variation, insertion and master EQ
src/fsvr/ is ours. Nothing in the hardware corresponds to any of it.
tuning.hcost knobs, the control-rate decimation and the queue cap. Changing one must not change the outputfastmath.h,fastmath.cppthe sample loop's sine, 2^x, dB and tanh: a table (the default), CORDIC, a hybrid of the two, or raw libm, chosen byFSVR_MATHdevice.cppfs1r::Device, host-rate resampling and state as bulk dumpssmf.hStandard MIDI File reading;selftest.cppthe engine self checkdisplay.hhow the unit shows values, for editors and displays: fixed operator frequencies, ratios and every effect parameter value, with each effect type's parameter slots. Transcribed from K_Take's FS1R Editor (freeware) and checked against the Data List and the ROMsrc/console/main.cppthe test console: WinMM MIDI in and out, waveOut, offline render
Plugin. The plug-in layer, which never models synthesis; it moves parameter values in and out of the engine as sysex, exactly as a hardware editor would.
plugin/plugin.cppthe processor: every param a sysex parameter change intofs1r::Device, the engine's own bulk dumps read back into the params, program change, the monitor, and the Save and Import menus' and bank manager's requestsplugin/library.cppthe bank manager's data: .syx files as banks (FS1R bulks, DX7 single voices and 32-voice banks), the factory bank and the user library folder;audio_decode.cppandaudio_fseq.cppImport Audioplugin/skin/the editor, a Hollow skin: views, params (params.json, 3,223 of them), images (at 1x inimages/, at 0.5x, 0.75x, 1.5x and 2x inscales/) and its TrueType fonts, anddata/fs1r_sysex.json, the address and packing of every param. This copy is the source: edit it with the web editor of the Hollow project (kept beside this repository, not published), which opens it by default and saves into itblender/the skin's artwork as Blender components (the window's chrome, buttons, panels, displays, glyphs, logos, pots, faders, wheels and keys),blender/scripts/what builds and renders them into the skin at every scale, andblender/textures/the blue mottled chrome they share (docs/editor.md, The art: Blender)plugin/generated/the bundled factory banksfs1r_presets.syxwith its indexfs1r_presets.csv,fs1r_performances.syxandfs1r_fseqs.syx, packed frompresets/bytools/make_presets_blob.py, andparameterDescriptions_fs1r.json, the 893 parameters with their sysex addresses and bit layouts, bytools/gen_parameters.py, which the skin's param table is built fromhollow/the plug-in framework: the formats (CLAP, and through clap-wrapper VST3, AU and the standalone; VST2 and the DXi of its own), the skin runtime and software renderer, and the editor window on Windows, macOS and X11. hollow/docs/skin-format.md is the skin's contract
Tools, firmware.
tools/build_fs1r_ghidra.pyimports and decompiles the firmware into../FS1R_DISASMwith pyghidra (SH-2);decomp.py,ghidra_disasm.py,ghidra_switches.py,ghidra_handlers.pyandghidra_probe.pyquery ittools/ghidra_ctrl_dests.pydecompiles the 48 controller destination handlers, which Ghidra never turns into functions because only a pointer table reaches themtools/extract_tables.py,extract_presets.pyandextract_demo.pypull the conversion tables, the 1408 voices, 384 performances and 90 Fseqs, and the demo songs out of the EPROM imagetools/extract_vop3.pyandextract_vop3_2.pypull the two VOP3 microcode uploads intodocs/vop3/anddocs/vop3_2/
Tools, calibration.
tools/make_capture_set.pywritescaptures/requests/, the hardware capture kit: Standard MIDI Files that play a measurement into a real FS1R, each setting up its own patches by sysex and opening and closing with a marker so a recording aligns itself. Built out oftools/fs1r_patch.py; the othermake_capture_*.pyare the later additions to the settools/analyze_capture.pyaligns a recording to the manifest, measures every segment, fits the constants it can, and diffs the result against our own render of the same file.bin/render_capturemakes that render, which is also how a request file is checked before anyone is asked to play it.tools/bench_captures.pyrebuilds the renderer from the source as it stands and prints one line per file;tools/render_demo.shdoes the same for the demo set and appends to the ledgertools/render_song.py,check_demo.pyanddemo_probe.pyplay the extracted demo songs through the engine and score them against rgwan's recording;demo_scores.txtis the running ledgertools/pitch_track.py,split_capture.pyandanalyze_unvoiced2.pythe per-measurement readers
Tools, checks.
tools/regress.pyrenders the fixed preset list and diffs it againstregress_ref.json: pitch, harmonic peaks, envelope, stereo width, centroidtools/test_effects.cppdecodes and sweeps every effect type, andfsvr_console -selftest(engine_selftestaway from Windows) is the engine check. Both run underctesttools/check_plugin.cppdrives the plug-in's processor the way a host does: factory banks, a saved session, Import SysEx, the bank browser, Import Audio, program change, panic, the monitor, Save to Bank, .fsvr presets, the right-click menus, and the Init Patch and the standalone's Load Last Patch.ctestruns it in a plug-in buildtools/check_gui.cppdrives the editor over the processor without a window, as a mouse and a keyboard would: the top bar's menus and toggles, every page by its tab or button, the operator panel and its waveform, the browser's right-click menus, every dialog, the modal's veil, Escape and close X, the close prompt, the Options page (every scale, both keyboards and each setting) and About, then every page's dials, faders, dropdowns and toggles.ctestruns it as "gui"tools/check_wav.py,check_formant.pyandcheck_presets.py, the rest of whatbuild.bat testruns;check_skirt.pyrenders every harmonic form at every skirt against the register sweep
Data.
presets/the factory voices, performances and Fseqs as.syxwithindex.csv, plus the DX7 bankcaptures/requests/the capture kit as MIDI with a README listing what each file settles,captures/hardware/the recordings that came back,captures/analysis/the per-segment numbers,captures/engine/our own renders of the same files
Docs.
- docs/research.md what is known about the hardware, and docs/ymp706_registers.md the tone generator interface and the CPU-side engine lifted from the firmware. These two are the reference.
- docs/fidelity_plan.md the ranked read of where the engine stands against every recording;
capture_0918.mdandhardware_capture_request.mdare the capture working docs/aeg.md,formant.md,skirt.md,noise.mdanddetune.md, one measurement each, the working behind the constants incaldocs/midi_dispatch.mdhow a Note On, a Control Change and both aftertouches get from the SCI0 interrupt to the tone generator;interface_from_firmware.mdthe unit's screen tables, cursor stops and MIDI View, read out of the EPROMdocs/vop3_microcode.md,vop3_2_microcode.mdandvop3_pinout.mdthe VOP3 reference- docs/Differences.md the short list of places FSVR knowingly behaves differently from the unit, and why
- docs/plugin_guide.md the plugin user guide, and docs/editor.md why the editor is the way it is: which of the unit's limits it drops, the bank manager and what the processor answers for the GUI. The Data List and owner's manual text and the formant patent are here too.
- hollow/docs/ the plug-in framework:
framework.mdhow a product is built on it,skin-format.mdthe skin's contract - STATUS.md what is known, what is modelled and what nobody knows, with the open work at the end
- docs/findings.md the research log, newest first, and the evidence behind each constant