Skip to content

Folders and files

NameName
Last commit message
Last commit date

Latest commit

Β 

History

57 Commits
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 

Repository files navigation

Performative

This library is a set of tools designed to help you design performative instruments and/or compositions in SuperCollider.

One of the main goals of this library is to create a framework for managing and designing musical perameters: Parameters that contain compositional decision making and encourage structural improvisation.

Interacting with the parameters should be as easy as possible. For this reason, all of them can be either set with direct values or using a normalized range of floating point numbers as inputs (0.0 to 1.0) β€” this makes it simple to map them to controllers, and it allows the creation of automatic GUI's, randomization, snapshots and other convenient tricks for interacting with them in complex and fun ways.

Features

  • Easily design parameters or full instruments
  • Automatic gui creation based on parameters
  • New type of spec: ArrayedSpec for parameters made from arbitrary lists/choices (including non-numeric objects)
  • Automatically map a normalized input (0.0-1.0) to any parameter range, included parameters of multiple choice (ArrayedSpec)
  • Presets and snapshots for saving/restoring parameter states
  • Randomization and per-parameter locking to protect values from randomize/preset changes
  • Pattern-native single parameters: Pparam / PparamDef. Advanced versions of Pdefn with spec built into them, and other features.
  • Pcontrol / Pctrldef: event-pattern instruments with embedded Pparams and automatic GUI
  • ParamFuncSet / ParamsDef: grouped parameters with callbacks, snapshots, restore, GUI.
  • Export as MIDI from patterns
  • Def-style globals for easy live-coding access (def variants of classes)
  • Automatic GUI generation for parameters, parameter sets, and instruments
  • Unit-tested codebase with PerformativeTest.runAll() for running tests

Support

Making this took a long time and effort. If you find it useful, please consider supporting with a donation:

ko-fi

Installation

Open up SuperCollider and evaluate the following line of code: Quarks.install("https://codeberg.org/madskjeldgaard/Performative")

Classes

Generally: Most classes have a GUI and you can choose between the class and it's def-style cousin - the two versions being the same, but the latter being stored in a global dictionary for easy access for live-coding.

Terminology

All parameters respond to the following messages:

  • .set: Sets the value directly. Eg. for a frequency this could be 421.3 herz.
  • .map: Input a number between 0.0 and 1.0, automatically mapped to the appropriate range and set internally using the parameter's spec.

Specs

Specs in the standard supercollider class library describe a range, units, warping, default value, etc. for a simple number. These objects are useful for creating GUI's and generally abstracting a parameter's values to a normalized range of 0.0 to 1.0.

Performative adds an extra kind of spec called ArrayedSpec which lets you use a list of choices of objects of any kind, instead of a range of numbers.

An ArrayedSpec can contain any object, which allows enormous flexibility in the parameters in this library.

a = ArrayedSpec([\hey, \ho, \yo])

a.map(0.0) // -> hey
a.map(0.5) // -> ho
a.map(1.0) // -> yo

ParamFunc: A simple parameter object

ParamFunc GUI

An object that represents a parameter: It has a spec defining it's range, etc., an automated gui, randomization, locking (to avoid parameters being changed by randomization or snapshot recalls / presets (see further down)). It's defined with a callback function that is called every time the output parameter changes and passed the mapped value and the object itself. This component and its GUI is used to represent any single parameter throughout the library.

(
p = ParamFunc.new(
    {|mapped, obj|
        "New values. Mapped to spec range: %, obj: %".format(mapped,obj).postln
    },

    // A spec with fluid controls
    [10.0,20000.0,\exp].asSpec
    // Alternative: A spec with fixed choices:
    // [261, 523, 784, 1046, 1308]
);

p.set(0.1);
p.set(0.25);
p.set(0.5);
p.set(0.75);
p.randomize();
p.gui;
)

Pparam / PparamDef: A pattern parameter

Pparam

Pparam and it's def-style cousin PparamDef are pattern-based parameters. They can be used to allow live-coding/changing a parameter inside a pattern for example, to make that pattern controllable from the outside. It has the same gui as ParamFunc and is a standard PatternProxy, so its changes may be quantized to the clock to synchronize it with your music.

(
// Make a parameter for freq
p = Pparam.new(500, Spec.specs[\freq]);

// Quantize changes to every beat
p.quant_(1);

s.waitForBoot{
    Pbind(\freq, p).play;
}
)

p.gui;

Since a parameter may contain an array of any kind of object, it also allows making a parameter consisting of patterns or a mix of objects.

Here is an example of a parameter that contains melodies and chords:

(
// Use patterns for the parameter
var choices = [
    0,
    4,
    5,
    Pseq([0,2,4],inf),
    Pseq([5,4,2],inf),
    Pseq([0,5,4,2,5,7],inf),
    [0,2,4,6]
];

p = Pparam.new(choices.first, choices);

s.waitForBoot{
    Pbind(\degree, p, \dur, 0.25).play;
}
)

p.gui;

Pcontrol / Pctrldef: Instruments based on Event Patterns

Pcontrol

Pcontrol and it's def-style cousin Pctrldef are instruments based on Event Patterns. They contain parameters (Pparams), have an automatic GUI and an environment for sharing the data from the parameters to the pattern. They are defined with an initial function that is called to construct the final pattern, this function is fed the object itself which allows easy access to all the parameters defined in it.

It comes with an automatic GUI that allows controlling all parameters, randomizing them, locking them, etc.

Features:

  • Parameters and Pbind in one easy to use environment
  • Presets: Save/load presets
  • Export as MIDI: Create a midi file from the pattern
  • GUI with controls for each parameter, automatically made from the defined parameters, also including an overall control section with randomization and preset management
(
// Create a Pcontrol
Pctrldef(\myinstrument, { |pc|
    pc.addParam(\degree, 0, [-10,10, \lin, 1].asSpec);
    pc.addParam(\amp, 0.1, [0, 1, \lin].asSpec);
    pc.addParam(\scale, Scale.major, [Scale.minor, Scale.major, Scale.melodicMinor]);

    Pbind(
        \scale, pc[\scale].trace,
        \degree,  pc[\degree].trace,
        \amp, pc.at(\amp).trace,
        \dur, 0.25,
    )
});

// Create and show the GUI
Pctrldef(\myinstrument).gui;

s.waitForBoot{ Pctrldef(\myinstrument).play };
)

ParamFuncSet / ParamsDef: A set of parameters that can control anything

ParamFuncSet

Encapsulates a collection of parameters for easy access and management. Each parameter is a ParamFunc with a callback function that is called every time the parameter changes. This allows you to easily create a set of parameters that can be used to control anything you want, for example a Pbind or a MIDI output, etc. It also has snapshot and restore functionality that allows you to save and restore the state of all parameters in the set, as well as a GUI.

The def-version is simply called ParamsDef.

(
p = ParamFuncSet();
p.add(\freq, {|mapped, obj| "Freq mapped: %, obj: %".format(mapped, obj).postln}, [10.0, 20000.0, \exp].asSpec);
p.add(\amp, {|mapped, obj| "Amp mapped: %, obj: %".format(mapped, obj).postln}, \amp.asSpec);
p.add(\yoyoy, {|mapped, obj| "Yoyo mapped: %, obj: %".format(mapped, obj).postln}, [\hey,Β \yo, \hi]);
p.gui;
)

p.randomizeAll()
p.snapshot(\one)

p.snapshots[\one]

p.randomizeAll()
p.snapshot(\two)

p.restoreSnapshot(\one)

p[\yoyoy].set(\hey);

p[\freq].set(0.5);

Development

To make this library as robust as possible, everything is automatically tested with unit tests. Any time changes are made, it should be reflected in the test-suite to make sure that this remains a solid and trust-worthy foundation for performance- and composition-setups.

To test all classes, in SuperCollider run:

PerformativeTest.runAll();

If you experience bugs or issues, please open an issue on codeberg.

About

πŸ„ Design performative parameters, instruments and composition setups in SuperCollider

Topics

Resources

Code of conduct

Stars

7 stars

Watchers

0 watching

Forks

Releases

Contributors

Languages