1.1 A Syd Tutorial|
1.2 Where to go from here
2.0 Basic Unit Descriptions|
2.1 Sound Generating Units|
2.2 Sound Modifier Units
2.3 Structure Units
2.4 Score Units
4.0 Menu Commands|
JSyd is an update to Syd, a program I wrote in C on both Macintosh and Windows computers. Since I first wrote the Macintosh version of Syd in 1997, Macintosh computers have changed significantly (changing CPUs and Operating Systems) and the original version of Syd no longer works. I decided to simplify my life by rewriting Syd in Java, so that it will work on Macs, Windows and Linux machines.
JSyd is fundamentally the same as the original Syd with only a few (mostly cosmetic) changes. It reads and writes the same patch file format.
When you modify a unit, options no longer appear in pop-up windows, instead there is a properties panel for editing units.
I have increased the size of the icons from 32 pixels to 64 pixels, and redrawn the interface artwork.
A new Module "SkiniScore" will read score files in the Skini format.
I have added a new "zap-link" feature which causes modules to automatically connect to nearby modules when you drag them around. This can make it simpler to set up patches. To disconnect two modules, drag the module on the left quickly to the left.
First of all, I'd like to say hi to any CalArtians who are reading this - I attended that fine institution (music composition) from '80 to '84.
Those days were pre-MIDI for CalArts, but they did have two analog electronic music studios which featured Buchla 200 synthesizers, which were maintained by John Payne who must have had a love/hate relationship with them.
I am now a computer programmer with a small collection of digital toys, but I miss those days of patch cords, razor blades and 2-track tape immensely.
One weekend, in late March of '97, in a fit of nostalgia, I decided to write a software synthesis program for my Mac that would share some interface elements with the Buchla 200. Working Buchla 200s are hard to come by, and I wanted to recreate the experience of patching modules together and hearing the results. So I spent the weekend writing the first version of Syd. By the end of the weekend, I had a simple patchable interface working that was capable of generating some interesting sounds.
I've since spent considerably more than a weekend working on it, and have learned a bit more about digital audio. After learning about CSound and other Music-N languages, I incorporated some of the features in those languages, while still trying to retain some of the ease of use that the graphical "patch" interface provides.
I believe there are a few trends which prevent serious computer music tools from reaching a wider audience. One of them is that these tools have an unnecessary level of complexity, which is primarily due to historical precedent - performance considerations forced programmers to make systems which are awkward to use. CSound and similar systems are only easily understood if you are nearly knowledgeable enough to have programmed them yourself. Music compilers don't need to be this complex. The increasing speed of desktop computers should enable us to rethink how we approach these tools.
I'd like to offer the source code of this program to other interested
amateurs - for any hobbyists who wish to tinker around with a digital
synthesis program. You can find the latest version of the source code at the Syd website:
Also, if you develop some interesting sounds, I'd like to hear them - feel free to send me a copy of your patches.
Syd, short for "Synthesis Demonstration" or "Synthesis Donut" is an instrument editor and software synthesizer. You can find the latest version of Syd here:
Syd is still very much a work in progress. I am making it with the following goals in mind:
The main interface in Syd is graphical. You create "patches" (algorithms for creating sound) by dragging the "modules" at the top into the large central area of the window. These modules are "patched" together using patch cords.
The patch cords indicate the direction of signal flow. In Syd signals generally flow either to the right or down. When a patch cords is coming out of a module, depending on the angle of the patch cord, it will either be coming out of the right side, or out of the bottom. On the other end, the patch cord will be "going in" to the left side or the top of another unit.
In this quick tutorial, we're going to create a simple FM-controlled oscillator.
You'll notice as you slide the mouse over the modules at the top, that each one identifies itself in a tool tip that pops up when rest the mouse for a few seconds. Similarly, once you've constructed your patch, each element unit and patchcord will identify itself in this way, helping you keep track of what's what.
You'll notice there is already an output unit (the one with the speaker icon) in place. All patches require an eventual output, so this is already placed for you.
To add an oscillator, click on the oscillator icon (the second unit from the left with the sine wave on it) and drag the oscillator unit down into the main working area.
To patch the oscillator to the speaker, position the mouse over the right edge of the oscillator unit until the cursor changes into a phono-plug. Then click and drag, connecting the oscillator unit to the speaker unit. When you drag over the speaker unit, the speaker unit will highlight itself. Release the mouse. You'll see that the oscillator and speaker are now connected with a patch cord.
Alternately, if you simply drag the oscillator close to the speaker, a lightning bolt will connect it to the speaker. Release the oscillator to keep this connection.
Congratulations! You've made your first patch. Let's listen to it.
To synthesize the sound, hit the "Synthesize" button (The S Icon on the upper left). Synthesis should end fairly quickly, since this is a simple patch.
After synthesis is done, you can listen to it by hitting the "play" button (the arrow icon next to the Synthesize button).
What you're hearing is a sine-wave oscillation beating at 440 times a second. The entire sound lasts for 2 seconds. If you'd like to make the sound last longer, click on the output unit (the "speaker") - some options will appear in the properties panel in the bottom-half of the window. In the properties panel, change the "duration" value to some other time (how about 10.53 seconds?). You'll also notice that the sound is being saved to a file called "untitled.wav". You can change the file name here as well. Then press the synthesize button and play it again. Aren't sine waves lovely?
Now, let's lower the pitch of the oscillator. Click on the oscillator again to change it's properties. In the properties panel, change the "Frequency" value from "440" (the default) to "220". Then synthesize and play again.
When you synthesize a sound, a graphical representation of it appears in the bottom panel. The waveform panel responds to mouse clicks and a few keystrokes as follows:
|Click||Zoom into the area clicked.|
|Click-drag||Zoom into the area defined by the drag.|
|Ctrl-Double Click||Zoom all the way out|
|Right-Double Click||Zoom all the way out|
|Alt-Click||Scroll left and right|
Now try creating a second oscillator and patching it to the first oscillator. Drag the second oscillator to the left of the first oscillator. A lightning-bolt will automatically connect it to the first oscillator. Release it.
Modules typically have one output, and one or more inputs. Different color patch cords correspond to differing inputs.
Once you've patched the two oscillators together, pass the mouse over the patch cord going from the new oscillator to the old oscillator. You'll see from the tool tip that the patch cord is going in to the Amplitude Modulation (am) input of the first oscillator. Right-click on the patch cord and use the pop-up menu that appears to change it to go into the Frequency Modulation (fm) input of the oscillator. You'll see that once you've changed the assignment from "am" to "fm", the color of the patch cord will change from blue to green. Eventually you'll learn to recognize green patch cords at a glance as "fm" patch cords.
Once the patch cord is assigned to the "fm" input of the right-most oscillator, you can refer to it's value within the right-most oscillator by editing that oscillator's settings. Click on the right-most oscillator again. A dialog will appear.
Change the "frequency" setting from "220" to "220+fm*10", this will cause the oscillator to use the "fm" input to modulate it's frequency. Hit the "OK" button, synthesize and play the sound again.
It's worth noting at this point that you didn't really need to change the patch cord from "am" to "fm". You could have left it at "am" and then used the formula "220+am*10" - this would have had the same effect. The main purpose of changing the patchcord is to provide you with a visual understanding of what is going on. Since we're using the signal to modulate the frequency, "fm" is more appropriate. For some units, however, the choice of input does indeed make a difference. For example, on the filter units (and most other signal modifiers) the signal that is being filtered must always go in the "sig" input, while signals which are used to control the filter should go in the "ctl" inputs.
At this point, probably the best way to learn more about Syd is to try some of the sample patches that have been included. Some have been designed to demonstrate particular features of the program, while others were included because they demonstrate particular synthesis styles. The "Patches" folder contains a file called "AAA_READ.ME" that describes each of these sample patches. I recommend reading this file and select a patch that sounds interesting to you.
You can load any of these patches via the file menu (you may edit multiple patches simultaneously in Syd) or simply double-click on the patch's icon in the finder.
After you load in the patch, listen to the sound it makes, and double click on each of it's units to see how they have been set up. If a particular unit being used in the patch mystifies you, look it up in this manual, and you'll find more information.
There are two units which are particularly interesting in Syd. One is the one that says "f(x)" on the icon - the Expression unit. This unit allows you to generate (or modify) a signal by typing in any mathematical expression - this manual describes the mathematical syntax that is used in these expressions. In addition, most of the other modules (such as the oscillator, the amplifier, the filters, the function table, and the random score module) also support expressions (in fact, you used one when you made the fm-controlled oscillator).
The other unit that is interesting is the "random score" module. This module can make a simple patch far more interesting by playing it with random values, and creating multiple notes which sound simultaneously (polyphany).
Some basic Syd units you should know about:
If you are not sure which unit is which, position the mouse over the unit in question at the top of the window - a pop-up tool tip will indicate the name of the unit.
The oscillator is the basic waveform generator.
It accepts general expressions for frequency, amplitude and phase. In addition you can optionally use an expression to define the waveform, in this expression, "t" will represent the position in the waveform from 0 to 1. You can create waveforms which vary over time using the variable "g" which represents global time.
|This controls the frequency, or pitch of the oscillation.|
|This controls the amplitude, or loudness of the waveform.|
|This controls the initial phase of the waveform. It is expressed in radians (0 - 2pi). Larger values will "wrap over".|
|Wave Type (radio buttons)|
|This controls the type of waveform.|
|Waveform Expression (expression)|
|When the Wave Type is set to "Expression" - this expression determines the wave shape. In this expression, "t" represents the position in the waveform from 0 to 1. You can create waveforms which vary over time using the variable "g" which represents global time.|
The frequency (like most of the other settings) can either be a constant, such as "440" or it can be an expression. For example, to make an FM controller oscillator, you could set Freq to "440+fm*0.1" which would cause it to use the incoming FM signal to modify the frequency.
There are some pitch conversion functions which allow you to specify pitch in different ways, for example, by MIDI note number, or by octave and step, see below.
The WaveType can either be a fixed waveform such as a sine, square, triangle or sawtooth wave; or it can be computed using an expression you provide. For example, the following expression makes a sine wave with two harmonics.
Generates a plucked-string sound using the Karplus/Strong algorithm.
These sounds are generated by filling a buffer with random values and
then smoothing the values over time. This generates an interesting
sound and has the added benefit of being extremely fast.
|Currently no effect - I will eventually support both plucked string sounds and drum sounds.|
|Frequency (pitch) of the sound. See the section on oscillators for a discussion of frequency.|
|Amplitude (loudness) of the sound.|
|How long the sound should last.|
|Controls the decay factor, or how quickly the harmonics drop out of the sound.|
Generates a maraca-like sound using Perry Cook's Maraca simulation
algorithm, which appeared in the Fall '97 Computer Music Journal (Vol
|The resonating frequency of the Maraca shell. Raising this frequency will make the Maraca sound smaller. Lowering it will make it sound bigger.|
|Controls how narrow the resonating frequency band is. The default value works nicely.|
|Controls how often the "beads" hit the "shell". Increasing this value will make the maraca sound like it has more beads.|
|Controls how fast the "beads" lose energy after the initial "shake". Raise this value to create an "anti-gravity" maraca.|
|Controls how fast the sound decays after the beads hit the shell.|
Reads a sample (AIFF or WAV) file and outputs the sound contained in the file.
|File (file spec)|
|Name of the sample file to playback.|
|Determines speed of playback. 1.0 is normal speed.|
Generates random values from 0-1. Note: In an expression, the symbol "?"
produces the same kind of signal.
|Provides a seed for the random number generator.|
|If true, a random seed will be chosen based on the system time.|
Expressions can be used both for generating and modifying sounds.
The expression syntax used by the Expression Unit also applies to the input fields of most of the other units (unless those fields are described in this manual as accepting "Constants").
See section 3.0 for more on expressions.
|The expression to compute.|
These signals can be referred to in the expression.
The HammerBank simulates a piano-like instrument with 128 strings, which
are activated by hammers, and have dampers. The action of the hammers
and dampers is triggered using one or more Hammer Actuator Units, see
below. These units can be used to simulate an instrument which has
sustain properties which are triggered independently of the notes. Most
of the fields take expressions which can use the "k" variable (key
number) to create characteristics which change relative to the register
of the key.
See the "HammerTest" patch for an example of a HammerBank in action.
|The number to assign to this bank (used by HammerActuators).|
|This is used to compute the key to frequency function. cpsmidi(k) will produce an equal tempered tuning which corresponds to MIDI note number, but you can use alternate tunings if you like.|
|This is used to compute the relative amplitude of each key. A value of 1.0 will produce an even amplitude across the whole keyboard.|
|This is used determine the length of the attack after the hammer strikes the string.|
|This is the decay coefficient which represents the amplitude of the note 1 second after the hammer has struck, using an exponential decay. On a real keyboard, lower notes will have a longer decay. You can accomplish this by making this value a function of k.|
|This is an expression which is computed during signal generation to determine if sustain is on, which causes all strings to behave as if they are undamped. You can simulate the effect of a sustain pedal by triggering this with a G variable from another instrument. Set this to 1 if you want permanent sustain.|
|If no input instruments are used, the module will use this expression to generate the waveforms for each string, it is equivalent to an internal oscillator.|
If provided, this input instrument will be cloned, once per string, to provide the sound, rather than using the internal waveform function. The amplitude of this instrument will be automatically scaled by the energy value of the string. Instruments 2 and higher are not yet supported.
This unit can be used to activate the hammers and dampen/undampen the
strings of a Hammer Bank unit (see above). See the "HammerTest" patch
for an example. Multiple Hammer Actuators attached to a single note
event can be used to create "sympathetic resonance" effects. In a
typical configuration using a Score unit, a single HammerBank will sound
throughout the entire piece, while Hammer Actuators will be triggered
for each note event.
See the "HammerTest" patch for an example.
|The Hammerbank to affect.|
|The key to strike or undampen. This should be a number from 0-127.|
A trigger signal which causes this actuator to trigger. To strike a key
at the beginning of a note event, use a value of "1". To cause a key to
be damped at the end of a note event, provide a value which will go to 1
near the end of the note event, such as cond(t|
|The force with which to strike the key (a value from 0 to 1). This value is added to the key's current energy, over a time interval set by the key's attack period.|
|Indicates whether the key should be damped (0) or undamped (1).|
Amplifies or attenuates the input signal, and then adds an offset value.
|A constant or time varying formula to scale the amplification.|
|An offset to add after amplification.|
|The signal to be amplified|
Control signals which can be used to create time-varying amplification
For example, to scale a sawtooth wave (which normally outputs values from -1 to 1) to output values from 0 to 1, use a scale of .5 and an offset of .5
|Envelope Generator (ADSR)|
This is a bare bones ADSR envelope generator.
Attack Time (constant)|
Attack Level (constant)
Decay Time (constant)
Decay Level (constant)
Sustain Time (constant)
Sustain Level (constant)
Release Time (constant)
|These control the overall shape of the envelope, determining the timing and value for 4 different amplitude levels (the last one is assumed to be zero). All these fields must be constants, not expressions.|
|This is the overall duration. Typically, the envelope values should be expressed so that the envelope takes one second. Than this value can be used to stretch or shrink the envelope.|
It is common to patch an Envelope Generator into a function table to generate a table with the envelope values in it. An oscillator can use the values in the function table with an expression like: "p4*ftab(p5,t/p3)" in which p4 is the overall amplitude of the note, p3 is the duration of the note and p5 is the function table number.
Envelopes used with function tables should have an overall length of 1. Envelopes used directly with notes should have an overall length equivalent to the duration of the note (commonly p3). For the most flexibility, the ADSR times should assume an envelope with a length of exactly 1 second, so the duration field can be used to scale it to arbitrary lengths.
This module is used to mix together and attenuate multiple signals which
might otherwise cause clipping when added. The output signal is
attenuated based on the number of input signals.
The Mixer module will always attentuate the signal if more than one signal is coming into it. If you would simply like to add some signals together, you can simply patch them all into the same input. In some cases, it is useful to add them together before patching them somewhere (for example before patching into a score, so as to reduce to a single instrument). In this case, you can use an Amplifier with a gain of 1.0 to add units together.
|Filter (2nd Order Section)|
This module is used to create a common kind of filter called a 2nd-order
Section. Such a filter can be expressed as outputting a series of vaues
y[0...N] based on a series of input values x[0...N] with the following
y[n] = a0*x[n] + a1*x[n-1] + a2*x[n-2] + b1*y[n-1] + b2*y[n-2]
Note: The "classic" 2nd order section uses subtraction, rather than
addition for the "b1" and "b2" terms. If you want this, use negative
values for the b1 and b2 coefficients.
If you are looking for a more "musical" filter that is easier to
understand, I suggest using the Butterworth filter (see below).
|These are the coefficient values for the filter. They can be time-varying expressions, or constants.|
This is the signal you wish to filter
These are for control signals which can be used to modify the
coefficients, creating time-varying effects such as filter sweeps.
This unit implements lo-pass, hi-pass, band-pass and band-reject
|Filter Type (pull down menu)|
|Allows you to select the type of filter you want. The default is band-pass.|
|For lo-pass and hi-pass filters, this is the cutoff frequency. For band-pass and band-reject filters, this is the center frequency.|
|Only relevent for band-pass and band-reject filters - this is the width of the band on each side of the center frequency. It is commonly expressed as a percentage of the center frequency.|
This is the signal you wish to filter
These are for control signals which can be used to modify the
coefficients, creating time-varying effects such as filter sweeps.
A simple delay unit. The output y[n] is expressed as (a0*x[n] +
|Controls the length of the delay between the initial sound and it's first reverberation - expressed in seconds. If the delay is too large, you may run out of memory. You can use time-varying expressions (a time-varying delay will cause pitch shifts).|
|Controls the gain of the original signal.|
|Controls the gain of the delayed signal.|
|If true, this causes the delayed signal, rather than the original signal to be stored in the delay line (making this an IIR rather than a FIR filter). This creates multiple repeats, which are useful for reverberation effects. However, keep in mind you can overload the signal if the delay gain is too high.|
This is the signal you wish to delay
Control signals which can be used to create time-varing delay effects.
Outputs 1 if the input signal is above a particular threshhold value,
otherwise, outputs 0.
|This controls the threshhold value - it defaults to 0.5.|
The signal to monitor.
|Sample and Hold|
When a trigger is received, this samples the current intput signal and
continues to output that value until the next trigger is received. Try
using a square wave oscillator for a trigger.
|The signal to sample.|
The trigger signal - when this signal goes over 0.5, it will cause the
next sample to be stored.
Inverts the signal by inverting its sign (multiplying by -1).
The signal to invert.
Smoothes the signal by averaging subsequent values. This is a simple
lowpass filter where y[n] = (x[n]+x[n-1])/2. For more predictable and
controllable effects, use the (slower) Butterworth filter.
The signal to smooth.
The following units control the overall structure and form of the patch, rather than generating or modifying audio signals directly.
There is always at least one speaker unit. This is meant to be the
final terminus for the patch. Any signal being fed into the speaker is
"heard". As described below, the settings are only meaningful if the
patch is being used as the "main instrument". If the patch is being used
as a folder instrument, the output settings are ignored.
|memory (radio button)|
|Causes the samples to be stored in a 440k buffer in RAM. If the duration of the sound is larger than the buffer (20 seconds at 22050 sampling rate), a "sliding window" will be used so you can see the results of the whole synthesis in the graph window, and hear the whole thing, if Listen is turned on. This is a useful option for previewing long samples when you don't have a lot of free disk space.|
|aiff file (radio button)|
|Causes the sound to be stored in an AIFF file.|
|wav file (radio button)|
|Causes the sound to be stored in a WAV file.|
The overall time of the sound to be generated.
If you are using a CSound or Skini score, you would probably prefer for the score itself to determine how long the piece is. Use the "Score overrides duration" option to get this.
|sample rate (constant)|
|The sample rate of the sound.|
The signal to output.
Folders are used to encapsulate entire instruments, which are stored in
separate patch files. This makes it easier to create complex
instruments without clutter. For an example, look at the "combo.syn"
patch, which combines 2 folder instruments.
Folders are also useful for defining the instruments to be patched into a score. A score might need 10 instruments patched into it, and there isn't enough space in the patch window to fit all of them.
|The patch file to patch in.|
Inputs into the folder instrument. If the folder instrument needs some
particular parameters, this is how you pass them to it. The folder
patch file can use the "Folder Input" units (see below) to retrieve these values, or
refer to them directly in expressions (e.g. "f1*100").
Folder inputs are used to document the inputs into an instrument which
is meant to be played as a Folder Instrument. They also provide default
values for these inputs so the instrument can be tested on its own,
without having to being played as a folder instrument.
For an example, see the "quietreverb.syn" patch, which accepts a folder input.
|F number (constant)|
|Specifies which folder input to retreive, when this patch is played as a folder instrument.|
|Provides a comment to identify this signal.|
|Provides a default value to use, so this patch can be tested without being played as a folder instrument.|
|Param (Score) Input|
Parameter (Score) Inputs are similar to Folder Inputs. They are used to document
the inputs into an instrument which are meant to be provided by a Score. They
are similar to Folder inputs, but refer to the parameter values (p1,p2,p3 etc)
which are generated by a Score unit.
They also provide default values for these inputs so an instrument can be tested
without a score. See Scores, below.
For an example, see the "shepsco.syn" patch, which reads parameters from a score
file and passes them to a folder.
|P number (constant)|
|Specifies which parameter to retreive, when this patch is played by a score.|
|Provides a comment to identify this parameter.|
|Provides a default value to use, so this patch can be tested without being played by a score.|
|Global Variable Assignment|
These units are used to load values into global variables, which can then be
accessed from other instruments (using the notation g0,g1,g2 etc.). These
units output 0, so they can't be used in a path which is directly generating an
audible signal (however, you can fork off such a path to create the assignment).
|G number (constant)|
|Specifies which global variable to assign.|
|Provides the value which is to be loaded into the global variable. Typically this is a function of the signal being fed into the unit, e.g. "sig".|
|Provides a comment to identify this purpose of this variable.|
|Specifies signals which can be fed into the global variable.|
|Function Table (ftab)|
Function tables are provided as a means of speeding up calculations. A function
table's contents are precomputed when the instrument is initialized.
Subsequently, the table's contents can be accessed from any expression using the
function ftab(n,t) where "n" is the function table number, and t is a number
from 0 to 1 which accesses a particular table element. The (slower) function
ftabi() [ not yet supported ] can be used if linear interpolation between table
values is desired.
All your tables should have different numbers, and ideally, tables should not be
defined in folder instruments.
|ftab number (constant)|
|Assigns this formula to a particular global function table number. This allows the table to be addressed by various instruments using the expression ftab(n,t) where "n" is the table number.|
|ftab size (constant)|
|Determines the number of entries in the table. For control signals, larger values will prevent aliasing noise.|
|The formula used to compute the table's contants.|
This signal will be generated only when the function table is calculated. For
units patched into the function table, the "t" value will go from 0-1 as the
table is filled in, regardless of the length of the table. The ADSR units are
designed to work with function tables, although other units can be used as well.
Score units are used to create entire pieces of polyphonic music. They use the instruments that are patched into them to sound each note in a "score". Although you can patch them together as you can the other units, their behavior is considerably different. Each input into a score unit will be treated as a separate "instrument". Whenever a note is played in the score, a unique "instance" of the sub-patch that corresponds to the instrument number will be temporarily created and sounded for the duration of the note. Multiple instances of instruments allow for multiple notes to sound simultaneously, creating polyphony.
If the score refers to multiple instrument numbers, you can patch in multiple instruments - one for each type used in the score. I suggest using folder instruments (see above) for this purpose, to reduce icon clutter. In this case, you would have one patch for each instrument, and one "master" patch which shows how those instruments are assigned to the score.
Since scores allocate instances of instruments, they may cause considerable amounts of memory to be consumed. Since Syd is still not very well behaved when it runs out of memory, I suggest saving your work before hitting the "Synthesize" button.
Score modules use the same conventions as CSound score files, where the note parameters are provided in variables named p1, p2, p3 etc. The first three parameters have fixed meanings: p1 is the instrument number, p2 is the start time of the note, p3 is the duration of the note. Subsequent parameters can be used in any way you want. In a simple instrument, p4 might be amplitude and p5 might be frequency or midi note number.
Syd treats score modules just like other modules. This means that a score module can "play" another score module as an instrument, and the output can be patched into a sound module (e.g. reverb or amplifier) for post processing.
The ability to patch two score modules together is particularly useful when used in conjunction with the random score unit, which generates events based on a set of formulas. For example, one way to use the random score unit is to thicken an instrument that is being played by a CSound score - the random score can cause each note event to trigger multiple note events, each with slightly randomized parameters, turning one instrument into a whole chorus.
Random scores can also be used to correct, adjust, swap or embellish the parameter values in a CSound score, allowing it to be used with an instrument which wasn't originally designed to be used with that score. This means you will spend less time modifying instruments to work with different scores, instead, you can use the random score unit to "map" a particular score to a particular instrument.
The CSound Score unit reads a "CSound" score file and plays it using the
instruments that are patched into it. At the moment, Syd's support for CSound
scores is very minimal - function tables and ramps are not yet supported. The
sample patch "prelude_pluck.syn" shows an example of CSound score being played.
|file (file spec)|
|Specifies the CSound score (.sco) file to use.|
Instruments to patch into the score. Each note event in the score will
create an instance of the corresponding instrument which will last for
the duration of the note.
The random score unit creates a series of notes (or more accurately - "events"),
which are generated using random numbers or other formula. It has many uses,
including creating aleatoric scores, testing instruments and fattening sounds.
Various options allow you to specify the number of notes, their starting times,
durations, and other parameters.
A random score can be played by another random score. In this case, the formulas in the random score can refer to "p2 p3 p4" etc., which refer to the note values provided by the parent score which is playing it.
If an instrument isn't being played by a score module, the values of p1,p2,p3 are assigned reasonable defaults. In particular:
p1 is 1 p2 is 0 p3 is the total duration of the sound. p4 is 1.0 p5 is 440
By nesting random scores in this manner, you can achieve a great deal of complexity.
In any of the formulas used in a random score, the variable "n" refers to event number, from 0 to (#events-1).
|# Events (expression)|
|Determines how many notes (or events) will be generated. A constant like "12" will generate 12 notes. "P3*2" will generate a number of notes relative to the duration of the parent event.|
|P1 (instrument#) (expression)|
|Used to select an instrument. Instrument numbers start at 1. If you use "0", it will select the first instrument available. To alternate between two instruments, you could use "1 + n mod 2".|
|P2 (start) (expression)|
|Used to set the start time of the note. Examples are "?*p3" which makes a random start time, and "n*p3/12" which generates 12 sequential start times.|
|P3 (duration) (expression)|
|Used to set the duration time of the note. Examples are "?*p3" which makes a random start time, and "n*p3/12" which generates 12 sequential start times.|
|Used to add optional parameters, such as amplitude and frequency, to each event.|
Instruments to patch into the score. Each note event in the score will create an
instance of the corresponding instrument which will last for the duration of the
ctl,ctl1,ctl2... (still to come)
These inputs can be used to provide signals to use in your note generation
formulas. These inputs are not "instantiated" in the way the instrument inputs
The expression syntax used by the Expression Unit also applies to the input fields of most of the other units (unless those fields are described in this manual as accepting "Constants").
Any patches into a unit can be referenced by using the input variable name. For
example, the inputs into an oscillator are "am, fm, amwidth and fmwidth". These
names are provided as mnemonics for their suggested uses, the signals can be used
in any manner you wish. So for example, the pitch of an oscillator might be
specified as "440+fm", where "fm" is the input from another oscillator.
See the specific unit definitions for a description of their inputs.
The variables "p1", "p2", "p3" etc. are provided when the instrument feeds into a
Score generator (such as a Random Score unit or a CScore Score Unit). These are
the parameters provided by the instrument events in the score. Generally, p2 is
the start time of the note, p3 is the duration of the note. For the random score
unit, p4 is the amplitude (0-1) and p5 is the pitch (cps).
You can use the "P-Input" module to assign reasonable defaults to these values as a way of testing a particular instrument without a score. Otherwise, if you are not using a score, they will be assigned reasonable defaults as follows:
p1 = 1 p2 = 0 p3 = duration of sound p4 = 1 p5 = 440 all others = 0
|The variables "g0", "g1", "g2", etc are provided for storage of global variables, which allow crosstalk between separate instruments. You can store a value into a global variable using the "Global Variable Assignment" units.|
duration of piece in seconds|
mix of all input signals (e.g. "sig", "am","fm")|
For a note this is note time.
For an oscillator waveform, this is wave form position (0-1).
For a function table, this is table positoin (0-1).
For anything else this corresponds to global time.
The time relative to the note being sounded (provided by the score modules).
This has 2 possible values. For a simple unit, such as an oscillator, this refers to the time of the note being sounded. It starts at 0, at the beginning of the note, and then increments as the note progresses.
If the unit isn't patched into a score, this value will correspond to g, or
If the expression is being used to generate the notes of the random score, this value will correspond to the note number, from 0 thru n-1, which is useful for creating linear note spacing. In versions of Syd prior to 1.0.6, the variable "n" was used for this purpose, and this method is still supported for backward compatability.
If the expression is being used in a Hammer Bank unit, this value will correspond to the key number, from 0 thru 127.
If the unit is connected to a HammerBank unit, this value contains the string energy, which will start around 1.0 when the string is struck, and then decay using the decay coefficient provided in the HammerBank module.
The time relative to the section as a whole.
The current sampling rate (determined by the output module).
On Macintoshes, the pi symbolÊmay also be used (Option-P).
The value of piÊmultiplied by 2.
The constant E|
This is the base of natural logarithms.
It is equivalent to exp(1).
Random number (0 >= r < 1)|
The random number generator used is a fairly decent one, as described in Stephen K. Park and Keith W. Miller, "Random Number Generators: Good Ones Are Hard to Find", Communications of the ACM, vol. 31, p. 1192 (October 1988).
Note: At the moment, I have not designed a good mechanism for controlling random
number seeds on a module by module basis. Every time a patch is used, the random
numbers will be different.
|-||Subtraction (x - y)|
|-||Negation (- y)|
|%||Modulo (also "mod")|
|^||Raise to Power|
|and||Logical AND (also "&&")|
|or||Logical OR (also "||")|
|not||Logical NOT (also "!")|
|>=||Greater than or equal|
|<=||Less than or equal|
Syd has a fairly rich set of functions available -most of these were inherited from the expression parser that is used in my Image Processing software "Pixel Magic". This means that if you like playing with the Mandelbrot set, you can use it to generate sounds too.
functions - basic math & trig
|int(x)||Convert to Integer|
|log10(x)||base 10 logarithm|
|exp(x)||E to the x power|
functions - f tables
|ftab(n,t)||Access function table N (0+) at position T (0-1)|
|ftabw(n,t)||Access function table N (0+) at position T (0-1), wrap|
|ftabp(n,t)||Access function table N (0+) at position T (0-1), pin|
|ftabi(n,t)||Access function table N (0+) at position T (0-1), interpolate|
|ftabip(n,t)||Access function table N (0+) at position T (0-1), interp+pin|
|ftabiw(n,t)||Access function table N (0+) at position T (0-1), interp+wrap|
These functions are used to access the tables which are created by the "FTAB" units. The basic ftab() function uses the value of T to access the values of Funtion Table #N. If T is less than 0 or greater than 1, then a value of 0.0 will be returned. Otherwise, the value of T (from 0 to 1) is used to access a value from the beginning to the end of the table.
The "Pin" variant will pin to the beginning and ending values of the table, that is values less than 0 will be treated like a 0, and values greater than 1 will be treated like a 1.
The "Wrap" variant will wrap over, using the fractional part of T to access the table. So, for example, 7.1 is treated the same as 0.1.
The "Interpolating" units will use linear interpolation, which is slower, but can reduce the aliasing caused by short tables.
functions - pitch converters
These functions are typically used for converting a linear representation of
pitch to oscillator frequency which is supposed to be expressed in cycles per
second (which is logarithmic).
In the following functions, the pitch of A 440 (A above Middle C) can be represented as follows:
|cps||440||(440 cycles per second)|
|pch||8.09||(8 octaves + 9/12 of an octave)|
|oct||8.75||(8 octaves + .75 of an octave)|
|midi||69||(69th note on keyboard)|
|cpspch(x)||Convert cycles per second to pitch|
|cpsoct(x)||Convert cycles per second to octave|
|octpch(x)||Convert octave to pitch|
|octcps(x)||Convert octave to cycles per second|
|pchoct(x)||Convert pitch to octave|
|octmidi(x)||Convert octave to MIDI note|
|cpsmidi(x)||Convert cycles per second to MIDI note|
functions - signal modifiers
These functions, which are borrowed from CSound, are useful for creating
envelopes and otherwise modifying signals.
|This function computes a straight-line envelope which has a total duration of duration, an attack time of attack and a decay time of decay. The values rise from 0 to 1, and then back to zero.|
|This function computes a simple envelope with a straight-line attack and exponential decay, similar to many natural sounds. The total duration is equivalent to attack+decay. The decayval controls the rate of cutoff, and is typically around 0.01. Values which are too large will produce a noticeable click, while values that are too small will shorten the sound.|
|This function limits the value of v to fall between the values of min and max. If v < min, then min is returned. If v > max, then max is returned. If max < min then a constant value of (min+max)/2 will be returned.|
functions - fractals and noise
|mandel(x,y)||Mandelbrot Set, level set method (also mand)|
|manc(x,y)||Mandelbrot Set, CPM method|
|julia(x,y,p,q)||Julia Set, level set method|
|fbm(a,b,c,d,e,f)||Fractal Brownian Motion (broken)|
|turb(x,y)||2D Turbulence (fractal noise)|
|turb3d(x,y,z)||3D Turbuluence (fractal noise)|
|gnoise3d(x,y,z)||Alternate Noise Function|
|gturb3d(x,y,z)||Alternate Turbulence Function|
functions - misc
|cond(exp,a,b)||if exp is non zero, a, otherwise, b.|
|angle(x,y)||angle from 0,0 to x,y|
|dist(x,y)||distance to x,y|
|prime(n)||Prime number function|
|Creates a new patch document.|
|Opens an existing patch document.|
|Closes the current window.|
|Saves the current patch document to disc. If you haven't named it yet, you'll be asked to assign a name.|
|Saves the current patch document to disc under a new name.|
Exits the Syd application.|
|Most editing operations are unimplemented, except for "Clear" which deletes the selected unit.|
|Starts synthesizing the current patch.|
|Starts playing back the current patch (only works after synthesis).|
|Stops synthesis or playback.|
6/1/2006 - 8/1/2006 JSyd (Java Syd) version 1.0, ported from the C version of Syd (1.0.6).