Event Specification

First measures of Nachtleben, Sasha J. Blondeau, 2014.
First measures of Nachtleben, Sasha J. Blondeau, 2014.


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).

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 NOTEs 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 and A#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 and NOTE A#4+50 or NOTE 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:

chord notation

 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 notation

 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 notation

 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.

gliss notation
 
 

 MULTI ( (F4 C5) -> (D4 A4) ) 4.0 

Event 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. If the label is a simple identifier, its $-form can be used in a expression elsewhere in the score to denote the time in beats of the onset of the event.

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"

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 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 next BPM 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 a BPM 60 is specified in the score, and the actual tempo of the performance if 70, then an indication of BPM 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 (through BPM statment, are used.

  • A dummysilence section begins with a dummysilence on and ends with dummysilence 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 (between nosyncsection on and nosyncsection 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 (between pizzsection on and pizzsection off ) that have the @pizz attribute by default.

  • The @transpose or transpose 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 and top_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: atempoand newtempo.



  1. 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.