SOUL

The SOUL Patch Format

A SOUL patch is a bundle of files which contains everything needed to implement an audio synthesiser or effect. It contains no natively executable code - an application is needed to load and play a patch.

Comparison to traditional audio plugins

In many ways a patch resembles a traditional audio plugin (e.g. VST/AudioUnit/AAX), but has significant differences too.

Similarities:

Differences:

A difference in the overall philosophy lies in the distinction between “sounds” and “plugins”.

If you were delivering a set of 100 “sounds” using a traditional plugin format, you’d build a single large native plugin (the engine), and then supply a set of 100 programs (a.k.a. “presets”, “patches”, “sounds”, etc) which can be loaded onto that engine.

Because SOUL patches are compact and script-based, there’s less reason to structure things like that. A SOUL patch can be treated more like an individual sounds (hence the name “patch” rather than “plugin”). Delivering a set of 100 sounds using SOUL could be done by simply providing 100 separate SOUL patches. Internally they may all share most of the same DSP and GUI codebase (when loaded, the JIT compiler will detect and coalesce any duplicated code). However, the fact that the sounds needn’t share all their engine code means that individual sounds can be fine-tuned to eliminate wasted processing overhead, or to tweak the underlying DSP for particular sounds.

File format

A patch is identified by a manifest file with the suffix .soulpatch which contains information and links to the set of files and resources that it requires.

The .soulpatch file is JSON, and contains details about this particular patch, e.g.

{
  "soulPatchV1": {
    "ID":               "com.mycompany.sounds.awesome_synth_sound_34",
    "version":          "1.0",
    "name":             "Awesome Synth Sound 34",
    "description":      "This is an awesome sound",
    "category":         "synth",
    "manufacturer":     "The Cool Synth Company Inc",
    "icon":             "AwesomeSoundIcon.svg",
    "website":          "https://mycoolsynthcompany.com",
    "isInstrument":     true,

    "source":           [ "AwesomeSound34.soul", "SomeSharedLibraryCode.soul" ],

    "externals": {
      "SampleSet::kickdrum": "sounds/kick1.ogg",
      "SampleSet::hihat":    "sounds/hihat.flac",
      "SampleSet::bass":     "sounds/bass.wav",
      "SampleSet::crash":    "sounds/crash22.wav"
    },

    "view":             [ "AwesomeGUI.js", "AwesomeGUI.faceplate" ]
  }
}

The main duties of this file are to provide:

The folder that contains the manifest file may also contain any resource files that are needed (e.g. audio files, image files for the GUI, etc).

The set of inputs and outputs declared in the main SOUL processor are used by a host to determine the i/o bus layout and set of parameters for the patch. e.g.

processor MySynth
{
    input event midi::Message midiIn;  // a MIDI input channel

    input event float cutoff    [[ name: "Cutoff",    min: 0, max: 127, init: 80, unit: "semi", step: 0.1 ]];
    input event float resonance [[ name: "Resonance", min: 0, max: 100, init: 20, unit: "%",    step: 1   ]];

    output stream float<2> audioOut; // a stereo audio output

The externals object in the manifest contains a set of values which need to be provided for external variables in the program (see the SOUL language guide for more details about how to declare an external variable). Each item in the externals list maps the (fully-qualified) name of a SOUL external variable to either a value (primitive or an object or array, etc), or a filename which should be loaded and turned into a float array. The patch loader uses JUCE for reading audio files, so will load WAV, AIFF, FLAC, Ogg-Vorbis and MP3 on all platforms, and maybe other formats on MacOS and Windows where the OS APIs support it.

Hosting Support and Utilities

To let you create a host that can load and run SOUL patches, we have the following resources:

The binaries and libraries can be downloaded as github releases: https://github.com/soul-lang/SOUL/releases/latest

Annotations for parameters

In SOUL, each input declaration can have an arbitrary set of properties (‘annotations’) attached to it, e.g.

input event float cutoff  [[ name: "Cut-off", min: 0, max: 127, init: 80, unit: "semi", step: 0.1 ]];
input event float turbo   [[ name: "Turbo Boost", boolean, text: "off|on" ]]

If you’d like an input to be treated by a host as a parameter rather than an audio stream, you can attach some of the following annotations to it:

API Resources

The SOUL Patch API interfaces and helper classes are found here.