draft: false Name: Bootleg Radio short-description: "A lo-fi bootleg tribute to Music Thing's Radio Music: tune through WAV files on a USB stick, like a pirate station" Language: C++ (Pico SDK + ComputerCard) Creator: Joep Vermaat Version: "1.0.0" Status: Released License: MIT Editor: none date-created: 2026-10-03 date-updated: 2026-10-04 contact: email: joep@joep-i.nl # Vendored, unmodified and under their own terms: # ComputerCard.h # (c) Chris Johnson, MIT # fatfs/ (FatFs, R0.16) # (c) ChaN, FatFs license (see fatfs/LICENSE.txt) # The usb_msc_host example this card is adapted from was contributed by # Chris Johnson to the Workshop_Computer repository (PR #437). uf2: - path: UF2/bootleg_radio.uf2 name: Bootleg Radio 1.0.0 tags: - sampler - playback - wav - usb-host - radio - utility summary: | A lo-fi bootleg tribute to Music Thing Modular's Radio Music - not a replacement, but a cheaper, grubbier cousin. Named for the 538 AM pirate broadcasters off the Dutch coast (and the Botlek, the grimy Rotterdam docklands where sub- and pirate culture ran thick), it deliberately keeps the hiss and the seams. Load a USB stick with WAV files, plug it into the Computer's front USB-C jack, and tune through them like radio stations. For a ready-made start, the [Radio Music Suggested Audio](https://www.musicthing.co.uk/Radio_Music_Suggested_Audio/) page is a great set of loops and samples to load onto the stick and try the card. The Main knob and CV in 1 pick the station, the X knob and CV in 2 set the tape speed, the Y knob and Audio in 1 set the loop start, and Audio in 2 sets the loop length. Each station loops over its window; the switch retriggers, selects banks, or (held) changes the tune mode.

Files are grouped into banks: the root directory is bank 0, and each subdirectory that holds WAV files is another bank (up to 32). Hold the switch up and turn Main to change bank; a new bank starts at its first station. The root is always bank 0 even if it holds no WAVs, in which case the card starts silent until you pick a folder. Banks and the stations within them are natural-sorted (case-insensitive, digits compared as numbers), so the order matches Finder; a bank holds up to 64 stations.

Files must be uncompressed 16-bit PCM, mono or stereo, at any sample rate up to 192kHz; they are resampled to 48kHz on the fly. This is a hacker's sampler rather than a pristine one: the DAC is 12-bit and the resampling is simple linear interpolation, which is part of the character.

Tuning can be a "synchronised jump" - the new file picks up at the same proportional position where the old one stopped - so a slow sweep through the stick keeps its place instead of restarting everything at the beginning. This is the default "Sync" mode; holding switch-down toggles to "Loop" mode, where a new station starts at its loop start point. A deliberate retrigger, or reaching the loop end, restarts from the live loop start point.

Needs a Rev 1.1 or later Computer (the revision with USB host support), and nothing else may be in the front USB socket, because the Computer has to act as a USB host. panel: inputs: - id: CVIn1 name: Station CV type: cv description: > Selects the station, added to the Main knob. The whole CV range sweeps evenly across every station in the current bank; while the switch is held up it selects the bank instead. When the jack is unpatched the knob works alone. - id: CVIn2 name: Speed CV type: cv description: > Tape speed, added to the X knob: about -6V is the slowest (-2 octaves), 0V is normal speed, +6V the fastest (+2 octaves). The CV inputs are bipolar, so a unipolar source sweeps only half the range. - id: AudioIn1 name: Loop Start CV type: cv description: > Loop start point, added to the Y knob: about -6V is the start of the file, +6V the end. The audio inputs are DC-coupled, so they read a steady voltage just like a CV input. - id: AudioIn2 name: Loop Length CV type: cv description: > Loop length, as a fraction of the file: about -6V is a very short loop, 0V is half the file, +6V the whole file. Unpatched, the loop runs to the end of the file. - id: PulseIn1 name: Clock type: pulse description: > External clock for the two CV outputs (the triangle LFO and the random CV). Unpatched, they run from an internal 120 BPM clock; patch a clock here to drive them from it. The tempo glides to the new rate and falls back to 120 BPM if the clock stops. - id: PulseIn2 name: Retrigger type: pulse description: > A rising edge retriggers the current station from the loop start, just like a short switch-down tap. outputs: - id: AudioOut1 name: Audio Out 1 type: audio description: Left channel (mono files appear on both outputs). - id: AudioOut2 name: Audio Out 2 type: audio description: Right channel (mono files appear on both outputs). - id: PulseOut1 name: Loop Gate type: pulse description: > By default, high while the loop is playing and low during the wrap/seek gap, so other modules can follow the loop window. settings.txt can set it to a loop-wrap tick, the active clock pulse, or off. - id: PulseOut2 name: Wrap Tick type: pulse description: > By default, a short pulse each time the loop wraps around to the start. settings.txt can set it to the loop gate, the active clock pulse, or off. - id: CVOut1 name: Random CV type: cv description: > A random stepped voltage (bipolar), with a new value on every clock pulse (2Hz at the internal 120 BPM). Patch it into any input to step a parameter - for example CV in 2 to step the tape speed, or Audio in 1 to jump the loop start. - id: CVOut2 name: Triangle LFO type: cv description: > A bipolar triangle, one cycle per 40 clock pulses (20 seconds at 120 BPM, stretching or shrinking with an external clock), so the card doubles as a slow LFO for the rest of the rack. Patch it into CV in 1 to sweep through the stations, or CV in 2 to sweep the tape speed. controls: switch: down: name: Retrigger / Mode description: > Momentary. A short tap restarts the current station from the loop start, so the switch acts as a trigger input for the loop. Holding it for about a second toggles the tune mode between Loop and Sync; the whole panel blinks 2 times for Loop and 3 times for Sync. up: name: Select Bank description: > While held, the Main knob and CV in 1 select the bank (root = bank 0, then each subfolder with WAV files). A new bank starts at its first station; releasing the switch returns Main to selecting stations. middle: name: Play description: > Playback runs normally. A station loops over its window forever; the card never advances on its own. knobs: - main: name: Station / Bank description: > Chooses the station within the current bank; CV in 1 adds to it, so patching a CV lets you tune by voltage as well as by hand. While the switch is held up, the same knob selects the bank instead. x: name: Tape Speed description: > Playback rate from -2 to +2 octaves, exponential around a centre of normal speed. Slower also plays lower, like slowing a tape. CV in 2 adds to it. y: name: Loop Start description: > Where the loop begins, as a fraction of the file. The loop plays from here for the loop length, then wraps back. Audio in 1 adds to it. leds: - display: list items: - id: LED0 name: Left Level description: Brightness follows the left output level. - id: LED1 name: Right Level description: Brightness follows the right output level. - id: LED2 name: Playing / Mode description: > Off when idle. Steady while a station is playing in Sync mode, and slowly blinking while playing in Loop mode, so it shows both the play state and the current tune mode. - id: LED3 name: Station Change / No Files description: > Blinks for about half a second when the station changes. Lights steadily (with LED 4) if a mounted stick has no WAV files in the selected bank, or if none of the files found could be played. Dark in the "quiet" LED mode (settings.txt). - id: LED4 name: USB Mounted description: Lit while a USB stick is detected. - id: LED5 name: Underrun / Mount Fault description: > Flashes if the stick cannot feed the buffer fast enough. Lights steadily (with LED 4) if the filesystem on a detected stick could not be mounted. Dark in the "quiet" LED mode (settings.txt). host: usb: - name: USB flash drive role: storage description: > A FAT32 or exFAT USB stick holding 16-bit PCM WAV files in its root directory and/or subfolders (each subfolder with WAVs becomes a bank), plugged into the Computer's front USB-C jack. Needs a Rev 1.1 or later board, because the Computer acts as USB host. Use a data cable or adaptor, and keep the stick the only thing in that socket. The card mounts a wide range of sticks: Master Boot Record, GUID Partition Map and whole-disk (superfloppy) layouts are all supported, as are sector sizes from 512 to 4096 bytes. A GPT data volume must be the Microsoft Basic Data type, which is the default for FAT/exFAT. notes: | The card never writes to the stick, so nothing on it can be changed by accident. WAV files are natural-sorted (case-insensitive, digits compared as numbers), so the station and bank order matches Finder. Files are read from the root directory and from each subfolder that holds WAV files. An optional settings.txt in the root sets the power-on mode, start bank, internal clock tempo, triangle rate, the two pulse-output modes and the LED mode; it is read once per mount, and a missing or malformed value falls back to the default.