This will:
The basic element of the Library is the unit (U ) and corresponding unit def (Udef), that play a similar role to Synth and SynthDef.
Udef Represents a synthesis defintion. It holds:
Declaring a Udef:
Declaring a Udef adds it to the a global Library of Udefs, reachable at Udef.all
, .e.g. Udef.all[\sine]
.
Udefs can be defined in plain text files containing supercollider code:
When starting up the library (ULib.startup) all the Udefs in certain folders are loaded.
You should add you own Udefs to the folder Udef.userDefsFolder
.
By default it is assumed that the SynthDefs are already written to files. If you want the SynthDef to be sent upon 'start' then use a LocalUdef.
- Represents a single synthesis process instance.
Given a symbol it will search the Udefs library for a Udef with than name.
Or
The arguments of the unit are persistent and can be set and retrieved locally (without contacting the server), even if the unit is not playing in the server(s).
Units can be grouped together in chains using the UChain object.
Each chain is a rack of units, where the output of each unit can be routed to the following unit. The routing is done using private busses, and is erased after each chain, so the output of a unit of one chain can never interfere with a unit in a different chain. Units in this context can be thought of effects or plugins in a DAW, although (almost) the full flexibility of SuperCollider is available. To get input from and output to other units in the chain the UIn and UOut pseudo-ugens are used. These ugens create automatic names for controls that allow changing the private bus number. This then allows easy re-patching of the units from a gui.
Arg names can be used as method names:
Unit arguments are not restricted to floats, or arrays of floats, they can be instances of any class (as long as the class knows how to turn itself into an acceptable synth argument).
When creating the Synths the unit will call .asControlInputFor( server, startPos )
on each of the arguments. Classes that respond to .asControlInputFor
properly, are valid argument values for a Unit.
Examples:
Extended classes:
Other objects that can behave as Unit arguments:
Each Unit argument has an ArgSpec.
The ArgSpec class has the following fields:
\sync
- set message with sample accuracy (if possible).\normal
- set message without time stamp, i.e., as soon as possible.\init
- only set when the synth is created. Changing the paremeter afterwards will not send a .set message. Usually for init rate controls.\nonsynth
- not a synth arg, not to be sent to synths. Used in MultiUdef.Ways in which specs are defined:
Explicitely:
Automatically:
setSpec:
Current Specs:
Classes | Parameters. |
ListSpec | |
StringSpec | |
SMPTESpec | |
BoolSpec | |
PointSpec | |
PolarSpec | |
RectSpec | |
RangeSpec | minRange, maxRange; |
RichBufferSpec | numChannels (number), numFrames (ControlSpec) |
BufSndFileSpec | numChannels (can be array of numbers), numFrames (ControlSpec) |
DiskSndFileSpec | numChannels (can be array of numbers), numFrames (ControlSpec) |
PartConvBufferSpec | numChannels (number), numFrames (ControlSpec) |
MultiSpec | an ordered and named collection of specs, with the option to re-map to another spec |
IntegerSpec | default = 0, step = 1, minval = -inf, maxval = inf; |
PositiveRealSpec | default = 0, step = 1, minval = 0 (can only vary between 0 and +inf), maxval = inf; |
Specs are responsible for creating the guis for the corresponding argument.
Chains can be organized in time using a UScore.
Each chain is also an event (inherits from UEvent) with a start time, duration and fade in and fade out times. Scores are played in real-time, and take care of preparing the events during for play playback (buffer loading, etc). The library provides a ScoreEditor GUI which works mostly as modern DAW: the start time can be changed by dragging the event on the timeline and the duration by dragging the end of the event. Many operations are available such as copy/paste, undo/redo, split, trim, duplicate, etc. Scores can have other scores as events, allowing for indefinite nesting of scores inside scores.
Before playback both units, chains and scores have to prepared. This is done by calling '.prepare' on either of them (preparing a score prepares all the chains within). All the preparation is then automatically taken care of, since the "smart" arguments, such as BufSndFile, know how to prepare themselves.
When playing a score it takes care of preparing all the resources and freeing them at the end.
UScores can be saved and loaded from files. UScore files are plain text files containing the SuperCollider compile string of the score.
This capability is encoded in the 'UArchivable' class:
.saveAs(path)
saves file, checks if file exists with that name..save
detects if the object has been changed since it was saved and saves it if needed to the last saved path.UArchivable.read( path )
reconstructs the object.MassEditU and MassEditUChain allow simultaneous editing of multiple Us or UChains.
MassEditU:
MassEditUChain:
Allows using UChains without a timeline and starting and stopping multiple UChains/UScores/UChainGroups at the same time.
Still work in progress.
For more complex uses, where a Udef does not provide the necessary functionality (e.g. multiple synths per unit per server) a FreeUdef class is available. By defining the 'createSynthFunc' function it's possible to have arbitrarily complex logic before instantiating the actual synth(s).
Chooses from several synthdefs using chooseFunc. Can be used for instance to create Udefs which need hardcoded number of channels.
Source code of diskSoundFile
:
It' easy to use the Unit Lib to control multiple servers at the same time. Starting a Unit will create a synth in each of the servers of the system.
Most parameters of U, UChain and UScore can be controlled via OSC.
Paremeters can be reached using the address pattern /scoreName/chainIndex/unitIndex/argName.subArg.
UnitRack's are just groups of units that have been properly configured or interconnected and can be inserted into other UChains.