The Standard Numeric Score
Preprocessing of Standard
Scores
Next-P and Previous-P Symbols
Ramping
F-Statement
I-Statement
A-Statement
T-Statement
S-Statement
E-Statement
A score is a data file that provides information to an orchestra about
its performance. Like an orchestra file, a score file is made up of statements
in a known format. The Csound orchestra expects to be handed a score
comprised mainly of ascii numeric characters. Although most users
will prefer a higher level score language such as provided by Cscore,
Scot, or another score-generating program, each resulting score must
eventually appear in the format expected by the orchestra. A Standard Numeric
Score can be created and edited directly by the beginner using standard
text editors; indeed, some users continue to prefer it. The purpose of
this section is to describe this format in detail.
The basic format of a standard numeric score statement is:
opcode p1 p2 p3 p4... ;comments
The opcode is a single character, always alphabetic. Legal opcodes are f, i, a, t, s, and e, the meanings of which are described in the following pages. The opcode is normally the first character of a line; leading spaces or tabs will be ignored. Spaces or tabs between the opcode and p1 are optional.
p1, p2, p3, etc... are parameter fields (pfields). Each contains a floating point number comprised of an optional sign, digits, and an optional decimal point. Expressions are not permitted in Standard Score files. pfields are separated from each other by one or more spaces or tabs, all but one space of which will be ignored.
Continuation lines are permitted. If the first printing character of a new scoreline is not an opcode, that line will be regarded as a continuation of the pfields from the previous scoreline.
Comments are optional and are for the purpose of permitting the user to document his score file. Comments always begin with a semicolon (;) and extend to the end of the line. Comments will not affect the pfield continuation feature.
Blank lines or comment-only lines are legal (and will be ignored).
A Score (a collection of score statements) is divided
into time-ordered sections by the s statement.
Before being read by the orchestra, a score is preprocessed one section
at a time. Each section is normally processed by 3 routines: Carry,
Tempo, and Sort.
1. Carry - within a group of consecutive i statements whose p1 whole numbers correspond, any pfield left empty will take its value from the same pfield of the preceding statement. An empty pfield can be denoted by a single point (.) delimited by spaces. No point is required after the last nonempty pfield. The output of Carry preprocessing will show the carried values explicitly. The Carry Feature is not affected by intervening comments or blank lines; it is turned off only by a non-i statement or by an i statement with unlike p1 whole number.
An additional feature is available for p2 alone. The symbol + in p2 will be given the value of p2 + p3 from the preceding i statement. This enables note action times to be automatically determined from the sum of preceding durations. The + symbol can itself be carried. It is legal only in p2. E.g.: the statements
i1 0 .5 100 i . + i
will result in
i1 0 .5 100 i1 .5 .5 100 i1 1 .5 100
The Carry feature should be used liberally. Its use, especially in large scores, can greatly reduce input typing and will simplify later changes.
2. Tempo - this operation time warps a score section according to the information in a t statement. The tempo operation converts p2 (and, for i statements, p3) from original beats into real seconds, since those are the units required by the orchestra. After time warping, score files will be seen to have orchestra-readable format demonstrated by the following: i p1 p2beats p2seconds p3beats p3seconds p4 p5 ....
3. Sort - this routine sorts all action-time statements into chronological order by p2 value. It also sorts coincident events into precedence order. Whenever an f statement and an i statement have the same p2 value, the f statement will precede. Whenever two or more i statements have the same p2 value, they will be sorted into ascending p1 value order. If they also have the same p1 value, they will be sorted into ascending p3 value order. Score sorting is done section by section ( see s statement). Automatic sorting implies that score statements may appear in any order within a section.
N.B. The operations Carry, Tempo and Sort are combined in a 3-phase single pass over a score file, to produce a new file in orchestra-readable format ( see the Tempo example). Processing can be invoked either explicitly by the scsort command, or implicitly by csound which processes the score before calling the orchestra. Source-format files and orchestra-readable files are both in ascii character form, and may be either perused or further modified by standard text editors. Userwritten routines can be used to modify score files before or after the above processes, provided the final orchestra-readable statement format is not violated. Sections of different formats can be sequentially batched; and sections of like format can be merged for automatic sorting.
At the close of any of the operations Carry,
Tempo and Sort, three additional score features are interpreted
during file writeout: next-p, previous-p, and ramping.
i statement pfields containing the symbols npx or ppx (where x is some integer) will be replaced by the appropriate pfield value found on the next i statement (or previous i statement) that has the same p1. For example, the symbol np7 will be replaced by the value found in p7 of the next note that is to be played by this instrument. np and pp symbols are recursive and can reference other np and pp symbols which can reference others, etc. References must eventually terminate in a real number or a ramp symbol. Closed loop references should be avoided. np and pp symbols are illegal in p1,p2 and p3 (although they may reference these). np and pp symbols may be Carried. np and pp references cannot cross a Section boundary. Any forward or backward reference to a non-existent note-statement will be given the value zero.
E.g.: the statements
i1 0 1 10 np4 pp5 i1 1 1 20 i1 1 1 30
will result in
i1 0 1 10 20 0 i1 1 1 20 30 20 i1 2 1 30 0 30
np and pp symbols can provide an instrument with contextual knowledge of the score, enabling it to glissando or crescendo, for instance, toward the pitch or dynamic of some future event (which may or may not be immediately adjacent). Note that while the Carry feature will propagate np and pp through unsorted statements, the operation that interprets these symbols is acting on a time-warped and fully sorted version of the score.
i statement pfields containing the symbol
< will be replaced by values derived from linear interpolation
of a time-based ramp. Ramps are anchored at each end by the first real
number found in the same pfield of a preceding and following note played
by the same instrument. E.g.: the statements
i1 0 1 100 i1 1 1 < i1 2 1 < i1 3 1 400 i1 4 1 < i1 5 1 0
will result in
i1 0 1 100 i1 1 1 200 i1 2 1 300 i1 3 1 400 i1 4 1 200 i1 5 1 0
Ramps cannot cross a Section boundary. Ramps cannot be anchored by an np or pp symbol (although they may be referenced by these). Ramp symbols are illegal in p1, p2 and p3. Ramp symbols may be Carried. Note, however, that while the Carry feature will propagate ramp symbols through unsorted statements, the operation that interprets these symbols is acting on a time-warped and fully sorted version of the score. In fact, time-based linear interpolation is based on warped score-time, so that a ramp which spans a group of accelerating notes will remain linear with respect to strict chronological time.
f p1 p2 p3 p4 ...
This causes a GEN subroutine to place values in a stored function table for use by instruments.
p1 Table number (from 1 to 200) by which the stored function will be known. A negative number requests that the table be destroyed. p2 Action time of function generation (or destruction) in beats. p3 Size of function table (i.e. number of points) Must be a power of 2, or a power-of-2 plus 1 (see below). Maximum table size is 16777216 (2**24) points. p4 Number of the GEN routine to be called (see GEN ROUTINES). A negative value will cause rescaling to be omitted. p5 | p6 | Parameters whose meaning is determined by the particular GEN routine. . | . |
Function tables are arrays of floating-point values. Arrays can be of any length in powers of 2; space allocation always provides for 2**n points plus an additional guard point. The guard point value, used during interpolated lookup, can be automatically set to reflect the table's purpose: If size is an exact power of 2, the guard point will be a copy of the first point; this is appropriate for interpolated wrap-around lookup as in oscili, etc., and should even be used for non-interpolating oscil for safe consistency. If size is set to 2**n + 1, the guard point value automatically extends the contour of table values; this is appropriate for single-scan functions such in envlpx, oscil1, oscil1i, etc.
Table space is allocated in primary memory, along with instrument data space. The maximum table number has a soft limit of 200; this can be extended if required.
An existing function table can be removed by an f statement containing a negative p1 and an appropriate action time. A function table can also be removed by the generation of another table with the same p1. Functions are not automatically erased at the end of a score section.
p2 action time is treated in the same way as in i statements with respect to sorting and modification by t statements. If an f statement and an i statement have the same p2, the sorter gives the f statement precedence so that the function table will be available during note initialization.
An f 0 statement (zero p1, positive p2) may be used to create an action time with no associated action. Such time markers are useful for padding out a score section (see s statement).
i p1 p2 p3 p4 ...
This statement calls for an instrument to be made active at a specific time and for a certain duration. The parameter field values are passed to that instrument prior to its initialization, and remain valid throughout its Performance.
p1 Instrument number (from 1 to 200), usually a non-negative integer. An optional fractional part can provide an additional tag for specifying ties between particular notes of consecutive clusters. A negative p1 (including tag) can be used to turn off a particular `held' note. p2 Starting time in arbitrary units called beats. p3 Duration time in beats (usually positive). A negative value will initiate a held note (see also ihold). A zero value will invoke an initialization pass without performance (see also instr). p4 | p5 | Parameters whose significance is determined by the instrument. . | . |
Beats are evaluated as seconds, unless there is a t statement in this score section or a -t flag in the command line.
Starting or action times are relative to the beginning of a section ( see s statement), which is assigned time 0.
Note statements within a section may be placed in any order. Before being sent to an orchestra, unordered score statements must first be processed by Sorter, which will reorder them by ascending p2 value. Notes with the same p2 value will be ordered by ascending p1; if the same p1, then by ascending p3.
Notes may be stacked, i.e., a single instrument can perform any number of notes simultaneously. (The necessary copies of the instrument's data space will be allocated dynamically by the orchestra loader.) Each note will normally turn off when its p3 duration has expired, or on receipt of a MIDI noteoff signal. An instrument can modify its own duration either by changing its p3 value during note initialization, or by prolonging itself through the action of a linenr unit.
An instrument may be turned on and left to perform indefinitely either by giving it a negative p3 or by including an ihold in its I-time code. If a held note is active, an i statement with matching p1 will not cause a new allocation but will take over the data space of the held note. The new pfields (including p3) will now be in effect, and an I-time pass will be executed in which the units can either be newly initialized or allowed to continue as required for a tied note (see tigoto). A held note may be succeeded either by another held note or by a note of finite duration. A held note will continue to perform across section endings (see s statement). It is halted only by turnoff or by an i statement with negative matching p1 or by an e statement.
a p1 p2 p3
This causes score time to be advanced by a specified amount without producing sound samples.
p1 carries no meaning. Usually zero p2 Action time, in beats, at which advance is to begin. p3 Durational span (distance in beats) of time advance. p4 | p5 | These carry no meaning. . .
This statement allows the beat count within a score section to be advanced without generating intervening sound samples. This can be of use when a score section is incomplete (the beginning or middle is missing) and the user does not wish to generate and listen to a lot of silence.
p2 action time and p3 distance are treated as in i statements, with respect to sorting and modification by t statements.
An a statement will be temporarily inserted in the score by the Score Extract feature when the extracted segment begins later than the start of a Section. The purpose of this is to preserve the beat count and time count of the original score for the benefit of the peak amplitude messages which are reported on the user console.
Whenever an a statement is encountered by a performing orchestra, its presence and effect will be reported on the user's console.
t p1 p2 p3 p4 ..... (unlimited)
This statement sets the tempo and specifies the accelerations and decelerations for the current section. This is done by converting beats into seconds.
p1 must be zero p2 initial tempo in beats per minute p3, p5, p7, ... times in beats (in non-decreasing order) p4, p6, p8, ... tempi for the referenced beat times
Time and Tempo-for-that-time are given as ordered couples that define points on a "tempo vs time" graph. (The time-axis here is in beats so is not necessarily linear.) The beat-rate of a Section can be thought of as a movement from point to point on that graph: motion between two points of equal height signifies constant tempo, while motion between two points of unequal height will cause an accelarando or ritardando accordingly. The graph can contain discontinuities: two points given equal times but different tempi will cause an immediate tempo change.
Motion between different tempos over non-zero time is inverse linear. That is, an accelerando between two tempos M1 and M2 proceeds by linear interpolation of the single-beat durations from 60/M1 to 60/M2.
The first tempo given must be for beat 0.
A tempo, once assigned, will remain in effect from that time-point unless influenced by a succeeding tempo, i.e. the last specified tempo will be held to the end of the section.
A t statement applies only to the score section in which it appears. Only one t statement is meaningful in a section; it can be placed anywhere within that section. If a score section contains no t statement, then beats are interpreted as seconds (i.e. with an implicit t 0 60 statement).
N.B. If the csound command includes a -t flag, the interpreted tempo of all score t statements will be overridden by the command-line tempo.
s anything
The s statement marks the end of a section.
All p-fields are ignored.
Sorting of the i, f and a statements by action time is done section by section.
Time warping for the t statement is done section by section.
All action times within a section are relative to its beginning. A section statement establishes a new relative time of 0, but has no other reinitializing effects (e.g. stored function tables are preserved across section boundaries).
A section is considered complete when all action times and finite durations have been satisfied (i.e., the "length" of a section is determined by the last occurring action or turn-off). A section can be extended by the use of an f 0 statement.
A section ending automatically invokes a Purge of inactive instrument and data spaces.
N.B. Since score statements are processed section by section, the amount of memory required depends on the maximum number of score statements in a section. Memory allocation is dynamic, and the user will be informed as extra memory blocks are requested during score processing.
For the end of the final section of a score, the s statement is optional; the e statement may be used instead.
e anything
This statement may be used to mark the end of the last section of the score.
All pfields are ignored.
The e statement is contextually identical to an s statement. Additionally, the e statement terminates all signal generation (including indefinite performance) and closes all input and output files.
If an e statement occurs before the end of a score, all subsequent score lines will be ignored.
The e statement is optional in a score file yet to be sorted. If a score file has no e statement, then Sort processing will supply one.