Skip to content

Repository files navigation

SuperCollider project template

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.

Requirements

  • 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 the project tools

Install these repositories at the indicated locations under the home directory:

The corresponding paths are already defined in project_config.scd:

~controllerDir = ~homeDir +/+ "midiFighterControllerPanel";
~gainStageDoctorDir = ~homeDir +/+ "gainStageDoctor";
~reaperSessionBridgeDir = ~homeDir +/+ "reaperSessionBridge";

Configure the MIDI controllers

  1. Open MIDI Fighter Utility
  2. Configure each Twister encoder switch as Note Toggle
  3. Enable Momentary CC for the Spectra
  4. Disable Spark under Spectra animations
  5. Connect the controllers before starting SuperCollider

Physical knob turns and button presses pass through only while their controls are active in the controller GUI.

Install the REAPER actions

  1. In REAPER, open Actions → Show action list
  2. Choose New action → Load ReaScript
  3. Load ~/reaperSessionBridge/reaperSessionSetup.lua
  4. Confirm that Synchronize SuperCollider recording tracks appears in the action list
  5. Choose New action → Load ReaScript
  6. Load ~/reaperSessionBridge/reaperAudioDeviceDiagnostic.lua
  7. 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.

Configure audio routing

Windows

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.

macOS

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)

Output mapping

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 files

  • project.scd: startup file
  • project_config.scd: project identity, shared paths, controller state, gain staging, REAPER publication, and input mode
  • project_init.scd: source definitions, control buses, and source configuration
  • project_outputStage.scd: source routing and optional gain-stage output strips
  • project_synthDefs.scd: starter SynthDefs
  • project_panel.scd: prototype gain-stage window and embedded performance controls
  • project_maps.scd: Twister parameter maps and source labels
  • project_actions.scd: source-start and source-stop actions
  • project_input.scd: input-mode dispatcher
  • project_input_keyboard.scd: QuNexus note responders
  • project_input_spectra.scd: Spectra input actions
  • project_input_none.scd: empty adapter for project-specific triggering
  • project_cleanup.scd: project cleanup function

Set up a new project

  1. Copy the ~/projectTemplate directory

  2. Rename the copied directory for the new project

  3. 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
    
  4. Open myNewPiece.scd and update its local .load filename strings to match the renamed files

    Keep the template variable ~projectDir unchanged.

  5. Open myNewPiece_input.scd and update its three local .load filename strings:

    (~projectDir +/+ "myNewPiece_input_keyboard.scd").load;
    (~projectDir +/+ "myNewPiece_input_spectra.scd").load;
    (~projectDir +/+ "myNewPiece_input_none.scd").load;
  6. Open myNewPiece_config.scd

  7. Set the project name and title

    ~projectName = \myNewPiece;
    ~projectTitle = "My New Piece";
  8. 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;
  9. Run myNewPiece.scd

Prototype a project

Replace or add a SynthDef

  1. Open project_synthDefs.scd

  2. Replace a starter SynthDef or add another

    Keep the outBus, makeupGainCtl, and makeupMaxDb arguments 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 trig argument and envelope-release convention.

  3. Open project_init.scd

  4. 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
            )
        ]
    )
  5. Open project_actions.scd

  6. 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.

Configure controllers and input

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 \trig control
  • \spectra: MIDI Fighter Spectra input using the configurations in project_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);

Define sources and outputs

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.

Set recording levels

Keep the standard gain-stage workflow enabled in project_config.scd:

~useGainStageDoctor = true;

For each source:

  1. Set amp to the loudest musical performance level expected from the source
  2. Trigger representative sounds or gestures
  3. Add makeup gain only when the source needs compensation or additional drive
  4. Use output trim to set the final REAPER recording level
  5. Confirm that the post-trim meter remains below clipping
  6. 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.

Open prototype REAPER tracks

  1. Keep ~publishReaperSession = false in project_config.scd
  2. Run project.scd
  3. Open a REAPER project
  4. 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.

Test the project

  1. Run project.scd
  2. Hold Spectra button 0 and confirm that the sustaining synth stops on release
  3. Press Spectra button 1 and confirm that the deterministic synth finishes before it can be triggered again
  4. Test Twister knob 0 with the sustaining synth
  5. Test Twister knob 1 with the deterministic synth
  6. Confirm that the two sources reach separate REAPER inputs
  7. Run the project cleanup before starting another project

Prepare a performance

Finalize controller state

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);

Publish the REAPER mapping

  1. Confirm that ~projectSources in project_init.scd contains the intended source names and hardwareOut assignments

  2. Open project_config.scd

  3. Set:

    ~publishReaperSession = true;
  4. Run project.scd

  5. Return to the REAPER project containing the prototype tracks

  6. Run Synchronize SuperCollider recording tracks

  7. Choose Yes for the displayed project title

  8. Review the resulting track names, inputs, monitoring states, and track count

Only bridge-managed tracks are synchronized. Unrelated REAPER tracks remain untouched.

Change an existing project

Change the recording configuration

  1. Open project_init.scd
  2. Edit the names, source count, or hardwareOut assignments in ~projectSources
  3. Leave ~publishReaperSession = true in project_config.scd
  4. Run project.scd
  5. Run Synchronize SuperCollider recording tracks in REAPER
  6. Choose Yes for the displayed project title
  7. 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.

Return to prototype REAPER tracks

  1. Run Synchronize SuperCollider recording tracks
  2. 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.

Verify a recording session

  1. Trigger each source independently
  2. Confirm that each source reaches only its intended REAPER track
  3. Confirm that the loudest expected sounds do not clip
  4. Make and play back a short test recording
  5. Run the SuperCollider project cleanup before starting another project

Notes

  • The template SynthDefs are starter sounds and should be replaced with project-specific sound design
  • Keep sustained keyboard sources on the established trig convention: 1 on note-on and 0 on note-off
  • Use short source names so labels fit in the performance interfaces

About

Reusable SuperCollider project template for MIDI Fighter control, gain staging, configurable input, and synchronized multitrack recording in REAPER

Topics

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages