Transport, tempo computation, and others practicalities


 
fragment of a railway turnout
 

Antescofo offers several execution modes to meet many different needs, ranging from automatic accompaniment to manual sequencer. It is even possible to change the mode during an execution. These different execution modes are activated by messages or by their associated internal commands, known as transport commands. These commands are critical to adapt to a wide range of stage set-ups but also in reharseals or during the design phase in studio, as they evades the linearity of the score.


 

Transport

Transport commands control the execution of the computations and their progression. As already mentioned, there are two sources of progression corresponding to the event-driven and the time-driven computations specified in an Antescofo score:

  • the occurrence of a musical event,

  • and the passage of time.

Transport commands can alter these sources, resulting in several execution modes.

For historical and technical reasons, the commands altering the source of progression are not acting independantly on these two but implement useful execution scenarios.

The source of musical events occurence

The usual source of musical event is the listening machine that notify new musical events when they are recognized in the input audio stream.

At any moment, the listening machine can be disabled with the antescofo::suivi command. Two others devices can be substituted to the listening module:

  • an internal player,

  • the message nextevent (and the command antescofo::nextevent) and its variations.

The listening machine

The listening module is selected as a source of musical event with the following internal commands or their equivalent messages:

These command are used to launch the execution of the program and activate the listening module. However, the listening module can be switched off during the execution using the message suivi.

All these commands start the execution from the begining. with the exception of the first one, they imply a target in the score and initiate the execution in fastforward mode: the listening machine is temporarily inhibited until the target is reached and the target is reached using the internal player and using the virtual time (see below). The difference between “startfrom...” and “scrubto...” is in the inhibition Max/PD message during the fastforward phase. And the “reset...” commands kill all remaining active actions when the target is reached, at the exit of the fastforward mode.

The internal player

The internal player simulates the occurence of musical events in the score. It makes possible to simulate the execution of an Antescofo score without the audio input. This mode can also be used to turn Antescofo into a pure sequencer. The internal commands that trigger the player are

When the internal player is active, the listening machine is inhibited. The musical events are simulated using the exact specification given in the score, i.e. all dating reflects the written duration.

The “next...” messages

The message nextevent (corresponding to the internal command antescofo::nextevent) notify the next expected event. It can be used even if the listening machine is active, for example to catch up on an event missed by the listening module.

They are several variations:

The difference between these variants are explained in section Controlling the Execution Flow.

Musical events are linearly ordered, so it makes sense to speak of a next event. A the start of the program, the “next event” is the first event in the score. When an event is labeled with alternative successors, using the @jump attribute, the player select the main successor (the event that appears sequentially in the score after the current one).

The Antescofo idea of the “current event” can be changed using the previous command, but also the following one:

The difference between these commdans is on what is triggered during the jump.

For the sake of the completness, we must point out two commands that can be used to go backward:

These commands are provided to overcome a problem with the listening machine: they allow to reposition the current event E on a past event P. However, actions that have been launched between E and P are not cancelled. Worse, they can be launched again because the execution will resume from P. Generally, when the listening machine has jumped forward, it is more appropriate to inhibit the listening until the musicians catch up with the listening machine, rather than using these controls.

The source of the passage of time

They are two basic sources for the passage of time:

  • the physical time,
  • the virtual time.

The physical time refers to the wall clock time. In the physical time, a delay or a period of 1 s means a time duration of one second (modulo the precision of the machine timers).

The virtual time is used to shrink the time passing between two events as much as possible. In the virtual time, a delay or a period of 1 s corresponds to a time duration of zero second (modulo the time spent in housekeeping procedure). Virtual time replaces the wall clock with a virtual clock running as fast as possible.

Virtual time preserves all datings but in virtual time. For instance, in this mode the variable $NOW reflects the virtual time. So, most of the computations gives the same results under physical or virtual time (however, there are some functions that behave differently like @is_fastforward).

Virtual time is used to implement the fastforward mode, which is useful in rehearsal to start in the middle of the score (it is also used in the stanalone Antescofo application that provides a command line to test Antescofo programs).

When leaving the fastforward mode, the source of time is not set immediately to the physical time if an event is expected: the source is set to the physical time only when the expected event is notified. This has the effect to suspend all computations until the occurrence of the next event resumes the execution.

Physical and virtual time are qualified as “basic sources” for the passage of time because they are the dating system that is ultimately used to schedule all computations. The passage of time, whether physical or virtual, also makes relative time pass. How much relative time is passing when the physical time is passing, depends on a tempo and a specific tempo is computed for each temporal scope: the computation depends on the reference and the synchronization strategy but also on the source of the events.


 

Tempo computation

There is a link between the occurence of musical events and the passing of relative time: the interpretation of a duration of 1 beat depends on the current tempo which is infered from the occurence of musical events.

The tempo inference is initialized by the BPM specification that appear in the score. It is possible to overide the BPM specification by a tempo curve using the command: antescofo::musician_tempo. For instance, this make easier to specify an accelerando. Nota Bene that the BPM indication (or their overriding) do not fix the tempo: the musician interpretation can depart from the specification in the score.

At any moment, the current tempo can be set using the command antescofo::tempo. But once it is set, it will be updated by the tempo inference algorithm. The tempo inference can be switched off only if the listening machine is switched off (using suivi 0) because the listening machine relies crucially on the tempo inference.

When musical events are expected (that is the following is on and when the current event is not the last one) they can be notified by the listening module or by nextevent or nextlabeltempo commands. At each event notification, the tempo is updated. The tempo is not updated when:

  • other transport functions (like antescofo::nextlabel) are used to notify a musical event,

  • the event notified by the listening machine is not the event that immediately follows the current event (i.e., in case of missed events),

  • on a jump,

  • on the first two events in the score (because duration are hardly respected at the very beginning of the performance).

For historical reasons, the variable $RT_TEMPO is updated only when the listening module notifies an event. So this variable does not reflect accurately the current tempo. Another discrepancy is when the score tempo is specified by a curve: the variable does not reflect the variation of tempo in-between two events.

If musical events are expected but not reported, the current tempo is set to zero starts after the non-reception of 8 events. To override this behavior, the command antescofo::bypass_temporeset can be used. This is useful when Antescofo is used as a sequencer but the score still contains musical events (these musical events can be used to structure the computation or to implement symbolic dates on the timeline). But in both case, the tempo value used to compute relative duration is the real inferred tempo.

Interactions with the synchronization strategies

These various mechanisms combine as expected with the synchronization strategies. Here are some examples.

The following program exhibits different behaviors depending on whether the commented lines are uncommented or not:

; antescofo::bypass_temporeset "on"

BPM 60
NOTE C4 1
   loop 1 
   ; @tight
   ; @tempo := 80
   ; @tempo := $RT_TEMPO
   { print $NOW } 
NOTE C4 1
NOTE C4 1
NOTE C4 1
NOTE C4 1

BPM 120
NOTE C4 1
NOTE C4 1
NOTE C4 1
NOTE C4 1
NOTE C4 1
NOTE C4 1

; ...

We start this program, with no audio input:

  • if all comments are preserved: then nothing happens until we send the nextevent message (e.g. the patch used for examples and tutorial, has a dedicated button nextevent).
    Upon reception of the nextevent command, the loop is started and the printing messages produced by the loop body appear on the console. After 8 iterations, there are no more messages because no events have been notified. Then, if we send an additional nextevent, more iterations are executed until the no-message limit is reached again.

  • if antescofo::bypass_temporeset is uncommented: then nothing happens until we send the nextevent message.
    Upon reception of the nextevent command, the loop is started and the printing messages produced by the loop body appear on the console for ever.
    However, one may notice that tempo of the loop changes at some point. This was also the case for the previous example. As a matter of fact, the loop is synchronized with the @loose strategy. So, the loop follows the tempo specified in the score and after 4 iterations, the tempo is changed for 120 bpm.
    We insist: a BPM specification is not a tempo prescription: it is only used to reset the tempo inference algorithm. But because there are no further event notified in this example, the BPM specification becomes the Antescofo idea of current tempo.

  • if @tight is uncommented: then nothing happens until we send the nextevent message.
    Upon reception of the nextevent command, the loop is started but stops after one iteration according the @tight synchronization strategy where the computation progress up to the reception of the next event.
    Subsequent nextevent can be used to progress, step by step, in the computations.

  • if @tempo := 80 is uncommented: then the loop follows the prescribed tempo, irrespectively of the musical events notifications.

  • if @tempo := $RT_TEMPO is uncommented: then the loop follows the tempo specified by $RT_TEMPO. This variable is updated only when the events are notified by the listening machine. So, in our case, it will remain constant until the follower is switched on. This behavior makes easy to ensure a constant tempo when the progression is achieved by hand (sending manually nextevent messages) and at the same time, to follow the tempo of the musician when he or she is the source of the musical events.