580 Vortex Runner

synthmidiweb-midisplit-outputcs-80-inspireddraft

Vortex Runner is a Yamaha CS-80-inspired Workshop Computer synth voice. The current stable firmware keeps a monophonic note path but renders two related output voices: Audio Out 1 is Voice A and Audio Out 2 is Voice B, detunable relative to Voice A. Pitch, gate, envelopes, portamento, CV policy, MIDI handling, LFO timing, and preset state are shared; only oscillator/filter colour is A/B-specific, including source/output levels, pulse/PWM, and filter settings. It includes expressive envelopes, high-pass and low-pass filter character, ring modulation, MIDI/Web MIDI control, and a browser editor.

Panel

Workshop Computer panelBase PitchPulse WidthPWM AmountPitch CVAudio / Mod InFilter CVExpression CVGateTrigger / HoldVoice AVoice BOffOffOffOff

Controls

Main knob

Base Pitch
Shared base pitch offset for both output voices.

X knob

Pulse Width
Pulse width for the selected output voice.

Y knob

PWM Amount
Pulse-width modulation amount for the selected output voice. The independent source mixer is Web-editor controlled.

Switch

Filter page: Low-pass cutoff, high-pass cutoff, and resonance for the selected output voice, with soft pickup.

Oscillator page: Shared base pitch plus pulse width and PWM amount for the selected output voice, with soft pickup.

Performance page: Hold page for Voice B detune, ring modulation, and LFO-to-pitch depth, with soft pickup.

Inputs & Outputs

Inputs

Outputs

Inputs

Audio 1

Pitch CV
Web-selectable 1V/oct pitch input: 0 V to +5 V with C4 at +3 V, or -3 V to +3 V with C4 at 0 V.

Audio 2

Audio / Mod In
Reserved for future audio-rate modulation or external processing experiments.

CV 1

Filter CV
Wide high-pass and low-pass filter modulation.

CV 2

Expression CV
Expression input for brightness and resonance modulation.

Pulse 1

Gate
Gate input for the amp and filter envelopes. When patched, it takes priority over USB MIDI gate.

Pulse 2

Trigger / Hold
Reserved for retrigger, sustain, or alternate performance gestures.

Outputs

Audio 1

Voice A
First audio voice output.

Audio 2

Voice B
Second audio voice output, detunable relative to Voice A.

CV 1

Off
Reserved for later modulation output once the split-output voice is stable.

CV 2

Off
Reserved for later modulation output once the split-output voice is stable.

Pulse 1

Off
Reserved for later clock, gate, or envelope-state output.

Pulse 2

Off
Reserved for later clock, gate, or envelope-state output.

LEDs

LED 1

Voice A
Bright when Voice A is selected for hardware-panel editing.

LED 2

Voice B
Bright when Voice B is selected for hardware-panel editing.

LED 3

X Value
Stored X parameter value for the active switch page.

LED 4

X Pickup
Soft-pickup state for the X knob; dim until picked up, bright when active.

LED 5

Y Value
Stored Y parameter value for the active switch page.

LED 6

Y Pickup
Soft-pickup state for the Y knob; dim until picked up, bright when active.

README

Vortex Runner

Vortex Runner is a Workshop Computer card for a CS-80-inspired split-output synthesiser voice.

The current stable target is still deliberately modest: keep one playable monophonic note path, but render it as two related output voices so Audio Out 2 can be detuned against Audio Out 1.

This card is not affiliated with Yamaha and is not intended to be a circuit emulation of the Yamaha CS-80. The goal is a playable Workshop Computer instrument inspired by the broad musical gestures of that synthesiser: two oscillator lanes, animated pulse/saw tone, high-pass into low-pass filtering, performance modulation, ring modulation, and expressive envelopes.

Current Status

This folder contains the tested split-output firmware baseline and its Web MIDI editor.

  • Firmware: uf2/Vortex_Runner_current_stable_dual_output_20260830.uf2 is the tested dual-output monophonic build, including the two-bank MIDI CC layout, CC1 vibrato depth, MIDI absolute-pitch handling, and coalesced Web MIDI patch handoff for rapid detune changes
  • Web editor: Vortex Runner SysEx v10 patch apply/readback interface with named persistent card slots
  • Rollbacks: locally retained rollback UF2s are ignored by git
  • Release status: draft
  • Release guide and first patch: RELEASE_SUMMARY.md or RELEASE_SUMMARY.txt

Release firmware should go in uf2/ when a build is ready to publish. Local hardware-test UF2s should go in test-uf2/, which is ignored by git.

Design Target

  • RP2040 clock: 192 MHz
  • Firmware should use pico_set_binary_type(... copy_to_ram)
  • Audio rendering should stay on core 0
  • USB MIDI, Web MIDI SysEx, and editor communication run on core 1
  • The audio loop should avoid division, float-heavy code, blocking calls, flash writes, and MIDI parsing
  • Complete Web MIDI patches cross from core 1 to core 0 through a bounded, lockless SPSC queue; core 0 publishes readback snapshots through a second queue
  • The playable note path remains monophonic while Audio Out 1 and Audio Out 2 render separate A/B voices for detune and shaping experiments

Current Voice Shape

  • monophonic note/gate path with two split audio outputs
  • Audio Out 1: Voice A
  • Audio Out 2: Voice B, detunable relative to Voice A
  • one shared pitch, gate, amp/filter envelope, portamento, pitch-CV policy, CV routing, MIDI state, LFO timing, and preset state for both outputs
  • A/B differences are limited to oscillator/filter colour: source levels, output level, detune, pulse width, PWM amount, HP cutoff, LP cutoff, and resonance
  • web-first portamento for smooth CV/pitch glides
  • independent saw, square/pulse, sine, and noise mixer levels
  • independent pulse width, PWM amount, LFO-to-pitch, and LFO-to-PWM controls
  • oscillator spread or detune
  • high-pass then low-pass filter character
  • amp envelope
  • filter envelope
  • LFO for vibrato, tremolo, or filter movement
  • ring modulation as a performance colour
  • gate and MIDI note triggering
  • Web MIDI editor for patch editing, readback, and saving

Draft Web MIDI Protocol

The editor and firmware now share a small non-commercial SysEx protocol:

  • manufacturer byte: 0x7d
  • legacy wire id: CS80 (retained for existing editor and firmware compatibility)
  • protocol version: 10
  • commands: apply patch, save slot, request current patch, request slot map, request slot, slot response, delete slot, and set startup slot

pitch-CV range mode, portamento, separate A/B pulse width, PWM amount, saw/pulse/sine/noise source levels, output level, HP cutoff, LP cutoff, and resonance, plus shared expression depth, amp/filter ADSR controls, LFO rate, LFO routings, ring amount, and ring speed. The source levels are summed rather than crossfaded. Save applies the patch and writes it, with a 24-character name, to one of eight persistent card slots. The first saved patch becomes the startup patch automatically; use the editor's Start Here button to choose a different saved startup slot. Refresh Slots reads the card's saved-slot map, Read Patch syncs the current live card patch, and Load Slot recalls the selected saved slot.

Factory presets remain immutable editor choices and load both outputs in unison. Users can create named browser presets alongside them, then use Save to Card to persist the current sound and its name in a selected hardware slot.

At startup, holding the Down switch during the short boot selection window enters patch-slot select. Main chooses among saved slots while the LEDs show only the selected slot number in binary. Release Down to keep browsing, then press Down again to load the selected slot, store it as the default startup slot, and enter normal performance mode.

Factory/example presets preserve the editor's current CV policy when loaded. Saved card slots are full snapshots: the pitch-CV range is part of each saved patch, so the startup slot also restores its -3 V to +3 V, C4 at 0 V or 0 V to +5 V, C4 at +3 V pitch reference. If no saved startup slot exists yet, the compiled fallback patch is the Web editor's Doctor Who Theme preset: an eerie lead using sine plus pulse, resonant filtering, portamento, vibrato, PWM wobble, and a little ring modulation.

MIDI CC Map

Following the Gnarly habit, Vortex Runner now exposes a simple two-bank encoder layout for controllers such as the M-VAVE SMK-25:

  • CC1: vibrato depth via LFO to pitch
  • Bank A, CC20-27: saw level, pulse level, sine level, noise level, pulse width, PWM amount, LP cutoff, resonance
  • Bank B, CC28-31: HP cutoff, ring amount, ring speed, portamento
  • Bank B, CC32-35: linked amp/filter attack, decay, sustain, release

The Web UI stores separate amp and filter ADSR values. CC32-35 move the amp and filter envelope values together by offset, so controller changes keep the relative Web UI envelope shape instead of collapsing both envelopes to identical values.

Secondary synth controls stay available on:

  • CC2 or CC11: expression depth
  • CC7: voice level
  • CC76: LFO rate
  • CC77 or CC93: LFO to PWM
  • CC91: LFO to VCF
  • CC92: LFO to VCA

Pitch bend is also supported at a fixed +/-2 semitone range. It is kept separate from the editor's performance-pitch parameter, so Web patch changes cannot overwrite an active MIDI bend or alter MIDI note pitch unexpectedly.

MIDI note-on and note-off drive the monophonic note path directly. While a MIDI note is held, it takes over pitch and gate for the synth voice, including portamento and pitch bend; the panel base-pitch offset no longer transposes MIDI notes. With USB MIDI connected and Pulse In 1 unpatched, the card is silent until it receives a MIDI note. A patched Pulse In 1 remains the gate source. After a MIDI release tail ends, pitch returns to the card CV/manual source.

Firmware

CS80.cpp is a lean starting point rather than a finished synth. It currently drives one monophonic note path with two audio output voices:

  • Audio Out 1: Voice A
  • Audio Out 2: Voice B, detuned relative to Voice A

Short-tapping Down toggles whether the hardware panel is editing Voice A or Voice B. Holding Down exposes performance controls for Voice B detune, ring modulation, and LFO depth. When Pulse In 1 is unpatched the gate is held open for oscillator bring-up; when it is patched, Pulse In 1 gates the monophonic note path. Audio/CV In 1 is the pitch input. The Web editor selects either unipolar 0 V to +5 V, with C4 at +3 V (0 V is C1), or bipolar -3 V to +3 V, with C4 at 0 V. Both use 1V/oct. The Web editor also provides one combined CV filter pairing selector. CV1 Contour Sweep + CV2 Expression keeps the broad sweep behaviour, with CV1 moving HP and LP while CV2 adds LP brightness and resonance. CV1 High-Pass Focus + CV2 Brightness gives separate lower-edge and upper-edge filter movement. CV1 Low-Pass Brightness + CV2 Resonance leaves CV2 as a resonance-only performance input.

Panel controls use soft pickup so switching pages does not immediately overwrite stored values. LEDs 0/2/4 show the stored Main/X/Y values for the current switch page, while LEDs 1/3/5 go bright once each physical knob has picked up its stored value.

Web MIDI never writes live audio parameters directly. Core 1 parses each complete SysEx patch or MIDI CC update and retains only the newest complete patch for the audio core; core 0 applies at most one patch on each 64-sample control tick (about 750 Hz at 48 kHz). This single-value mailbox coalesces rapid detune or editor updates rather than making audio apply stale intermediate states. A second, best-effort queue returns core-0 snapshots to the editor for safe readback. Apply messages do not generate a full patch reply; explicit read, slot load, save verification, and slot refresh continue to do so.

The first pass uses small lookup tables in CS80_LUT.* for pitch ratios, filter curves, envelope rates, and LFO/ring sine values. This follows the C1ZZL3 habit of keeping expensive shaping out of the 48 kHz audio path.

Build locally with:

cmake -S . -B build -DPICO_NO_PICOTOOL=1
cmake --build build -j2

References

Cards 84 and 101 are the main local references for the Web MIDI/editor pattern, 192 MHz build setup, copy-to-RAM configuration, dual-core USB MIDI worker, flash storage, and complex synth-card release structure:

  • releases/84_CosmikC1zzl3
  • releases/101_Gnarly_C1ZZL3

Attribution And License Notes

Vortex Runner firmware is by Adrian Vos and is released under the MIT License. See LICENSE.

The included computercard.h file is ComputerCard by Chris Johnson, version 0.3.0, also MIT licensed. It is copied from:

Demonstrations+HelloWorlds/PicoSDK/ComputerCard/ComputerCard.h

The USB MIDI host helper files usb_midi_host.* and usb_midi_host_app_driver.c are copied from the local C1ZZL3 cards and retain the upstream rppicomidi MIT copyright notices in the source files. The TinyUSB descriptor/config pattern is adapted from Adrian Vos's C1ZZL3 cards for this card's Web MIDI device interface.

The included pico_sdk_import.cmake file is the standard Raspberry Pi Pico SDK import helper. It carries the Raspberry Pi (Trading) Ltd. BSD-style notice in the file itself.

About this card

Creator
Adrian Vos
Language
C++ (Pico SDK)
Version
0.1
Status
Beta - stable-tested split-output firmware with named Web MIDI presets
License
MIT
Created
2026-08-26
Updated
2026-08-31

Notes

Web MIDI editor: Draft browser editor using Web MIDI SysEx for patch apply, readback, and eight persistent named card slots.

USB MIDI input: MIDI note/gate, pitch-bend, and performance CC input for the draft split-output voice, following a Gnarly-style dedicated controller block with standard synth aliases.

Draft architecture target: RP2040 at 192 MHz, copy-to-RAM firmware, audio rendering on core 0, USB MIDI/Web MIDI work on core 1, and bounded lockless queues for complete patch handoff and core-0 readback. The current st…

Data sources

releases/580_Vortex_Runner/info.yaml, releases/580_Vortex_Runner/README.md

Verify your download

Confirm the file you downloaded really is that new firmware.

macOS / Linux (Terminal)

shasum -a 256 firmware.uf2

Linux also has sha256sum firmware.uf2.

Windows (PowerShell)

Get-FileHash firmware.uf2 -Algorithm SHA256

Compare the result to the SHA256 on the website — it should match exactly.