CuePlayer

Organise and execute cues for real-time and mixed electronic works

Description

The CuePlayer is useful for real-time and mixed electronic works (possibly involving acoustic instruments) when the composer wishes to build a series of processes (cues) and execute them one after another during the course of a piece. The cues are initially organised into an Array, and later on they may be triggered via code, a GUI window or any device/software which outputs midi/osc data, such as a footpedal or a Digital Audio Workstation.

There are lots of features which make the CuePlayer useful for composing in-studio and performing on-stage electroacoustic works using SuperCollider. Please read below and go through this short CuePlayer Tutorial for more information.

Class Methods

*new

Create a new CuePlayer instance

*globalClock

Returns the global clock. See useGlobalClock.

Inherited class methods

12 methods from Object ► show

Instance Methods

-tempo

-tempo = bpm: 120

Set the tempo. Processes may be evaluated with reference to this clock.

Arguments:

bpm

Beats per minute.

Returns:

Beats per minute.

 

-put (cueNumber, function, timeline, timelineOptions)

Put cue at cue-number, replacing what is there.

This allows explicitly to create a cue at a specific cue-number. Simply construct your cue as a function and then assign it to a cue-number; (think of the cue-number as the index of the cue-list which holds all processes).

Arguments:

cueNumber

The cue-number to register the function.

function

An instance of Function or a String representing the path of an scd file; it must return a function.

timeline

An instance of Array with time - function pairs, (time is in beats or optionally in seconds). Alternatively a String representing the path of an scd file. The file must return an Array of time - function pairs, like [ 0, { }, 1, { } ]. See Timeline and the examples at the end of this document.

timelineOptions

An event of timeline options. See Timeline.

// This is how to make cues at specific cue-numbers.

a =
CuePlayer.new; // Create a new CuePlayer instance

a
.put(1, { "do something".postln }); // Define 1st cue.
a
.put(2, { "this is the 2nd cue".postln }); // Define 2nd cue.
a
.put(5, { "& this is the 5th cue".postln }); // Define 5th cue.

 

-add (function, timeline, timelineOptions)

Add a cue at the end of the cue-list.

Arguments:

function

An instance of Function or a String representing the path of an scd file; it must return a function.

timeline

An instance of Array with time - function pairs, (time is in beats or optionally in seconds). Alternatively a String representing the path of an scd file. The file must return an Array of time - function pairs, like [ 0, { }, 1, { } ]. See Timeline and the examples at the end of this document.

timelineOptions

An event of timeline options. See Timeline.

 

-trigger (cueNumber: 1)

From superclass: Cues

Trigger a cue.

Arguments:

cueNumber

An integer which corresponds to the function (cue) to evaluate.

a = CuePlayer.new; // Create a new CuePlayer instance

// Define cues 1 & 2
a
.put(1, { "this is cue one".postln });
a
.put(2, { "this is cue two".postln });

// Trigger cues
a
.trigger(1); // trigger cue 1
a
.trigger(2); // trigger cue 2

-blockTrigger (interval: 0.3)

From superclass: Cues

Filter out triggers that occur too fast.

When the CuePlayer receives a new trigger within less time than the blockTrigger's value, it neglects it. This avoids the piece moving forward by mistake, for example when a footpedal is rapidly pressed twice by accident.

Arguments:

interval

A number. Default is 0.3 secs.

 

-setCurrent (cueNumber)

From superclass: Cues

Set current cue.

Arguments:

cueNumber

An integer which corresponds to the function (cue).

 

-next

From superclass: Cues

Trigger next cue.

-gui (monitorInChannels: 2, monitorOutChannels: 8, options)

Create a GUI window for the CuePlayer.

This method brings up a convenient window allowing the user to control the CuePlayer from a Graphic User Interface. Through the window the user can monitor input/output buses, trigger cues, use a timer and a metronome and control the server's level.

Arguments:

monitorInChannels

An integer (0 - 8) for creating input level meters.

monitorOutChannels

An integer (1 - 48) for creating output level meters.

options

An event of one or more options.

b = CuePlayer.new; // Create a new CuePlayer instance

// Bring up the CuePlayer window.
b
.gui(
    monitorInChannels:
5, // Monitor 5 input channels
    monitorOutChannels:
24, // Monitor 24 output channels
    options:
(
        monitorInOffset:  
2, // Offset input monitoring by 2; (hence monitor inputs 3,4,5,6,7 here)
        largeDisplay:
true, // Show/hide the big window displaying current cue-number. Useful for the performers on stage.
        largeDisplayBounds:
Rect(600, 300, 450, 450), // Set bounds of the big window.
        left:
1200, // Left bound of the CuePlayer window.
        top:
300, // Top bound of the CuePlayer window.
        timer:
true, // Show/hide timer
        metronome:
true, // Show/hide metronome
        serverControls:
true, //  Show/hide server controls: mute-button, volume-slider, Peak CPU, Number of Synths
        shortcuts:
false // Use shortcuts; default is false
   
)
);

-midiTrigger (note: 60, channel: 15)

Set up a midi-trigger on a given note and channel to trigger the next cue. This allows to evaluate sequential cues upon receiving a midi-note through a specified midi-channel. Default note is 60 (middle C) transmitted via channel 15. See also the CuePlayer Tutorial.

Arguments:

note

The midi-note which the CuePlayer listens to in order to trigger the next cue.

channel

The midi-channel.

// Create a new CuePlayer instance & bring up the GUI
a =
CuePlayer.new;
a
.gui;

// Connect all midi devices & set up a midi-trigger for the CuePlayer
MIDIIn.connectAll;
a
.midiTrigger(note: 60, channel: 15);

// Ready to trigger cues from an external midi-device hooked up on channel 15 upon sending note 60.

-midiTriggerVelocity (note: 60, channel: 16, offset: 0)

Set up a midi-trigger on a given note and channel to trigger a cue based on the note's velocity value. This allows to evaluate specific cues upon receiving a midi-note; the velocity (1-127) controls the cue-number. Default note is 60 (middle C) transmitted via channel 16. See also the CuePlayer Tutorial.

Arguments:

note

The midi-note which the CuePlayer listens to.

channel

The midi-channel.

offset

Add a constant to the specified cue-number. Useful when more than 127 cues are needed.

// Create a new CuePlayer instance & bring up the GUI
a =
CuePlayer.new;
a
.gui;

// Connect all midi devices & set up a midi-trigger for the CuePlayer
MIDIIn.connectAll;
a
.midiTriggerVelocity(note: 60, channel: 16, offset: 0);

/* Ready to trigger cues from an external midi-device hooked up on channel 16
based on the note's velocity value. */

-clearMIDI

Clear all MIDI functions defined with midiTrigger and midiTriggerVelocity.

-oscTrigger (path: '/cueTrigger')

Set up an Open Sound Control trigger. This allows to evaluate a cue upon receiving an OSC message. Default path is '/cueTrigger'. Default message is -1 which will trigger the next cue; any other positive integer will trigger the respective cue. See also the CuePlayer Tutorial.

Arguments:

message

An OSC message.

(path)

A Symbol indicating the path of the OSC address.

// Create a new CuePlayer instance & bring up the GUI
a =
CuePlayer.new;
a
.gui;

// Define cues 1, 2 & 3
a
.put(1, { "this is cue 1".postln });
a
.put(2, { "this is cue 2".postln });
a
.put(3, { "this is cue 3".postln });

// An OSC responder
a
.oscTrigger

// Test it
m =
NetAddr("127.0.0.1", NetAddr.langPort); // Create a net address
m
.sendMsg("/cueTrigger", -1); // Send a message to trigger next cue
m
.sendMsg("/cueTrigger", -1); // Trigger next cue
m
.sendMsg("/cueTrigger", -1); // Trigger next cue
m
.sendMsg("/cueTrigger", 2); // Trigger cue 2
m
.sendMsg("/cueTrigger", 3); // Trigger cue 3

-freeOscTrigger

Free the OSC trigger mechanism.

-sendOSC (ip: "127.0.0.1", port: 8000, msg)

Send an open sound control message to a network address. See also the CuePlayer Tutorial.

Arguments:

ip

The IP number, like "127.0.0.1".

port

The port number, like 57110.

msg

The message, like ["/play", 1].

a = CuePlayer.new; // Create a new CuePlayer instance

// Send messages (possibly to control a DAW).
// ip/port/message need to be adjusted to match the software's specs.
a
.sendOSC("127.0.0.1", 8000, ["/play", 1]);
a
.sendOSC("127.0.0.1", 8000, ["/pause", 1]);

-clock

-clock = value

Return the clock currently in use by this CuePlayer instance.

Returns:

A TempoClock instance.

 

-useGlobalClock

Use the common clock. This is a TempoClock used by all CuePlayer instances. Useful when multiple synced CuePlayers are needed.

NOTE: Current GUI implementation for this feature is under development.

-plot (cueNumber)

Provides a visual representation of the selected timeline items. It is applicable only when using timelines. See put and add methods.

Arguments:

cueNumber

An integer. If a timeline is provided, it plots the items in the selected cue-number.

-enableLiveReload

Enable live reloading of scripts provided as path strings. See put and add methods.

-disableLiveReload

Disable live reloading of scripts provided as path strings. See put and add methods.

-guiInstance

Return the instnace of CuePlayerGUI used by this CuePlayer.

 

Inherited instance methods

6 methods from Cues ► show
329 methods from Object ► show

Undocumented instance methods

-addTimelineToRegister (cueNumber, timeline)

-oscTriggerInform (path, message)

-sched (time, function)

-timelineRegister

Examples

/* ************************************************************************ */
// Using few basic methods

// Define a SynthDef to play with
(
SynthDef(\fsosynth, {
   
arg fundamental = 120, harmonics = #[0.5, 1.19, 1.5, 4], dec = 4;
   
var signal, envelope, delay;
    signal =
Mix.ar( FSinOsc.ar( fundamental * harmonics, mul: 0.07) );
    delay =
DelayN.ar(signal, delaytime: SinOsc.kr(15, mul: 25/SampleRate.ir, add: 50/SampleRate.ir ));
    envelope =
EnvGen.kr(Env.perc(attackTime:0.1,releaseTime: dec), 1, doneAction: 2);
   
Out.ar( [0,1], (signal + delay) * envelope)
   
}
).store;
)

// Create a new CuePlayer instance & set its tempo
a =
CuePlayer.new;
a
.tempo_(130);

// Build the cues
(
// Define cue-1
a
.put(1, {
   
Synth(\fsosynth, [\fundamental, 146]);
});

// Define cue-2
a
.put(2, {
   
Synth(\fsosynth, [\fundamental, 97, \harmonics, #[0.5, 1.19, 1.5, 8] ]);
});

// Define cue-3
a
.put(3, {
   
Pdef(\pattern, Pbind(\instrument, \fsosynth, \fundamental, 110, \dec, 0.5, \dur, 1 )).play(a.clock, quant:[1]);
   
// Play the pattern at the CuePlayer's clock
});

// Add a cue at the end of the cue-list, (here it equates with cue-4)
a
.add({
   
Pdef(\pattern).clear;
});
)

// Now, evaluate one by one
a
.trigger(1); // trigger cue 1
a
.trigger(3); // trigger cue 3
a
.tempo_(100); // change the tempo
a
.setCurrent(1); // set current cue to 1 ...
a
.next; // trigger next cue (i.e cue-2)
a
.trigger(4); // trigger cue 4

/* ************************************************************************ */
// Using the GUI

// Bring up the window and control the CuePlayer from its GUI
a
.gui(
    monitorInChannels:
4, // Monitor 4 input channels
    monitorOutChannels:
16, // Monitor 16 output channels

    options:
(
        largeDisplay:
true, // Show the big window displaying current cue-number.
       
// Useful for the performers on stage.
        left:
1300, // Left bound of the CuePlayer window.
        top:
300, // Top bound of the CuePlayer window.
   
)
);

/* ************************************************************************ */
// Using a timeline

// Put a timeline at cue-5
a
.put(5,
   
{"a timeline".postln},
    timeline:
[
       
1, {Synth(\fsosynth, [\fundamental, 174, \dec, 0.4 ])},
       
2, {Synth(\fsosynth, [\fundamental, 220, \dec, 0.4 ])},
       
3, {Synth(\fsosynth, [\fundamental, 130, \dec, 0.4 ])},
       
4, {Synth(\fsosynth, [\fundamental, 146, \dec, 0.4 ])},
       
4.5, {Synth(\fsosynth, [\fundamental, 174, \dec, 0.4 ])},
       
5, {Synth(\fsosynth, [\fundamental, 220, \dec, 0.4 ])},
       
5.5, {Synth(\fsosynth, [\fundamental, 130, \dec, 0.4 ])},
       
6, {Synth(\fsosynth, [\fundamental, 146, \dec, 1 ])},
       
8,{Synth(\fsosynth, [\fundamental, 293, \dec, 3 ])}
   
],
    timelineOptions:
(quant: 1)
);

// Trigger cue-5 with the following code or via the GUI
a
.trigger(5);

// Plot the timeline's events
a
.plot(5);

// Alternatively you may save the timeline (as an Array of time - function pairs) in an scd file and point to its path.
a
.put(6,
   
{"read timeline from an scd file".postln},
    timeline:
PathName(CuePlayer.class.filenameSymbol.asString).parentPath +/+ "HelpSource/Classes/timeline" +/+ "score.scd",
    timelineOptions:
(quant: 1)
);

a
.trigger(6);
/* ************************************************************************ */