662 lines
31 KiB
Plaintext
662 lines
31 KiB
Plaintext
SAU language reference
|
|
======================
|
|
|
|
SAU (Scriptable AUdio) is a simple and non-Turing-complete
|
|
language for mathematical audio synthesis,
|
|
without support for the use of pre-recorded samples.
|
|
|
|
The core idea of the language is that of time-ordered steps for
|
|
configuring audio generation: add an oscillator, then later,
|
|
change a parameter and extend play duration, etc. A script is
|
|
basically a list of such timed instructions. Language constructs
|
|
also offer more flexible arrangement of steps to take than a
|
|
bare flat list of instructions and forward time movement.
|
|
|
|
The syntax is a bit terse and unusual. It uses one-character
|
|
keywords with or without an argument, followed by zero or more
|
|
parameters with arguments. Each main keyword provides an action,
|
|
either at run time (like a function call in other languages),
|
|
or at parse time (like a global script setting).
|
|
|
|
The keywords "W" and "R" are type names for signal generators,
|
|
and are used to add instances of wave oscillators, and rumbly
|
|
noise generators, respectively. Such objects can be connected
|
|
for modulation. Together with the timing logic and parameters,
|
|
these are the core features of the language.
|
|
|
|
Keyword parameters may either be set (by writing the name,
|
|
followed by immediately writing their argument(s)), or left out
|
|
to use the previous value or a default value. Some default values
|
|
can be changed using the S (Script options) parse-time action.
|
|
|
|
Modifiers are somewhat like keywords, but use another character
|
|
than a letter as a name. They are used alongside the keywords to
|
|
adjust time placement. They are simpler and more flexible in how
|
|
they may be used.
|
|
|
|
Scopes
|
|
------
|
|
|
|
The flow of time and the nesting of scopes are like two dimensions
|
|
in which things are arranged. For altering the time-arrangement,
|
|
see 'Timing'; that includes sub-steps, which are considered part
|
|
of the same larger step involving the same reference to an object.
|
|
|
|
Beginning a new step, by introducing a new object or new reference
|
|
to an object, terminates the previous when done in the same scope.
|
|
|
|
The global level of a script is a top scope containing objects and
|
|
steps for them. Each list ("[...]") is a similar subscope. What is
|
|
written for an object inside a list is a step in the inner scope,
|
|
with timing connected to the outer scope. Termination of an inner
|
|
step does not terminate any outer it is related to (i.e. nesting).
|
|
|
|
Keywords
|
|
--------
|
|
|
|
Each of these keywords is further described in its own section below.
|
|
S Script options (parameter default value or other);
|
|
runs during parsing. Changes made inside a
|
|
nested list scope don't apply outside of it.
|
|
R Random segments oscillator -- "R", optionally followed
|
|
by the initial "Line types" value, e.g. "Rlin".
|
|
W Wave oscillator -- "W", optionally followed
|
|
by the initial "Wave types" value, e.g. "Wtri".
|
|
|
|
S: Script options
|
|
-----------------
|
|
|
|
Set parameter default value or other option; runs during parsing.
|
|
Changes made inside a nested list scope don't apply outside of it.
|
|
|
|
Usage: "S", followed by zero or more whitespace-separated parameters,
|
|
each with a value.
|
|
|
|
Parameters:
|
|
a Multiplier for amplitude "a" values after, in the current
|
|
scope of "[]" nesting. Starts at 1.0. The multiplier also
|
|
applies to "a.r" values, and to the multiplier in any deeper
|
|
main "a[]" modulator list. It does not apply to other nested
|
|
lists for modulators; their multipliers apply unchanged.
|
|
.m Script-wide gain mix control (multiplier). If used,
|
|
this disables automatic down-scaling of amplitude
|
|
by the number of voices (max carrier audio generators
|
|
simultaneously producing signals), for manual control
|
|
instead. Can only be set in the outermost scope.
|
|
c Default channel mixing "c" value. Starts at 0.0,
|
|
i.e. C (center). Useful as a main way of setting
|
|
the parameter value.
|
|
f Default frequency "f" value, in Hz. Starts at 440.
|
|
.k Key selection for "f" values using note syntax,
|
|
default C4. Mainly changes the default and relative
|
|
octave. Can be C, D, E, F, G, A, or B, with or
|
|
without one of 'b'/'f' (flat), 's' (sharp),
|
|
'd' (half-flat), 'z' (half-sharp),
|
|
'v' (flat-and-a-half), 'k' (sharp-and-a-half),
|
|
'w' (double-flat), or 'x' (double-sharp) --
|
|
and/or an octave number (0-10) to move the default
|
|
from a 4-5 range to one of the number to the number
|
|
plus one.
|
|
.n A4 tuning frequency in Hz for "f" values
|
|
using note syntax. Starts at 440.
|
|
For example, use "S f.n432" for 432 Hz.
|
|
.s Tuning system, either 'e' (24-EDO, default),
|
|
'p' (Pythagorean JI), 'c' (classic 5-limit JI),
|
|
or 'j' (SAU 7-limit JI).
|
|
r Default relative frequency "r" value, a
|
|
modulator:carrier ratio. Starts at 1 (1/1, a "1:1" ratio).
|
|
t Default short definite time "t" value, in seconds.
|
|
Default times may be longer (and occasionally shorter)
|
|
depending on the context. Starts at 1.0.
|
|
|
|
Signal generator common parameters
|
|
----------------------------------
|
|
|
|
The "R" and "W" types have these parameters in common:
|
|
t Time duration in seconds. If no "t" setting is given, the
|
|
time set depends on the context.
|
|
For a single non-nested generator, 1.0 is used unless
|
|
the default value is changed with "S t".
|
|
When several generators are specified, the default
|
|
time is based on the longest remaining (at the current time)
|
|
duration of play in use for any step at the current level,
|
|
in considering the surrounding sequence of steps and delays
|
|
(up to the next '|' time separator, or to the end of the
|
|
script if none).
|
|
The default time lengthens further when modulators
|
|
with longer definite times are specified for the current step.
|
|
For modulator generators, default time is however an
|
|
"implicit" time length (see 'i' below), meaning playing
|
|
whenever a carrier it is linked to does. (Implicit time is
|
|
only supported for nested generators.) When such a time
|
|
length is retrieved as part of setting the default time for
|
|
something else, a definite default time in seconds (e.g. 1
|
|
second) is however used instead.
|
|
For a compound step, the first sub-step is however
|
|
simply given the "S t" default value if no time is set.
|
|
The following sub-steps in turn each have the time of the
|
|
previous as its default time. The exception is modulators,
|
|
for which the last sub-step has implicit time ('i', "ti")
|
|
by default, just like for undivided steps for modulators.
|
|
Special non-number literals can also specify time:
|
|
d Definite default time can be set using "td", always.
|
|
i Implicit time can be set using "ti", for modulators.
|
|
f Frequency in Hz. Can be negative to flip wave shape timewise.
|
|
"Value sweep" values are supported; see section.
|
|
"Modulation with value range" is supported for FM
|
|
(frequency modulation); see section. Note that the modulator
|
|
lists for "f" and "r" expressions are shared and identical.
|
|
r (For modulator generators only.) Relative frequency, a value
|
|
which will be multiplied by the frequency of closest carrier
|
|
in the chain for the modulator, to give the frequency to use.
|
|
For an n:m modulator:carrier frequency ratio, a value of the
|
|
form (n/m) may be used; e.g., for a 4:3 frequency ratio,
|
|
"r(4/3)".
|
|
When using "r" the same values are changed as when
|
|
using "f", the difference simply being whether multiplication
|
|
by carrier frequency is switched on or off. Specific values
|
|
like the main value or the ".r" second value can be set again
|
|
under "f" or "r" to toggle just that value.
|
|
"Value sweep" values are supported; see section.
|
|
"Modulation with value range" is supported for FM
|
|
(frequency modulation); see section. Note that the modulator
|
|
lists for "f" and "r" expressions are shared and identical.
|
|
Note that for FM modulators, the carrier frequency
|
|
used as a multiplier is simply the unmodulated value. (If
|
|
several types of FM list are set and used at the same time,
|
|
the result of earlier stages will be used for later.) For
|
|
other kinds of modulation, if FM is done the result is used.
|
|
a Amplitude, where 1.0 corresponds to a level of 0 dB and
|
|
0.0 is silence. (Note that the "S a" option can be used to
|
|
set a multiplier for this value. Further options affect mixing
|
|
and the final output level afterwards; this includes panning,
|
|
which reduces output level unless fully left or right.)
|
|
Can be negative to flip the sign of the signal.
|
|
"Value sweep" values are supported; see section.
|
|
"Modulation with value range" is supported for AM & RM
|
|
(amplitude and ring modulation); see section.
|
|
p Phase in percentage of the wave cycle modulo 1.0. Set to
|
|
reset the phase, e.g. to change the initial value from 0.0.
|
|
See "Phase values" for more.
|
|
"Modulator list" values are supported for PM (phase
|
|
modulation); see section. A phase percentage value can be set
|
|
together with a list in one go, the value then going first
|
|
after the 'p', for example "p0.25[...]". A subparameter can
|
|
be used instead or in addition for another kind of PM.
|
|
.f Frequency-amplified PM modulators can be set in a
|
|
separate list, as in "p.f[...]". See "Modulator list".
|
|
The sum of all PM modulator amplitudes will phase-modulate
|
|
the carrier(s). For frequency-amplified PM modulators, first
|
|
the amplitudes are multiplied by the carrier frequency divided
|
|
by 632.45... Hz (the geometric mean of 20 and 20000 Hz).
|
|
c (For non-nested generators only.) Channel mixing, mainly
|
|
(-1.0) to 1.0. See "Channel mixing values" for more.
|
|
"Value sweep" values are supported; see section.
|
|
"Modulator list" values are supported for panning-AM
|
|
(stereo placement amplitude modulation); see section. The sum
|
|
of modulator amplitudes is added to the channel mixing used.
|
|
(If you downmix the result to mono the effect will disappear.)
|
|
|
|
R: Random segments oscillator
|
|
-----------------------------
|
|
|
|
Value noise oscillator, connecting random values generated at a frequency
|
|
with line segments of a selected shape. Two random values and line segments
|
|
are generated each "cycle", so that the base frequency matches that of
|
|
a wave oscillator -- though the spectrum otherwise differs in most modes.
|
|
|
|
As a signal generator, if not enclosed within a "[]" list, then
|
|
it will run and output at the current time, for its duration.
|
|
|
|
Usage: "R", optionally followed by a line type (e.g. "Rlin"),
|
|
by the default the same as "Rcos". Followed by zero or more
|
|
whitespace-separated parameters, each with a value. Several
|
|
'm' modes are available, for several types of random
|
|
distribution, as well as a naive oscillator mode.
|
|
See "Line types" for the available line types.
|
|
|
|
The "seed(x)" mathematical function changes
|
|
the starting seed of new "R" instances.
|
|
|
|
Parameters:
|
|
The "R" random segments oscillator has the
|
|
"Signal generator common parameters", and additionally:
|
|
l Line type -- see "Line types" for values.
|
|
m Mode for line start and goal value variation; consists of
|
|
a letter (random function) and a digit (0-9 shaping level);
|
|
one or both may be set at a time; the default level is '9'.
|
|
Roughly, each level above 0 halves what remains of the
|
|
unshaped underlying randomness. The functions are...
|
|
r Uniform random (default). Ignores the level setting.
|
|
g Gaussian random, soft-saturated approximation. On
|
|
average ~6 dB quieter. Ignores the level setting.
|
|
b Binary random. Extreme levels, more repetitive runs.
|
|
t Ternary smooth random. Never repeats twice in a row;
|
|
cycles above or below zero, randomly flips polarity.
|
|
f Fixed cycle. Plain naive oscillator at the top level;
|
|
below it, mixed with randomness at reduced amplitude.
|
|
In addition to the function and level, these flags can be set.
|
|
h Half-shape waveform. Use with 'lin' for a decreasing
|
|
sawtooth instead of a triangle wave; similarly changes
|
|
the shape for all line types and randomness modes.
|
|
s Square, then restore sign, of the start/goal values.
|
|
Turns uniform value variation into uniform energy
|
|
variation; somewhat quieter, and more tremulant.
|
|
Doesn't affect 'b', 't', nor 'f' with level '9'.
|
|
Distorts 'v' violet noise toward white, as if mixed.
|
|
v Violet rather than white noise version of the function
|
|
if available; missing for 'g' and 't'. Like high-pass
|
|
filtering the lower end of the noise, 6 dB per octave.
|
|
z Zig-zag flip. Swap ends of each half-cycle, adding an
|
|
inharmonic waveform jaggedness unless using 'h', or
|
|
'f' level '9'; more difference from these adds larger
|
|
sharp steps. Always flips the waveform top and bottom.
|
|
|
|
Line types:
|
|
cos
|
|
Half cosine (S-curve) trajectory over time.
|
|
lin
|
|
Linear trajectory over time.
|
|
sah
|
|
Sample and hold until time (then jump to goal).
|
|
exp
|
|
Steep "exp(x)-1"-like increase or decrease.
|
|
log
|
|
Steep "log(x+1)"-like increase or decrease.
|
|
xpe
|
|
Exponential shape envelope (saturate or decay).
|
|
lge
|
|
Logarithmic shape envelope (saturate or decay).
|
|
sqe
|
|
Square polynomial envelope (saturate or decay).
|
|
cub
|
|
Cubic polynomial segment (-1 to +1) trajectory.
|
|
ncl
|
|
Noise camel line; softer, two noise bulges.
|
|
nhl
|
|
Noise hump line; harder, one broad noise bulge.
|
|
uwh
|
|
Uniform random white noise in start-goal range.
|
|
The 'exp' and 'log' shapes use ear-tuned polynomial
|
|
approximations with definite beginnings and ends,
|
|
designed to sound natural for frequency sweeping,
|
|
and symmetric one to the other. The 'xpe' shape increases
|
|
like 'log' and decreases like 'exp', much like a capacitor
|
|
charges and discharges, natural-sounding for an envelope;
|
|
and 'lge' increases like 'exp' and decreases like 'log'.
|
|
For a less-steep alternative to 'xpe', 'sqe' can be used.
|
|
The 'cos' shape sounds similar to 'lin', except it has a
|
|
smoothly curved start and stop, and a steeper middle.
|
|
|
|
W: Wave oscillator
|
|
------------------
|
|
|
|
Wave oscillator. The sine variety is a fairly typical "FM synth operator".
|
|
Producing a (weakly) anti-aliased signal, including for FM/PM, amplitude
|
|
can be a little lower for frequencies close to half the sample rate.
|
|
|
|
As a signal generator, if not enclosed within a "[]" list, then
|
|
it will run and output at the current time, for its duration.
|
|
|
|
Usage: "W", optionally followed by a wave type (e.g. "Wtri"),
|
|
by the default the same as "Wsin". Followed by zero or more
|
|
whitespace-separated parameters, each with a value.
|
|
See "Wave types" for the available wave types.
|
|
|
|
Parameters:
|
|
The "W" wave oscillator has the
|
|
"Signal generator common parameters", and additionally:
|
|
w Wave type -- see "Wave types" for values.
|
|
|
|
Wave types:
|
|
Beyond 'sin', there's 3 times 3 complementary wave types, in terms
|
|
of the added harmonics (odd, even, or all), and mellow vs. bright.
|
|
Additionally, there's 2 more, listed after these first 10.
|
|
sin
|
|
Sine. For cosine, set phase 'p' to 1/4.
|
|
tri
|
|
Triangle.
|
|
Mellow odd-harmonics wave.
|
|
Opposite of 'ean' relative to 'par'.
|
|
srs
|
|
Square root of sine. (Mirrored for the negative half.)
|
|
Medium-bright odd-harmonics wave.
|
|
Opposite of 'cat' relative to 'hsr'.
|
|
sqr
|
|
Square.
|
|
Bright odd-harmonics wave.
|
|
Opposite of 'eto' relative to 'saw'.
|
|
ean
|
|
Evenangle.
|
|
Mellow even-harmonics wave.
|
|
Opposite of 'tri' relative to 'par'.
|
|
To begin at 0.0 amplitude, set phase 'p' to 6/93.
|
|
cat
|
|
Catear.
|
|
Medium-bright even-harmonics wave.
|
|
Opposite of 'srs' relative to 'hsr'.
|
|
To begin at 0.0 amplitude, set phase 'p' to 1/16.
|
|
eto
|
|
Eventooth.
|
|
Bright even-harmonics wave.
|
|
Opposite of 'sqr' relative to 'saw'.
|
|
par
|
|
Parabola. (x^2, steep part up.)
|
|
Mellow all-harmonics wave.
|
|
Between 'tri' and 'ean'.
|
|
To begin at 0.0 amplitude, set phase 'p' to 9/87.
|
|
hsr
|
|
Mellowtooth. (Half-rectified 'srs', amplitude doubled.)
|
|
Medium-bright all-harmonics wave.
|
|
Between 'srs' and 'cat'.
|
|
To begin at 0.0 amplitude, set phase 'p' to 1/25.
|
|
saw
|
|
Sawtooth.
|
|
Bright all-harmonics wave.
|
|
Decreasing slope; use negative amplitude
|
|
or frequency (but not both) for increasing slope.
|
|
Between 'sqr' and 'eto'.
|
|
hsi
|
|
Half-rectified sine. (Amplitude doubled.)
|
|
Like a somewhat louder 'ean', harmonics decreasing as fast.
|
|
To begin at 0.0 amplitude, set phase 'p' to 1/12.
|
|
spa
|
|
Sine parabola. (First half, amplitude doubled.)
|
|
Slightly cleaner than 'par'. Mainly useful for modulation.
|
|
To begin at 0.0 amplitude, set phase 'p' to -1/12.
|
|
|
|
Values and expressions
|
|
----------------------
|
|
|
|
Whitespace is not allowed within multi-character names, keywords or
|
|
numbers, and separates values. Spaces and tabs may otherwise be used or
|
|
omitted anywhere.
|
|
|
|
Comment syntax:
|
|
"//" (C++-comment) comments out the rest of the line.
|
|
"/*" (C-comment) comments out text until the next "*/". Does not nest.
|
|
"#!" (Shebang) comments out the rest of the line.
|
|
"#Q" (Quit file) comments out the rest of the whole file.
|
|
|
|
Modulator list:
|
|
Within "[]", written after the name of a parameter that supports it,
|
|
signal generators can be included for use with that parameter. For
|
|
example, for PM the phase parameter 'p' is assigned a list as in
|
|
"p[...]". It works the same for other parameters such as 'a'
|
|
(for AM/RM) and 'f' (for FM), and subparameters such as 'a.r', etc.
|
|
Assigning a list to a parameter will append the new list to
|
|
any old one, expanding it rather than replacing the old items. Thus
|
|
"p[]" changes nothing. To clear old items when setting a list, add
|
|
'-' before the '[', as in "p-[]" (which removes all PM modulators).
|
|
Lists can be assigned together with other values (numbers)
|
|
for various parameters. For the whole expression beginning with the
|
|
parameter name, whitespace can only be placed inside list brackets
|
|
(or inside parentheses for any numerical expressions).
|
|
"Value sweep" for a parameter can use the same list as one
|
|
which contains modulators; the modulators simply need to be listed
|
|
after any sweep subparameters (see section) which head the list.
|
|
It's also possible to write multiple lists directly after
|
|
one another when setting to a parameter (with or without the one
|
|
leading '-'). These lists will be joined into one, meaning that
|
|
"[X][Y]" for some contents "X" and "Y" is the same as "[X Y]".
|
|
This also allows placing sweep subparameters in a later list.
|
|
|
|
Numerical expressions:
|
|
A number can be specified with or without a decimal point;
|
|
for a number with a decimal point, a leading zero can be omitted.
|
|
Number signs and arithmetic operation symbols can be used in infix
|
|
expressions, together with numbers and named constants, variables,
|
|
and functions. But unless something is written within parentheses,
|
|
it cannot contain any whitespace, as it ends the expression. For
|
|
example, "-1" is fine, but "- 1" is a dangling minus followed by
|
|
a dangling number 1, if not inside parentheses as "(- 1)".
|
|
The following operations are recognized, and grouped below by
|
|
priority (nested parentheses can be used to change evaluation order):
|
|
^ To the power of (right-associative)
|
|
* / % Multiplication, division, remainder
|
|
+ - Addition, subtraction
|
|
Parentheses also allow shorthand multiplication (leaving out a
|
|
"*" between two parts), e.g. "2(3)" and "(2)3" both give "6".
|
|
Some parameters support named constants specific to that type
|
|
of value, like "Frequencies as notes", "Channel mixing values", and
|
|
others. Such a name can be written instead of a number.
|
|
The following universal mathematical symbols (functions and
|
|
constants) can also be used in any numerical expression; functions
|
|
require parentheses after the name (and most often require a value
|
|
inside), while constants are simply written as names:
|
|
abs(x) Absolute value.
|
|
cos(x) Cosine of value.
|
|
exp(x) Base-e exponential value.
|
|
log(x) Natural logarithmic value.
|
|
met(x) Metallic value, e.g. "met(1)" gives the golden ratio.
|
|
Positive integers give the series of metallic ratios.
|
|
Other values are also allowed: fractional, 0 giving 1
|
|
and negative (gives how much the positive value would
|
|
be increased, approaching zero further from zero).
|
|
Note that met(-x) is also equal to (1/met(x)).
|
|
mf 632.45... Geometric mean of 20 and 20000.
|
|
pi 3.1415...
|
|
rand() Pseudo-random number in range 0-1. The value sequence
|
|
from a series of calls restarts each new script unit.
|
|
rint(x) Round value to the nearest integer. Halfway cases are
|
|
rounded to the nearest even integer.
|
|
seed(x) Reset the rand() value sequence with a passed number.
|
|
(Every bit counts; different expressions for the same
|
|
number, with e.g. rounding may give different seeds.)
|
|
Returns 0 so that e.g. "/seed(100)" will only reseed.
|
|
sin(x) Sine of value.
|
|
sqrt(x) Square root.
|
|
time() Get a system timestamp number changed each second.
|
|
It can be used for seeding in a randomized script.
|
|
(Note that the exact value is platform-dependent.)
|
|
If disabled (deterministic mode), instead gives 0.
|
|
|
|
Channel mixing values:
|
|
Panning, where 0.0 is centered. Named constants can be used in place
|
|
of numbers for the three classic channel "modes". Values outside the
|
|
range of L to R are allowed, amplifying one channel while giving the
|
|
other a negative amplitude.
|
|
C 0.0
|
|
L (-1.0)
|
|
R 1.0
|
|
|
|
Phase values:
|
|
Phase offset as a percentage of the wave cycle. Any value will be used
|
|
modulo 1.0. For example, (1/4) turns sine into cosine. Named constants
|
|
provide scaled angles which can be used in expressions, e.g. (G*n) for
|
|
some whole number n makes for the nth leaf-around-a-stem angle.
|
|
G 0.3819... (golden angle as cycle percentage)
|
|
|
|
Value sweep:
|
|
To sweep a parameter which supports sweep subparameters towards a
|
|
goal value -- the ordinary value being the start for a trajectory --
|
|
following the ordinary value or by itself, the following value sweep
|
|
subparameters can be given values at the start of a "[]" list. For
|
|
example, "f[g220]" sweeps frequency to 220 Hz over a default time.
|
|
g Goal (go-to) value, assigned to the parameter after time.
|
|
This value has no default and must be provided. If changed
|
|
again before the full time, the current point reached on the
|
|
previous trajectory will be used to change the start value.
|
|
l Line fill shape (default 'lin', or the previous shape if any)
|
|
-- see "Line types" for values.
|
|
t Time to reach goal (default is the external "t" duration,
|
|
or the remaining previous time, if any, for this parameter).
|
|
If longer than the active time for the object which has the
|
|
swept parameter, the trajectory will be left unfinished.
|
|
v Start (state) value, the ordinary parameter value.
|
|
It can alternatively be set here after a 'v',
|
|
if not set before the enclosing "[]".
|
|
|
|
Modulation with value range:
|
|
Amplitude ('a'), frequency ('f'), and relative frequency ('r')
|
|
parameters all support modulation of the parameter values in the
|
|
same ways. For amplitude, whether the result is called amplitude
|
|
modulation (AM), or ring modulation (RM), depends on how carrier
|
|
and modulator amplitude are set up relative to one another. (For
|
|
frequency modulation, the result is however always the "real FM"
|
|
related to yet distinct from PM, whenever modulation happens.)
|
|
Following a parameter name and optionally its main value(s),
|
|
lists can be used (see "Modulator list") to assign modulators whose
|
|
amplitudes are simply added to the main value. For example "a0[...]"
|
|
will set amplitude to 0, and the modulators within "[...]" will have
|
|
the effect of ring modulating, while with "a1" set the result is AM.
|
|
A subparameter can be used instead or in addition, to set up
|
|
modulation in a complementary way (the whole larger argument, for
|
|
example "f200.r(200 * 2)[...]", cannot contain any whitespace
|
|
outside of parentheses or brackets):
|
|
.r Following a main parameter name and optionally the things
|
|
mentioned above, under ".r" a subparameter with a second
|
|
value can be set. This second value is the other boundary
|
|
for a range to which modulator amplitudes can be mapped;
|
|
it has no other uses, and defaults to 0.0. "Value sweep" is
|
|
also supported for this subparameter whenever for the main.
|
|
After a value or by itself, lists can be used (see
|
|
"Modulator list"). Each modulator here produces a result in
|
|
the range of 0.0 to 1.0 (i.e. a positive signal) multiplied
|
|
by its amplitude (with a default of 1.0). However, a negative
|
|
amplitude multiplier can be used to switch the top and bottom
|
|
of the 0.0 to 1.0 range, and is then used as if positive.
|
|
When several modulators are used for this, their
|
|
outputs are multiplied. The product of outputs is mapped to
|
|
a range where 0.0 is matched to the main value, and 1.0 to
|
|
the second. Using more modulators thus adds a bias towards
|
|
the main value. Furthermore, changing amplitude multipliers
|
|
for modulators from the default can change the range.
|
|
To use this for classic 100% modulation depth AM,
|
|
one of the bounds should be 0.0 (like the default for the
|
|
second value); while for classic RM, the two bounds should
|
|
have the same magnitude, but with opposite sign.
|
|
If this type of modulation is used, it is done first
|
|
and the output from the other, main additive modulator list
|
|
is then added to the result.
|
|
|
|
Parameters and object binding:
|
|
When specifying or referencing objects within "@[...]", any
|
|
parameters set following the closing ']' will be bound to and apply
|
|
to all of them.
|
|
Significantly, this allows multiple carriers (given within
|
|
the []) to be linked to the same modulator(s), whether for FM, PM,
|
|
or AM/RM. (Note: Support for this is experimental and incomplete.)
|
|
|
|
Variables:
|
|
A named variable can be assigned by writing an expression beginning
|
|
with "'name", where the "name" is a case-sensitive string with
|
|
alphanumeric characters and/or '_'. Variables are dynamically typed,
|
|
can be assigned several times, and can either be assigned to a number
|
|
or made to point to an object as a label for it.
|
|
To assign a number, "'name=" can be written just before a
|
|
numerical expression. Once it holds a number, it can be used in any
|
|
numerical expression using "$name". (It's possible to retrieve such
|
|
a variable value as part of redefining its value.) Whitespace is
|
|
allowed both before and after the '='.
|
|
Numerical expressions for some named parameters can use
|
|
context-sensitive constants; to allow such when assigning a variable,
|
|
one of the below parameter namespace names can be added after the
|
|
'='. Between it and any number or mathematical name after must be
|
|
whitespace and/or a mathematical symbol, to keep names apart.
|
|
For example, "'freq=f A4" has the frequency value of the note "A4".
|
|
c Channel mixing values
|
|
f Frequencies as notes
|
|
p Phase values
|
|
To point a variable to an object, "'name " can be written
|
|
just before an object is added or referenced. The name can then be
|
|
used to refer back to the object as "@name", to start a new step for
|
|
the object anywhere later in the script.
|
|
A new "@name" step differs in not automatically setting a new
|
|
time duration for the object, so "t" (see "Parameters") or other
|
|
time-altering syntax (see "Timing") must be used in order for the
|
|
old time duration value to be changed.
|
|
Note that a "@name" reference placed in a nesting scope
|
|
different from the original (e.g. outside a list, or in a new list)
|
|
does not move the object into the new nesting scope. It will not be
|
|
added to, nor removed from, any list by being referenced anywhere.
|
|
The time scope is however new and of the reference.
|
|
|
|
Frequencies as notes:
|
|
Frequency values may be specified as notes. The "S f.n" option
|
|
sets the A4 tuning frequency, by default 440 Hz. The tuning system
|
|
can also be changed using "S f.s".
|
|
By default, notes use the 24-tone equal temperament or equal
|
|
divisons of the octave (24-EDO) system, a superset of 12-EDO. There
|
|
are also three justly intoned systems (Pythagorean JI, classic
|
|
5-limit JI, SAU 7-limit JI), in all of which each of the 7 notes
|
|
have a natural, 3 flat, and 3 sharp variations, all of them unique.
|
|
Each note is written with a C, D, E, F, G, A, or B. As a
|
|
first optional suffix, a 'b'/'f' (flat) or 's' (sharp) can be added --
|
|
or a quartertone alternative: 'd' (half-flat), 'z' (half-sharp),
|
|
'v' (flat-and-a-half), or 'k' (sharp-and-a-half). There's also
|
|
'w' (double-flat) and 'x' (double-sharp). The flats and sharps
|
|
differ for EDO and the three JI systems -- making a smaller
|
|
difference in the JI systems than for EDO, except for the
|
|
Pythagorean JI which very slighly exaggerates it instead.
|
|
An octave number (0-10) can be written as a final suffix,
|
|
e.g. "A5" matches twice the tuning frequency, "Ad5" a little below
|
|
that. With no number, the octave for the note will be relative to the
|
|
key setting ("S f.k"), and by default 4-5, so that the note set for
|
|
the selected key is also the lowest using the low default octave.
|
|
To access more octaves from a relative position, add arithmetic.
|
|
Another means of microtonal variation is a subnote prefix
|
|
for "inner octave" placement, optionally added first: c, d, e, f,
|
|
g, a, or b. (It can be combined with any other options.) The result
|
|
is moving the tone, part of the distance from the diatonic note used
|
|
to that above it. I.e., "cC" is the same as only "C", but "dC" moves
|
|
up one subnote step towards "D", "eC" another step, and so on. (What
|
|
about "eCs"? It likewise moves two subnote steps from "Cs" towards
|
|
"Ds", as the 's' is applied in addition.) If the diatonic part of the
|
|
key selected is not C, this small letter scale rotates with it. In
|
|
just intonation, the frequency increases apply rational fractions.
|
|
|
|
Timing
|
|
------
|
|
|
|
Timing modifiers:
|
|
| Time separator. Delays all that follows by the duration of
|
|
prior steps. This also resets any other delays to be added
|
|
to later steps using other syntax like '/', so such should
|
|
be placed after, not before, if it is to take effect.
|
|
/number Forward shift, time in seconds. Delay the next step and
|
|
all steps placed after. The next step can be either a
|
|
split-out continuation of the current step, or new.
|
|
Does not automatically extend time duration on
|
|
splitting a step, unlike ';'.
|
|
|
|
Compound steps:
|
|
For a step written for some object, timing can be changed locally,
|
|
within only the step and for lists nested under it. Two varieties
|
|
of the ';' sub-step separator allow this. Their use can be repeated.
|
|
; The numberless ';' step split can be written after a step for
|
|
an object (on a new line or the same), to specify a new time
|
|
duration and new parameter arguments which apply just after
|
|
the previous time duration. The new duration generally has
|
|
the length of the previous by default. (For the default time
|
|
of the first sub-step, and special handling for the last, see
|
|
"t" under each "Parameters" for more).
|
|
The time handling is designed to simplify writing a
|
|
sequence of connected, non-overlapping timed updates for a
|
|
single object. For example (three frequencies, one a second):
|
|
"Wsin f100 t1; f200; f300". Changing "t1" in this example
|
|
changes the time length for all three parts.
|
|
For more flexibility, especially for adding "silent"
|
|
gaps between parts, the numberless ';' can be combined with,
|
|
or replaced by, the ';number' gapshift. Combination is easy,
|
|
as "; ;number" will subdivide and shift the second sub-step
|
|
by "number" of seconds, and move the active time duration for
|
|
the second sub-step past the second split, creating a gap
|
|
"number" of seconds long. For example (1 second of silence
|
|
between frequency changes): "Wsin f100 t1;;1 f200;;1 f300".
|
|
;number Gapshift, time in seconds. When a number immediately follows
|
|
the ';', then the new sub-step is placed in time that number
|
|
of seconds after the previous, instead of after the duration
|
|
of the previous. Depending on usage, may move, alternatively
|
|
extend, the current sound in time.
|
|
For ease of adding silent time padding, before the
|
|
";number" part (but not after it) the default time duration
|
|
is changed to 0, so that any time value automatically set
|
|
there will be 0. After the ";number" part, a time value is
|
|
always set, the last "t" or default (before zeroing) value.
|
|
Several uses of ";number" to separate sub-steps in
|
|
a row (no numberless ';' in-between!) will only zero the
|
|
default time before the first ";number", allowing e.g. to
|
|
extend the whole time rather than to move it by adding a
|
|
leading ";0" before another ";number".
|