▄████▄ ██ ██ ██ ██▓███ ██▓███ ▓█████ ██▀███
██▀ ▀█ ▓██ ██ ▓██ ▓██ ██ ▓██ ██ ▓█ ▀ ▓██ ██
▓█ ▄ ██▀▀██ ██ ██ ██ ██ ██ ███ ██ ▄█
▓▓▄ ▄██ ▓█ ██ ██ ██▄█ ██▄█ ▓█ ▄ ██▀▀█▄
▓███▀ ▓█ ██ ██ ██ ██ ████ ██ ██
.oO c h i p t u n e s y n t h c o r e Oo.
Chipper is a multi-chip retro synth VST3 focused on classic game and computer sound chips. The goal is to make chip limitations feel musical: fast presets and readable controls on the surface, with register-aware or emulator-backed behavior underneath.
The project is intentionally honest about accuracy. A mode is only labeled accurate when the implementation and tests justify it. Most modes are currently verified partial or clean-room partial while renderer tests, emulator comparisons, and hardware validation are built out.
- Chip-aware VST3 instrument built with JUCE.
- User-facing controls map to chip-native ideas such as pulse duty, PSG noise modes, SID filter routing, FM algorithms, BRR/DMC sample playback, and wavetable source lanes.
- Factory presets are chip-local and update the visible controls instead of hiding decisions inside opaque macros.
- Every plugin parameter has a fixed MIDI CC mapping for hardware control and Ableton Configure workflows.
- A separate
chipper_rendercommand-line tool renders WAV plus debug JSON for regression tests and emulator validation. - Third-party emulator cores are vendored only after a license/provenance audit.
Each interface screenshot includes a click-to-play MP3 example for GitHub users.
NES / RP2A03![]() Play sample |
Game Boy / DMG![]() Play sample |
SID / C64![]() Play sample |
YM2149 / AY![]() Play sample |
SN76489 / Sega PSG![]() Play sample |
YM2612 / Genesis FM![]() Play sample |
OPL2 / OPL3![]() Play sample |
SNES SPC700-style![]() Play sample |
Atari POKEY![]() Play sample |
PC Engine HuC6280![]() Play sample |
Namco WSG![]() Play sample |
Konami SCC Play sample |
YM2151 / OPM![]() Play sample |
YM2413 / OPLL![]() Play sample |
Amiga Paula![]() Play sample |
Chipper is being developed as an accurate, truthful chip instrument rather than a decorative retro synth. The current product rules are:
- Presets are the primary musical entry point. They should load audible chip-local sounds, update the visible controls, and remain editable/shareable as normal Chipper state.
- The header's Strictness control requests Inspired, Hybrid, or Authentic behavior. It is not an accuracy certificate; the footer and docs carry the actual verification claim. Hosts and MIDI maps may show the same stable parameter as
Behavior Strictness. - Chip-owned controls belong where the hardware owns them: duty under pulse channels, noise mode under noise channels, wave/sample choices and level under each wavetable or sampler lane, filters/echo/sample banks in shared modules.
- Chips without native ADSR use clearly labeled Chipper amp/gate helpers instead of pretending the hardware has full ADSR.
- Fixed regressions stay in tests and release gates. FM held-note fade-out and NES DMC loop-off behavior are currently treated as fixed; if they return, they are regressions, not open design questions.
- UI readability wins over density, but the default editor must remain DAW-friendly. Most chip layouts stay inside the 1240 x 820 editor default; documented chip-specific exceptions may use a taller fixed height when that preserves standard-height controls, visible level lanes, and waveform previews without opening off-screen on typical DAW displays. SID currently uses 1240 x 880 for its per-voice ADSR surface.
The planning docs intentionally separate current execution from broader research so fixed bugs do not keep looking like active product gaps:
- docs/priority-roadmap.md is the ranked execution list for the next high-value slices.
- docs/product-gap-roadmap.md tracks larger instrument workflows such as tracker motion, wave/sample editing, FM operator editing, preset sharing, and release readiness.
- docs/ui-priority-audit.md is the UI non-regression checklist for chip-aware layouts, standard control sizes, and channel-local controls.
- docs/preset-sourcing.md is the factory preset provenance and quality checklist.
- docs/emulation-accuracy.md is the truthful source/verification/license status for each chip.
- docs/release-builds.md owns local install, GitHub release, and release-gate procedure.
Fixed issues such as FM sustained-note fade-out and NES DMC one-shot looping should remain in regression tests and release gates, not in the active feature queue unless they reproduce in the current build. When a fixed issue is suspected, run the named gate first; if it passes, keep planning focused on new user value instead of adding another stale todo. As of the current planning cleanup, those gates are treated as green guardrails and the next work should favor chip-aware editors, preset quality, state recall, and verification evidence.
Implemented depth varies by chip. See docs/emulation-accuracy.md for the source, verification status, known gaps, and license posture of each mode.
| Mode | Current status |
|---|---|
| NES / RP2A03 | Partial clean-room APU with pulse, triangle, noise, DMC file/folder banks, nonlinear mixer, and frame-counter tests |
| NES + VRC6 | Partial clean-room NES expansion mode with VRC6 pulse/saw lanes, seven source strips, Chip Poly allocation, and original expansion presets |
| NES + FDS | Partial clean-room NES expansion mode with one 64-step FDS wavetable/modulation lane, five source strips, Chip Poly allocation, and original FDS presets |
| NES + Sunsoft 5B | Partial clean-room NES expansion mode with three AY-style 5B tone lanes, seven source strips, Chip Poly allocation, and original 5B presets |
| NES + MMC5 | Partial clean-room NES expansion mode with two MMC5 pulse lanes, one conservative PCM/DAC lane, seven source strips, Chip Poly pulse allocation, and original MMC5 presets |
| NES + VRC7 | Verified-partial NES expansion mode with six emu2413-backed VRC7 melodic FM lanes, nine source strips, Chip Poly allocation, and original VRC7 presets |
| Game Boy / DMG | Partial clean-room APU with pulse, wave RAM helpers, noise, envelope/sweep/stereo routing tests |
| SID / C64 | Partial clean-room SID-style voice model with 3 voices, per-voice waves/PW/ADSR, sync/ring bits, filter modes, routing, and model color |
| YM2149 / AY | Verified-partial MIT emu2149 PSG adapter |
| SN76489 / Sega PSG | Verified-partial MIT emu76489 PSG adapter |
| Philips SAA1099 | Partial clean-room stereo PSG model with six tone lanes, dual shared noise generators, envelope groups, source strips, Chip Poly allocation, and original SAA1099 presets |
| PC Speaker | Partial clean-room one-bit PIT channel 2 beeper model with one speaker source lane, port 0x61 gate/data behavior, direct-click SFX, and original PC Speaker presets |
| ZX Spectrum Beeper | Partial clean-room one-bit ULA port FE beeper model with one source lane, EAR/MIC output-bit behavior, border-bit metadata, MIC-click SFX, and original ZX beeper presets |
| YM2612 / Genesis FM | Verified-partial BSD-3-Clause ymfm OPN2 adapter with native LFO Depth and partial channel-6 DAC drum playback |
| YM2203 / OPN | Verified-partial BSD-3-Clause ymfm OPN adapter with three FM lanes plus three embedded SSG tone/noise/envelope lanes |
| YM2608 / OPNA | Verified-partial BSD-3-Clause ymfm OPNA adapter with six FM lanes, three embedded SSG tone/noise/envelope lanes, generated/user-owned ADPCM-A rhythm ROM support, and first-pass encoded ADPCM-B sample memory for Drum/Hit macros; WAV/AIFF conversion and sample editing remain planned |
| YM2610 / OPNB | Verified-partial BSD-3-Clause ymfm OPNB adapter with four FM lanes, three embedded SSG tone/noise/envelope lanes, and first-pass renderer/VST encoded ADPCM-A/B sample memory for Drum/Hit macros; conversion/editing and stronger validation remain planned |
| YM2610B / OPNB2 | Verified-partial BSD-3-Clause ymfm OPNB2 adapter using the YM2610 six-FM channel mask, three embedded SSG tone/noise/envelope lanes, and first-pass renderer/VST encoded ADPCM-A/B sample memory for Drum/Hit macros; conversion/editing and stronger validation remain planned |
| OPL2 / OPL3 | Verified-partial BSD-3-Clause ymfm YMF262/OPL3 adapter with nine visible source cards, native rhythm mode, explicit paired 18-channel OPL3 layer mode, and first-pass $104 4-op Pair mode; dedicated 18-card/four-op editing still planned |
| SNES SPC700-style | Partial clean-room eight-voice BRR/WAV/AIFF sample-player model with note maps, loop handling, Gaussian-style interpolation, PMON-style pitch modulation, noise, and musical echo helper |
| Atari POKEY | Partial clean-room polynomial/timer model |
| Amiga Paula | Partial clean-room tracker-sampler model with file/folder sample banks |
| PC Engine HuC6280 | Partial clean-room wavetable/noise model with six lanes and partial Ch 1/2 FM-LFO pairing |
| Namco arcade WSG | Partial clean-room wavetable model |
| YM2151 / OPM | Verified-partial BSD-3-Clause ymfm OPM adapter with eight lanes, pan, first-pass native LFO Depth, and channel-8 noise control |
| YM2413 / OPLL | Verified-partial MIT emu2413 preset/custom-FM adapter with editable user patch slot 0, native rhythm mode with BD/HH+SD/TOM+CYM source-card mixer labels, and original OPLL presets |
| Konami SCC | Verified-partial MIT emu2212 wavetable adapter |
Requirements:
- CMake 3.22 or newer
- Visual Studio 2019/2022 with the Desktop C++ workload
- Internet access on first configure so CMake can fetch JUCE
Configure and build:
cmake -S . -B build -G "Visual Studio 17 2022" -A x64
cmake --build build --config Release --target Chipper_VST3 chipper_renderThe VST3 bundle is produced at:
build\Chipper_artefacts\Release\VST3\Chipper.vst3
Run the test suite:
ctest --test-dir build -C Release --output-on-failureFor fast regression checks while developing, run the focused renderer/processor smoke tests first:
ctest --test-dir build-codex -C Release -R "chipper_descriptor_smoke|processor_midi_cc_smoke|held_tail|preset_.*held" --output-on-failureThese cover high-risk playable-instrument paths such as NES DMC loop-off behavior and FM sustained-note/key-on regressions before a full suite run. For the FM sustain regression specifically, the CTest names include held_tail and assert renderer tailRms rather than only checking that rendering completed.
GitHub Actions are intentionally quiet on normal branch pushes. The release workflow only runs when you push a v* tag, publish a GitHub Release, or start it manually from the Actions tab.
- Push a tag such as
v0.2.0when you want GitHub to build, test, package, create or update the GitHub Release, and attach Windows, macOS, and Linux VST3 zips. - Tag-created releases are draft/prerelease by default so the artifacts can be downloaded, checksum-verified, and smoke-tested before publishing.
- Publishing a GitHub Release manually for an existing tag also builds and attaches the same platform zips and checksum files.
- Use the manual
Release VST3workflow for private candidate builds, or provide arelease_tagand enableattach_to_releaseto stage assets on a draft/prerelease release. - The zip includes
Chipper.vst3,README.md,THIRD_PARTY_NOTICES.md,CHANGELOG.md, andLICENSEwhen present. - Each zip has a matching
.sha256file using the standardhash filenamechecksum format. - No build cache is configured yet, keeping the workflow simple and avoiding extra artifact/storage churn.
See docs/release-builds.md for the local build sequence, release workflow behavior, install verification, and release gate checklist.
The root installer defaults to a user-scope install, so it does not need UAC:
.\install-vst3.ps1If -BuildRoot and CHIPPER_BUILD_ROOT are not set, the installer auto-selects the newest local VST3 bundle from build-codex or build. Pass -BuildRoot when you want a specific build folder.
For day-to-day development, use this sequence from the repo root:
cmake --build build-codex --config Release --target Chipper_VST3 chipper_render
.\install-vst3.ps1 -Scope User -BuildRoot build-codex
.\install-vst3.ps1 -VerifyOnly -BuildRoot build-codexThe installer prints a source build marker and the installed user/global build markers. The marker shown in Chipper's footer should match the installed marker, for example:
Source build: v0.1.0 b9bfeeb283 (clean, built ...)
Installed build marker: ...\ChipperBuildInfo.txt
If Ableton or another host still shows an older footer hash, close the host and check whether both user and global copies exist:
.\install-vst3.ps1 -VerifyOnly -BuildRoot build-codexWhen the global copy is older, sync both locations from an elevated PowerShell:
.\install-vst3.ps1 -Scope Both -BuildRoot build-codexThis matters because some hosts scan C:\Program Files\Common Files\VST3 before %LOCALAPPDATA%\Programs\Common\VST3, so an old global bundle can shadow the freshly installed user bundle.
By default it installs to:
%LOCALAPPDATA%\Programs\Common\VST3
To install to the global VST3 folder, use an elevated PowerShell:
.\install-vst3.ps1 -Scope GlobalInstaller defaults can be steered with environment variables instead of editing the script:
| Variable | Purpose |
|---|---|
CHIPPER_BUILD_ROOT |
Build folder used by the installer; when unset, the newest local build-codex or build VST3 bundle is selected |
CHIPPER_INSTALL_SCOPE |
User, Global, or Both; default User |
CHIPPER_VST3_DESTINATION |
Explicit destination folder for one-scope installs |
CHIPPER_VST3_USER_DIR |
User-scope VST3 install folder |
CHIPPER_VST3_GLOBAL_DIR |
Global VST3 install folder |
CHIPPER_VST3_FALLBACK_DIR |
Optional fallback folder when fallback installs are enabled |
CHIPPER_VERIFY_INSTALL |
Set to 1, true, or yes to report source/user/global build markers without copying files |
CHIPPER_ALLOW_FALLBACK_INSTALL |
Set to 1, true, or yes to allow fallback copies when the requested destination cannot be replaced |
Examples:
$env:CHIPPER_BUILD_ROOT = "build-debug"
.\install-vst3.ps1.\install-vst3.ps1 -BuildRoot build -Destination "D:\Audio\VST3"For Codex/local development builds, you can still install the explicit build folder:
.\install-vst3.ps1 -Scope User -BuildRoot build-codexTo verify which build a host may be loading without copying files:
.\install-vst3.ps1 -VerifyOnly -BuildRoot build-codexThis prints the source build plus the user and global VST3 install markers. If those markers differ, update both scopes from an elevated PowerShell:
.\install-vst3.ps1 -Scope Both -BuildRoot build-codexThe installer removes the previous Chipper.vst3 bundle before copying the new one, writes a build marker into the installed bundle, and copies third-party legal notices into Contents\Resources\Legal. If a DAW has the plugin loaded, close the host and rerun the installer. If both user and global VST3 copies exist, keep them in sync with an elevated .\install-vst3.ps1 -Scope Both -BuildRoot <your-build-folder> so hosts do not load an older copy.
chipper_render is the verification path for the engine. It accepts chip mode, behavior strictness, note/register events, render length, chip-specific parameters, and outputs WAV plus debug JSON. The command-line flag is still named --accuracy for compatibility with earlier tests and scripts, but it represents the same Inspired/Hybrid/Authentic strictness request shown in the plugin header:
build\Release\chipper_render.exe --chip nes --accuracy authentic --clock 1789773 --rate 48000 --seconds 1 --note 69 --output-db -9 --out nes.wav --debug nes.jsonList factory presets:
build\Release\chipper_render.exe --list-presets --debug presets.json
build\Release\chipper_render.exe --list-presets --chip sid --debug sid-presets.jsonRun the preset QA gate before adding or releasing factory sounds:
cmake --build build --config Release --target Chipper_VST3 chipper_render
.\scripts\verify-presets.ps1The QA gate exports the factory preset catalog, validates chip/category metadata, prints chip-by-chip preset counts, and renders every factory preset to catch silent, clipped, or missing-output sounds before release.
The plugin header includes Load and Save buttons beside the preset browser. User presets are saved as plain .chipperpreset XML files so they can be shared, versioned, and inspected without a DAW-specific preset container.
User preset files store the same Chipper state used by host project recall, including chip mode, behavior strictness, play mode, the selected factory/user preset state, public parameters, register snapshots, and external sample-bank references. They also carry browser metadata such as musical role, chip engine, tags, note text, and source context, so saved presets can participate in the same Role/Engine/Tag filtering and search vocabulary as factory sounds. Audio sample data is not embedded. For portable sharing, put referenced NES DMC, SPC700, or Paula samples next to the preset or in a Samples folder beside it; Chipper will try those relative locations before falling back to the original local path.
The default save location is:
Documents\Chipper Presets
Files saved there are scanned into the preset browser as a chip-filtered User Presets bank. Metadata-bearing user presets appear in Role/Engine/Tag filter counts alongside factory presets, while older files without metadata still load as portable flat files. Selecting a user preset from the browser loads the file directly; Save updates the loaded user preset file, Save As writes a new shareable copy, and a new sound asks for a .chipperpreset file name. A preset loaded from another folder also appears in the User Presets list for the current session, so downloaded/shared sounds stay reachable while you audition them.
The browser also includes an Init Patch entry at the top for a neutral chip-local starting point. It resets the current chip's sound controls while preserving the current Strictness and supported Play Mode.
Factory presets are grouped by chip-local musical categories in the browser, such as leads, basses, drums, UI sounds, FM patches, or sampler voices. The grouping is only presentation: selecting a preset still applies a normal Chipper parameter snapshot that can be edited, saved, and shared as a flat file.
Save As suggests the currently selected preset name when possible, which keeps variant files easy to recognize when building banks like SID Dirty Bass 02.chipperpreset or SPC700 Echo Pad Soft.chipperpreset.
Factory preset growth follows docs/preset-sourcing.md: original Chipper sound design first, permissive sources only with documented provenance, no copied game data, no bundled unlicensed samples, and every preset must pass audibility plus visible-control QA before release.
Chipper keeps a stable MIDI CC map so hardware controllers and DAW automation can reach all current parameters. The compact map is shown in the plugin footer, exported in descriptor JSON, and documented in docs/ui-architecture.md.
Important shared assignments:
| CC | Parameter |
|---|---|
| 70 | Chip Mode |
| 71 | Behavior Strictness (header label: Strictness) |
| 73 | Output Level |
| 74 | Preset recipe (internal compatibility parameter) |
| 75 | Play Mode |
| 76-79 | Chip-native performance controls |
| 80-87 | Source enable and level controls |
| 88-119 | Chip-specific register, envelope, routing, and sample controls |
Choice/register parameters quantize CC input to valid chip states. Continuous controls use the full 0-127 range.
First-party Chipper source code is licensed under AGPL-3.0-or-later. This is the conservative open-source path because the plugin currently uses JUCE under its open-source AGPL option unless a commercial JUCE license is used.
Current vendored emulator cores are permissive:
digital-sound-antiques/emu2149: MITdigital-sound-antiques/emu76489: MITdigital-sound-antiques/emu2413: MITdigital-sound-antiques/emu2212: MITaaronsgiles/ymfm: BSD-3-Clause
Do not import GPL/LGPL emulator code, preset banks, songs, samples, lookup tables, or patch dumps without a documented compatibility plan. Candidate and reference projects are tracked in docs/emulator-source-map.md, and bundled notices are in THIRD_PARTY_NOTICES.md.
- docs/emulation-accuracy.md: per-chip implementation status, verification evidence, and known gaps
- docs/emulator-source-map.md: source candidates, license audit tiers, and reference-only projects
- docs/product-spec.md: product goals, chip modes, and UX/DSP direction
- docs/ui-architecture.md: adaptive UI strategy and MIDI/automation contract
- docs/ui-priority-audit.md: current chip-aware layout rules and screenshot non-regression checklist
- docs/preset-sourcing.md: factory preset provenance, legal boundaries, and QA checklist
- docs/snes-spc700-plan.md: SPC700-style sampler roadmap
- docs/priority-roadmap.md: execution priorities
- docs/product-gap-roadmap.md: larger workflow gaps and non-regression policy
- docs/release-builds.md: local install, GitHub release builds, and release gates
Chipper should sound like an instrument, but it should not overclaim. The header's Strictness selector requests Inspired, Hybrid, or Authentic behavior; it does not prove that a chip mode is fully accurate. The host/MIDI parameter is named Behavior Strictness to make automation lanes self-explanatory. If a mode is not verified at register/timing level, label it as inspired, style, or partial. Cycle-accurate claims require accepted test suites, trusted emulator comparisons, or real hardware captures.














