Event Specification¶
Events are detected by the listening machine in the audio stream. The
specification of an event starts by a keyword defining the kind of event
expected and some additional parameters. There are two basic event
(NOTE
and EVENT
) and three event
containers (CHORD
, TRILL
) and
MULTI
).
A midi file or a MusicXML file can be converted in a sequence of Antescofo event using an independant tool. This tool is also available on-line in a web page at url https://antescofo-converter.ircam.fr/: just drop the file you wan to convert in the web page and the result becomes available from download through your browser.
Here we give the general syntax of an event specification and then we details all its components.
Musical Event Specification¶
Event definitions must end by a carriage return. In other words, you are allowed to define only one musical event per line.
TRILL
and MULTI
are examples of compound
events organizing a set of NOTE
s in time. Thus they can
accept one or several pitch_lists.
There is an additional kind of event
EVENT d
also followed by a mandatory duration d, which correspond to a fake event triggered manually by the “nextevent” button on the graphical interface or bythe message 'nextevent' sent to the antescofo object.
We first detail the specification of a pitch, then the notation of a duration. We detail the various kinds of events before the presentation of the optional event's attributes. The last section of this chapter is devoted to the command that alters the sequencing of the score.
Pitch Specification¶
A pitch (used in NOTE
) can take the following forms:
-
MIDI number (e.g. 69 and 70, 0 is silence),
-
MIDI cent number (e.g. 6900 and 7000),
-
Standard Pitch Name (e.g.
A4
andA#4
). -
For microtonal notations, one can use either MIDI cent (e.g. 6900) or Pitch Name standard and MIDI cent alteration using ’+’ or ’-’ (e.g.
NOTE A4+50
andNOTE A#4+50
orNOTE B4-50
).
A minus sign -
may precede the previous specification to specify that
the current note is a continuation of a note with the same pitch in the
preceding event:
CHORD (C4 D5) 1
CHORD (-C4 D3) 1/2
A pitch list is a sequence of one or more pitches (without
separator). They are used for instance to define content of a
CHORD
. For example, the following line defines a C-Major
chord composed of C4
, E4
and G4
:
CHORD ( C4 64 6700 )
Duration specification¶
Duration is a mandatory specification for all events. The of
duration an event is specified in beats either by an integer
(1
), the ratio of two integers (like 4/3
)
or a float (like 1.5
).
Events as Containers¶
Each event keyword in Antescofo can be seen as containers with
specific behavior and given nominal durations. A NOTE
is
a container of one pitch. A CHORD
contains a vector of
pitches. The figure below shows an example including simple notes and
chords written in Antescofo:
BPM 60
NOTE C4 1.0
CHORD (D4 F4) 1.0
NOTE 0 1.0 ; a silence
NOTE G4 0.0 ; a grace note with duration zero
NOTE F4 2.0
TRILL¶
Similar to trills in classical music, a TRILL
is a
container of events either as atomic pitches or chords, where the
internal elements can happen in any specific order. Additionally,
internal events in a TRILL
are not obliged to happen in
the environment. This way, TRILL
can be additionally used
to notate improvisation boxes where musicians are free to choose
elements. A TRILL
is considered as a global event with a
nominal relative duration. Figure below shows basic examples for Trill.
TRILL (A4 B4) 1.0
NOTE 0 1.0 ; a silence
TRILL ( (C5 E5) (D5 F5) ) 2.0
The figure below shows a typical polyphonic situation on piano where the
right-hand is playing a regular trill, and the left hand regular notes
and chords. In this case, the score is to be segmented at each event
onset as TRILL
whose elements would become the trill
element plus the static notes or chords in the left-hand.
TRILL ( (A4 A2) (B4 A2) ) 1/2
TRILL ( (A4 D3) (B4 D3) ) 1/2
TRILL ( (A4 C3 E3) (B4 C3 E3) ) 1/2
TRILL ( (A4 D3) (B4 D3) ) 1/2
TRILL ( A4 B4 ) 2.0
MULTI¶
Similar to TRILL
, a MULTI
is a compound
event (that can contain notes, chords or trills events) but where the
order of actions are to be respected and decoded accordingly in the
listening machine. They can model continuous events such as
glissando.
A chord event inside a multi is specified through its pitch list between parenthesis.
To specify a trill event in a multi, it suffices to insert a '
character after the pitch list specifying the trill (between
parenthesis). The figure below shows an example of glissandi between
chords written by MULTI
.
MULTI ( (F4 C5) -> (D4 A4) ) 4.0
Event Label and other Attributes¶
The attributes of a musical event are either a label or a @-keyword following the definition of the event. Attributes are optional.
Event Label¶
A simple identifier or a string or an integer acts as a label for this event. There can be several such labels.
Label: Optionally, users can define labels on events as a simple identifier, a number or a string, useful for browsing inside the score and for visualisation purposes.
For example, measure1
is an accepted label. If you intend
to use white space or mathematical symbols inside your string, you should
surround them with quotations such as "measure 1"
or "measure-1"
You can have several labels for a musical event and they appear when you print the score (printfwd message). The idea was to use additional labels as a kind of comment or free annotation. However, only the first one is actually associated with the event:
-
the first label is the label notified through the variable $LAST_EVENT_LABEL when the event is reached;
-
only the first label is recognized by the function @event_label_position.
The function @event_label_position takes a label and returns the time in beats of the onset of the event2.
Fermata, Pizzicato, Hook, Nosync and Jump¶
There are five kinds of event attributes besides labels:
-
The keyword
@fermata
specifies that this event has a fermata signature. A Fermata event can last longer and arriving and leaving it does not contribute to the tempo decoding of the performance. -
The keyword
@pizz
specifies the event is a string pizzicato. This usually helps Score Follower stability. -
The keyword
@staccato
signifies the event is played staccato. This attribute add an “invisible grace silence” between the attributed event and the next. This is just there to absorb the silence induced by a staccato. This may help Score Follower stability. -
The keyword
@hook
specifies that this event cannot be missed (the listening machine need to wait the occurrence of this event and cannot presume that it can be missed). -
The keyword
@nosync
specifies that the occurence of this event does not provide information to the tempo inference algorithm (so the occurence and duration of this event are not taken into account in the computation of the tempo). -
The keyword
@jump
is followed by a variable or by a comma separated list of simple identifiers referring to the label of an event in the score. This attribute specifies that this event can be followed by several continuations: the next event in the score, as well as the events listed by the@jump
. See below.
These attribute can be given in any order. For instance:
Note D4 1 here @fermata @jump l1, l2
defines an event labelled by here
which is potentially followed by the
next event (in the file) or the events labeled by l1
or l2
in the
score. It has a fermata. Note that
Note D4 1 @jump l1, l2 here
corresponds to the same specification: here
is not interpreted as the
argument of the jump but as a label for the event because there is no
comma after l2
.
Open Score and Dynamic jumps¶
Open Score: specifying alternative follow-ups¶
Usually, musical events are matched in sequence: after an event e, the listening machine looks to match the event that is specified textually after e in the score. So, the score is deterministic: the expected future of each musical event is well defined1.
The @jump attribute of an event is used to specify alternative “continuations” as a list of labels specifying the events that can be expected after e. This feature makes possible to escape the standard linearity of a score to specify open score where the musician may choose between several alternatives to proceed. The resulting score is not deterministic: after an event with a @jump attribute, one of the events listed in the jump list can be expected.
Obviously, the listening machine must be able to disambiguate the possible follow-ups: so, the first events of each continuation must be different.
Here is an example corresponding to the following open score organization:
// INTRO
NOTE G3 1 INTRO
; ...
NOTE G4 1 @jump part2, part2_alt
// PART2
NOTE D2 1 part2
; ...
NOTE D3 1 end_part2 @jump next_part
// PART2 ALT
NOTE E3 1 part2_alt
; ...
NOTE E5 1 end_part2_alt
// NEXT_PART
; NOTE E5 next_part
; ...
Dynamic Jumps¶
Instead of a fixed list of labels, it is possible to use an Antescofo variable. This variable must refer to an event position (integer or float) or an event label (through a string) or a tab of them. This variable may change its value in the course of the performance. In this way, it is possible to achieve “dynamic open score” where the graph of the possibilities is updated during the performance, e.g. following the choices made by the musician, external events, internal computations, etc.
Dynamic changes in the score graph (through the variables appearing in the @jump attribute) impact the listening machine. The listening machine maintains a set of hypothesis about the potential events to recognize in the audio stream. If the changes in the score graph are anticipated enough with respect to the actual jumps, the listening machine will automatically accommodate these changes.
However, if the computation of the jumps are not far enough in time from
the actual jumps, the listening machine must be explicitly warned to
allow the revision of the hypothesis. This is done by setting
true
to the system variable $JUMP_UPDATED
when the modifications are done. It is not easy to define
what it means “far enough” because the temporal horizon used by the
listening machine is adaptive.
Here is a toy example: the idea is to start with an INTRO
sequence and
then to finish with a NEXT_PART
sequence, and in between playing at
most once PART2
or PART3
followed by INTRO
, in any order:
$jumps := [ "begin_part2", "begin_part3", "next_part" ]
$part2_done := false
$part3_done := false
// INTRO
NOTE G3 1 INTRO
; ...
NOTE G4 1 @jump $jumps
// PART2
NOTE D2 1 begin_part_2
$part2_done := true
; ...
NOTE D3 1 end_part_2 @jump INTRO
$jumps := if ($part3_done) { "next_part" }
else { ["begin_part3", "next_part"] }
$JUMP_UPDATED := true
// PART3
NOTE E3 1 begin_part_3
$part3_done := true
; ...
NOTE E5 1 end_part_3 @jump INTRO
$jumps := if ($part2_done) { "next_part" }
else { ["begin_part2", "next_part"] }
$JUMP_UPDATED := true
// NEXT_PART
; ...
In this example, the musician may choose to perform one of the following five scenarios:
INTRO → NEXT_PART
INTRO → PART2 → INTRO → NEXT_PART
INTRO → PART2 → INTRO → PART3 → INTRO → NEXT_PART
INTRO → PART3 → INTRO → NEXT_PART
INTRO → PART3 → INTRO → PART2 → INTRO → NEXT_PART
Score statement¶
An Antescofo text score is interpreted from top to bottom. Score statements will affect lines that follow its appearance.
-
If the
antescofo_is_in_rehearsal_mode
keyword appears in the score, then during fastforward, the local actions are not triggered. This mode is used to avoid too much computations in transports functions.
This mode acts globally on the whole score, irrespectively of its position in the score. Once selected, it cannot be reverted but it is reset when (re)loading a score. -
The
atempo
statement is used -
The
BPM
statement is used to give a tempo specification in the score and its scope extends until the nextBPM
statement. Beware: this is the score tempo, not the musician tempo. The BPM specificiation is used to initialize the inference of the musician tempo. Each time aBPM
appears in the score, the tempo inference algorithm is restared from the given value.
The@modulate
attribute indicates that the tempo must be modulated to the pro rata of the actual tempo of the performer. For example, if aBPM 60
is specified in the score, and the actual tempo of the performance if 70, then an indication ofBPM 80 @modulate
reset the tempo expected by the listening machine to 80 \times \frac{70}{60} \simeq 93.3.
To change Antescofo idea of the musician's tempo, see the command antescofo::tempo. -
The
variance
statement is used to alter the variance parameter of the listening machine. A variance is associated to each musical event. The statement change the variance of the next events for the specified quantity. Use at your own risk. -
The
tempo
statement is used disable or to enable the tempo inference. When the tempo inference is disabled, the nominal tempo specified in the score (throughBPM
statment, are used. -
A
dummysilence
section begins with adummysilence on
and ends withdummysilence off
). In such asection, a special ‟ghost event” is inserted between two musical events. In some contexts, it can improve the behavior of the listening machine (and degrade this behavior in other contexts). -
The
nosyncsection
statement is used to declare a section where all musical events (betweennosyncsection on
andnosyncsection off
) are@nosync
. Such evets are not considered as meaningfull events in the tempo inference. -
The
pizzsection
statement can be used to define a sequence of musical events (betweenpizzsection on
andpizzsection off
) that have the@pizz
attribute by default. -
The
@transpose
ortranspose
statement is used to define a transpose factor used for all subsequent pitch definition. -
The
rubato
statement is reserved for future specification. -
The
top_level_groups_are_tight
andtop_level_groups_are_loose
keywords alter the handling of implicit top-level groups.
The sequence of actions directly defined after the specification of an event implicitly denotes a group with a @loose synchronization strategy. The [top_level_groups_are_tigh] change this behavior to the @tight strategy. The decision can be reverted using top_level_groups_are_loose -
There are two score statement keywords reserved for futur uses:
atempo
andnewtempo
.
-
Even if the specified score is deterministic, the performance is not: musical events can be missed and the temporal relationships of the score are subject to the interpretation of the performer. ↩
-
There is an alternative mechanism that can be used to find the position of a musical event: If the label is a simple identifier
xxx
, its $-form$xxx
can be used in an expression elsewhere in the score to denote the time in beats of the onset of the event, as long as this identifier is not set (anywhere in the score). This mechanism is deprecated. ↩