A reusable starting point for SuperCollider projects using MIDI Fighter controllers, gainStageDoctor, configurable sound input, and REAPER recording-track synchronization.
This README is the primary usage guide for the complete project workflow. The companion repositories document their individual APIs and implementation details.
- SuperCollider: tested with version 3.13.0
- REAPER: tested with version 7
- MIDI Fighter Twister, MIDI Fighter Spectra, or both
- Windows audio routing through
Voicemeeter Virtual ASIO - macOS audio routing through an aggregate device named
BlackHole + MixPre
Install these repositories at the indicated locations under the home directory:
- projectTemplate:
~/projectTemplate - midiFighterControllerPanel:
~/midiFighterControllerPanel - gainStageDoctor:
~/gainStageDoctor - reaperSessionBridge:
~/reaperSessionBridge
The corresponding paths are already defined in project_config.scd:
~controllerDir = ~homeDir +/+ "midiFighterControllerPanel";
~gainStageDoctorDir = ~homeDir +/+ "gainStageDoctor";
~reaperSessionBridgeDir = ~homeDir +/+ "reaperSessionBridge";- Open MIDI Fighter Utility
- Configure each Twister encoder switch as Note Toggle
- Enable Momentary CC for the Spectra
- Disable Spark under Spectra animations
- Connect the controllers before starting SuperCollider
Physical knob turns and button presses pass through only while their controls are active in the controller GUI.
- In REAPER, open Actions → Show action list
- Choose New action → Load ReaScript
- Load
~/reaperSessionBridge/reaperSessionSetup.lua - Confirm that Synchronize SuperCollider recording tracks appears in the action list
- Choose New action → Load ReaScript
- Load
~/reaperSessionBridge/reaperAudioDeviceDiagnostic.lua - Optionally assign the synchronization action a keyboard shortcut or toolbar button
REAPER loads subsequent changes directly from the installed script files. The actions do not need to be added again after those files are updated.
Select the following devices in REAPER:
Audio system: ASIO
Input device: ASIO Voicemeeter Virtual ASIO
Output device: ASIO Voicemeeter Virtual ASIO
Leave input monitoring off on the bridge-managed recording tracks.
Create an aggregate device named BlackHole + MixPre with BlackHole 16ch first and MixPre-3M after it.
Select the following devices in REAPER:
Audio system: CoreAudio
Input device: CoreAudio BlackHole + MixPre
Output device: CoreAudio BlackHole + MixPre
Select BlackHole + MixPre as the SuperCollider audio device.
Input monitoring is enabled on the bridge-managed recording tracks. The REAPER synchronization action routes the master output to:
17: Out 1 (MixPre-3M) / Out 2 (MixPre-3M)
| SuperCollider output | REAPER mono input |
|---|---|
| 0 | 1 |
| 1 | 2 |
| 2 | 3 |
| 3 | 4 |
Run reaperAudioDeviceDiagnostic.lua from REAPER’s action list to inspect the current audio-device configuration.
project.scd: startup fileproject_config.scd: project identity, shared paths, controller state, gain staging, REAPER publication, and input modeproject_init.scd: source definitions, control buses, and source configurationproject_outputStage.scd: source routing and optional gain-stage output stripsproject_synthDefs.scd: starter SynthDefsproject_panel.scd: prototype gain-stage window and embedded performance controlsproject_maps.scd: Twister parameter maps and source labelsproject_actions.scd: source-start and source-stop actionsproject_input.scd: input-mode dispatcherproject_input_keyboard.scd: QuNexus note respondersproject_input_spectra.scd: Spectra input actionsproject_input_none.scd: empty adapter for project-specific triggeringproject_cleanup.scd: project cleanup function
-
Copy the
~/projectTemplatedirectory -
Rename the copied directory for the new project
-
Rename the copied project files using the project name
For a project named
myNewPiece, rename:project.scd → myNewPiece.scd project_config.scd → myNewPiece_config.scd project_init.scd → myNewPiece_init.scd project_outputStage.scd → myNewPiece_outputStage.scd project_synthDefs.scd → myNewPiece_synthDefs.scd project_panel.scd → myNewPiece_panel.scd project_maps.scd → myNewPiece_maps.scd project_actions.scd → myNewPiece_actions.scd project_input.scd → myNewPiece_input.scd project_input_keyboard.scd → myNewPiece_input_keyboard.scd project_input_spectra.scd → myNewPiece_input_spectra.scd project_input_none.scd → myNewPiece_input_none.scd project_cleanup.scd → myNewPiece_cleanup.scd -
Open
myNewPiece.scdand update its local.loadfilename strings to match the renamed filesKeep the template variable
~projectDirunchanged. -
Open
myNewPiece_input.scdand update its three local.loadfilename strings:(~projectDir +/+ "myNewPiece_input_keyboard.scd").load; (~projectDir +/+ "myNewPiece_input_spectra.scd").load; (~projectDir +/+ "myNewPiece_input_none.scd").load;
-
Open
myNewPiece_config.scd -
Set the project name and title
~projectName = \myNewPiece; ~projectTitle = "My New Piece";
-
Leave the project in prototype mode while its sound design, controls, and recording sources are being developed
~projectControllerConfig = ( mode: \prototype, controllers: \both, twisterActive: [0, 1], spectraActive: [0, 1], spectraDeterministic: [1] ); ~useGainStageDoctor = true; ~publishReaperSession = false; ~projectInputMode = \spectra;
-
Run
myNewPiece.scd
-
Open
project_synthDefs.scd -
Replace a starter SynthDef or add another
Keep the
outBus,makeupGainCtl, andmakeupMaxDbarguments when using the standard gainStageDoctor routing:SynthDef(\myNewSynth, { | outBus = 0, amp = 0.2, makeupGainCtl = 0.0, makeupMaxDb = 6.0 | var makeupGainDb, sig; makeupGainDb = makeupGainCtl.linlin(0, 1, 0, makeupMaxDb); sig = SinOsc.ar(220) * amp * makeupGainDb.dbamp; Out.ar(outBus, sig); }).add;
For a sustained keyboard SynthDef, also keep the existing
trigargument and envelope-release convention. -
Open
project_init.scd -
Add or update the corresponding source dictionary
( name: \myNewSynth, label: "My New Synth", hardwareOut: 0, makeupMaxDb: 6.0, makeupValue: 0.0, trimMinDb: -24.0, trimMaxDb: 12.0, trimDb: 0.0, twisterMap: [ ( knob: 0, arg: \amp, label: "amp", min: 0.0, max: 1.0 ) ] ) -
Open
project_actions.scd -
Update the action that creates the Synth
Synth.tail( ~projectSourceGroup.(), \myNewSynth, [ \amp, ~twisterBusses[0].asMap, \outBus, source[\outBus] ] ++ ~projectMakeupArgs.(source) );
Keep project-specific Synth creation and release behavior in project_actions.scd, not in the MIDI responder files.
When the project requires tasks, routines, Patterns, or other sequencing behavior, add clearly named project files beside the existing .scd files and load them from project.scd at the required startup stage.
Open project_config.scd and update the existing configuration:
~projectControllerConfig = (
mode: \prototype,
controllers: \both,
twisterActive: [0, 1],
spectraActive: [0, 1],
spectraToggle: [],
spectraDeterministic: [1]
);
~projectInputMode = \spectra;controllers may be \twister, \spectra, or \both. The active-control arrays use indices from 0 through 15.
Input mode is independent of the visible controller layout:
\keyboard: QuNexus note input and sustained\trigcontrol\spectra: MIDI Fighter Spectra input using the configurations inproject_input_spectra.scd\none: no standard input responders, for Patterns, OSC, routines, or project-specific triggering
List deterministic Spectra sources in spectraDeterministic. Leave sustaining Spectra sources out of that list.
List controls that alternate between explicit on and off states in
spectraToggle. Their project input action receives 1 when switched on and
0 when switched off. Leave spectraToggle empty when the project does not
use this behavior.
In prototype mode, activate the GUI controls that should pass physical controller input to the project.
To switch the running panel to prototype mode:
~projectSetPanelMode.(\prototype);Add one dictionary per independent recording source to ~projectSources in project_init.scd:
~projectSources = [
(
name: ~projectName,
label: ~projectTitle,
hardwareOut: 0,
makeupMaxDb: 6.0,
makeupValue: 0.0,
trimMinDb: -24.0,
trimMaxDb: 12.0,
trimDb: 0.0,
twisterMap: [
(
knob: 0,
arg: \amp,
label: "amp",
min: 0.0,
max: 1.0
)
]
)
];Use a unique zero-based hardwareOut from 0 through 3 for each source that needs a separate REAPER recording track.
The source index determines its Twister column and corresponding Spectra label:
| Source index | Twister knobs |
|---|---|
| 0 | 0, 4, 8, 12 |
| 1 | 1, 5, 9, 13 |
| 2 | 2, 6, 10, 14 |
| 3 | 3, 7, 11, 15 |
The twisterMap argument names must match controls defined by the SynthDef.
Keep the standard gain-stage workflow enabled in project_config.scd:
~useGainStageDoctor = true;For each source:
- Set
ampto the loudest musical performance level expected from the source - Trigger representative sounds or gestures
- Add makeup gain only when the source needs compensation or additional drive
- Use output trim to set the final REAPER recording level
- Confirm that the post-trim meter remains below clipping
- Confirm that the source reaches only its intended REAPER track
Makeup gain occurs inside the source signal path and can affect saturation. Output trim changes the final recording level without changing the source synthesis behavior.
- Keep
~publishReaperSession = falseinproject_config.scd - Run
project.scd - Open a REAPER project
- Run Synchronize SuperCollider recording tracks
With no published manifest, the action creates four managed tracks:
| Track name | SuperCollider output | REAPER mono input |
|---|---|---|
sc out 0 |
0 | 1 |
sc out 1 |
1 | 2 |
sc out 2 |
2 | 3 |
sc out 3 |
3 | 4 |
The action configures the monitoring state required by the current platform.
- Run
project.scd - Hold Spectra button 0 and confirm that the sustaining synth stops on release
- Press Spectra button 1 and confirm that the deterministic synth finishes before it can be triggered again
- Test Twister knob 0 with the sustaining synth
- Test Twister knob 1 with the deterministic synth
- Confirm that the two sources reach separate REAPER inputs
- Run the project cleanup before starting another project
Open project_config.scd and list only the controls used by the finished project:
~projectControllerConfig = (
mode: \performance,
controllers: \both,
twisterActive: [0, 1],
spectraActive: [0, 1],
spectraToggle: [],
spectraDeterministic: [1]
);Performance mode shows only active controls and prevents activation changes from the performance panel.
To switch the currently running panel:
~projectSetPanelMode.(\performance);-
Confirm that
~projectSourcesinproject_init.scdcontains the intended source names andhardwareOutassignments -
Open
project_config.scd -
Set:
~publishReaperSession = true;
-
Run
project.scd -
Return to the REAPER project containing the prototype tracks
-
Run Synchronize SuperCollider recording tracks
-
Choose Yes for the displayed project title
-
Review the resulting track names, inputs, monitoring states, and track count
Only bridge-managed tracks are synchronized. Unrelated REAPER tracks remain untouched.
- Open
project_init.scd - Edit the names, source count, or
hardwareOutassignments in~projectSources - Leave
~publishReaperSession = trueinproject_config.scd - Run
project.scd - Run Synchronize SuperCollider recording tracks in REAPER
- Choose Yes for the displayed project title
- Review the updated track names, inputs, and track count
The bridge does not remove a managed track containing media. Move or remove that media before synchronizing a configuration that requires the track to be removed.
- Run Synchronize SuperCollider recording tracks
- Choose No when asked whether to use the published manifest
The bridge-managed tracks return to sc out 0 through sc out 3 without changing unrelated tracks.
- Trigger each source independently
- Confirm that each source reaches only its intended REAPER track
- Confirm that the loudest expected sounds do not clip
- Make and play back a short test recording
- Run the SuperCollider project cleanup before starting another project
- The template SynthDefs are starter sounds and should be replaced with project-specific sound design
- Keep sustained keyboard sources on the established
trigconvention:1on note-on and0on note-off - Use short source names so labels fit in the performance interfaces