< Back to IRCAM Forum

Timing

Dear all, I wish you a happy new year.

I’m still working hard on getting Antescofo follow the notes of my piece for flute. I’m beginning to become desperate about it, because I’m encountering a lot of problems of which I have no idea how to work around these. It seems to me that Antescofo often only relies on the temporal grid given by the score and doesn’t adapt to the performance of the musician. The flutist takes some notes and rests actually longer (or at a slower actual tempo) than given in the score. I assumed that this shouldn’t do any harm to the detection of notes. But I see Antescofo going astray sometimes, missing one or several notes. Most of the time later it catches up again, but important actions may have been triggered at the wrong time or skipped. I’ve tried out different synchronisation strategies but that didn’t help.

To give an example: Up to measure 31 Antescofo seems to be well-aligned with the performance (almost perfectly in tempo, which is BPM = 69). When the flutist plays the first ordinario A4 after the long aeolian A4 (which is held by the performer for about 0.5 s longer than the note’s duration in BPM = 69), Antescofo detects the Bb4 instead (i.e. even a different pitch) which actually comes only 5 beats (a bit more than 4 s) later. The effect is, among other details, that ring modulators which should colorize the sound of the ordinario A4 attacks are not heard, or rather only for the duration of a crack, because the signal route is closed immediately after it was opened, as Antescofo skips all the notes in between.


; ----------- m.29 -------------
NOTE 7350 1/11 ; Dd5
group @global @tight { /* actions */ }
NOTE A4 1/11 ; A4
NOTE 7350 1/11 ; Dd5
NOTE A4 1/11
NOTE 7350 1/11
NOTE A4 2/11
NOTE 0 1/11
NOTE 7350 1/11
NOTE A4 1/11
NOTE 7350 1/11

NOTE A4 1/4
NOTE 0 1/8
NOTE 7350 1/8
TRILL ( A4 ) 1/2 ; flz
group @global @tight { /* actions */ }

NOTE 0 1/9
NOTE 7350 1/9
group @global @tight { /* actions / }
NOTE A4 1/9
TRILL ( A4 ) 1/3 ; flz
group @global @tight { /
actions */ }
NOTE A4 1/3

NOTE 0 1/10
NOTE 7350 1/10
group @global @tight { /* actions / }
NOTE A4 1/10
NOTE 7350 1/10
TRILL ( A4 ) 3/5 ; flz
group @global @tight { /
actions */ }

; ----------- m.30 -------------
TRILL ( A4 ) 1/4 ; flz
NOTE A4 1/2
NOTE 0 1/8
NOTE 7350 1/8
group @global @tight { /* actions / }
NOTE A4 3/2
group @global @tight { /
actions / }
NOTE 7350 0
group @global @tight { /
actions / }
NOTE A4 1/4
3/4 group @global @tight { /
actions / }
3/4 group @global @tight {
/
actions, e.g. open input route to two frequency shifters */
}
NOTE 0 5/4

; ----------- m.31-33 ----------
NOTE A4 12 ; aeolian pp indiff.
NOTE 0 1

; ----------- m.34 -------------
NOTE 0 1/8
NOTE A4 7/8 ; ordinario
group @global @tight { /* actions / }
NOTE 0 1/8
NOTE A4 7/8
group @global @tight { /
actions / }
NOTE 0 1/8
NOTE A4 7/8
group @global @tight { /
actions */ }

; ----------- m.35 -------------
NOTE A4 2/3
group @global @tight { /* actions / }
NOTE A4 4/9
group @global @tight { /
actions */ }
NOTE A4 4/9
NOTE A4 4/9

NOTE A#4 1 ; Bb4
group @global @tight {
/* actions, e.g. close input route to the two frequency shifters /
}
NOTE 0 2
group @global @tight { /
actions */ }

What can I do in a context like this to get Antescofo on track?

Happy New Year also!

I’m quite new to Antescofo, so this question is probably one you’ve already excluded: in your example what is the pitch that is actually sounded by the flute at the “first ordinario A4”? If the instrument or the player happen to have drifted sharp, then the detected Bb4 could be Antescofo behaving “properly”.

I’d probably add a visual display of the incoming pitch in my Max host (using say [sigmund~]), to check, before trying to change Antescofo parameters.

Best wishes,
Neal

Happy new year to everyone on the list! :slight_smile:

@kyl: Thanks for posting. Here are some guidelines to bring Antescofo on track:

From your description, Antescofo gets lost on the long A4 note that has a duration of 12 beats and desperately jumps to the A#4 way beyond. This passage contains a lot of repeated A4 notes and silences which means that Antescofo audio input is more or less similar (aka non-informative) and thus becomes sensitive to other parameters. We therefore need to make sure other parameters are coherent :

(1) Check Calibration: If you have a recording of this passage, look at the Calibration output of Antescofo. I actually suggest that you integrate this into your patch and leave it ON all the time! If during the long A4 note the calibration goes down (below 0.5) then Antescofo will detect the following silence and attempts to move forward. By increasing your input gain to Antescofo you can avoid this. I suspect that this is the main cause.

(2) Reduce Variance: You mention that Antescofo jumps to the Bb4/A#4 and you have aeolian sounds. Reduce Antescofo’s variance (which is its pitch sensitivity) by introducing a line VARIANCE 0.2 in your score (default is 0.3). This way, Antescofo won’t mix up close pitches.

(3) Add more silence in the score: If you still encounter the same behavior it might be that (following 1), you need to add more “silence” events in your score. If for example you have 3 consecutive A4 notes followed by a silence, and the musician makes a big silence between the first two A4, Antescofo might jump to the 4th silence event. You can avoid this by introducing silence between events.

(4) Add Fermata: If calibration is correct (issue 1 above) and you still see Antescofo progress using Tempo, and tempo detection is not important in your passage, I suggest adding a @fermata attribute for example to the long A4 note. This will allow Antescofo to stay longer on that event without any problem, not use Tempo to progress, and also to avoid tempo update on that event.

Hope this helps. Let us know.

Arshia

@Neal: A good point. I measured the frequencies and indeed, the flute is significantly high in the recording which I use for tweaking the score, about 25 C. I wasn’t aware of this because the frequencies in the accompaniment are defined as relative proportions. And behold, after I changed the Antescofo tune from 442 to 448 Hz, the Bb4 was detected at the right moment. This is very good, indeed. However, there are some other passages where Antescofo passes ahead of the performance, where the pitches of the confounded events are not close but rather more than an octave apart (e.g. D5 and B3).

@Arshia: Thank you for these hints. All four sound reasonable. I will try it out and let you know about the results.

@both of you: Many thanks for your advice!

That’s interesting observation!!! Thumbs up to @nealfarwell

Just for info, when you’re in the Calibration Mode of Antescofo, the second output in the list is actually the probability of an A4 note (MIDI 69) using the tunning you have. If the probability goes high enough (towards 1.0) when an A4 is played it means that the tunning is fine, if not then you can try until you get an acceptable output.

Just out of curiosity, is this tuning situation normal on a regular flute? In my personal experience I had seen flute tuning go high when the instrument is used for a long time (getting hot!).

Yes, woodwinds in general and notably flutes rise in pitch when they warm up (while singers and strings tend to sink). After warm-up the instrument should be tuned to concert pitch (anything between 440 and 443 Hz, many musicians seem to prefer a higher pitch). But we forgot to retune the instrument after a break during a longer rehearsal session.

In the meantime I managed to improve the score so that Antescofo follows more reliably. I played around with event and action attributes, internal commands (antescofo::gamma and antescofo::variance), tempo adjustments, re-grouping of actions etc. so it’s difficult to say what in the first place or for the major part helped most. In my score, synchronisation is almost always tied to notes played by the performer, i.e. tight. So I guess that the most important change was to more often tell Antescofo explicitly to go tight. This is less obvious than it seems. In my observation, Antescofo has a tendency to consider events “late” (even when fast-forwarding). So in the course of a performance it becomes increasingly likely that, even when an event is recognized accurately almost on its onset, actions are omitted (because of the default loose synchronisation scheme), although there would have been enough time.

I wonder if it’s due to that notion of “lateness” that the result is less deterministic than I’d expect it to be. I tweaked the score using one and the same recording of the performance for all tests. But even when I repeated a test without having changed anything, there were differences in the timing of actions and even their appearance or non-appearance.

Yesterday however, unfortunately during a semi-public performance (a private workshop presentation), the environment (Max with Antescofo, patch and score) crashed. The first crash happened after about 6 minutes (about half of the piece). We then tried to continue at a later point in the score but it took less than a minute until the next crash. We tried again after having rebooted the computer, the next crash happening after 5 minutes. From that moment on fast-forwards to a label in the middle of the score made Max crash immediately. I had to resort to the recording of a test run I had made the day before to not completely disappoint the audience. Today I tracked down the offending lines in the score by gradually narrowing the difference between working and non-working versions. It’s a group marked as global and tight which contains the instantiation of a process. Of course, I can send you more details.

Hello Kyl.
Can you send us (privately) the stack trace of the crash and the score? It will be very useful to elucidate the cause.

You mention that: “Antescofo has a tendency to consider events “late” (even when fast-forwarding)”. Beware that

  • There is no recognition of musical events involved when fast-forwarding, they are simulated by Antescofo itself to implement the progression. So the timing must be reliable, but
  • when fast-forwarding (i.e., during a startfrom... or a playfrom...) the Max/PD messages are not sent to Max/PD. The command scrubto... must be used if the messages must be sent until the point of arrival (and then switching the mode). See controlling the execution flow in the reference manual.
Can it explain that you perceive a tendency to consider events “late” when fast-forwarding?

To track where Antescofo is late, you can print easily the recognition of an event using the following construction:

whenever ($BEAT_POS == $BEAT_POS)  
{ print "I am at position" $BEAT_POS " at time " $NOW }

Put this two lines at the beginning of the score. Then, the body of the whenever will be performed each time $BEAT_POS is updated by Antescofo, i.e., each time an event is recognized. It enables to check that the actions are launched at the right moment (by tracing also the actions).

Another point is that in the case of repeated musical events, the use of a tight strategy is not always a good solution, because the listening machine may drop more easily one of the repeated events (e.g., perceiving fewer events but with a longer duration). In this case, it may be better to anchor the actions to the previous musical event (that differs from the repeated events) and to use delays and a loose strategy to trigger the action at their correct date. If the tempo is not correctly inferred, a fixed tempo can be used. For example:

NOTE C4 1  
NOTE D2 1  
   A1 @tight  
NOTE D2 1/2  
   A2 @tight  
NOTE D2 1/2  
   A3 @tight  
NOTE D2 2  
   A4 @tight

becomes

NOTE C4 1  
  Group G   
  {  
     1 A1  
     1 A2  
     1/2 A3  
     1/2 A4  
  }  
NOTE D2 1  
NOTE D2 1/2  
NOTE D2 1/2  
NOTE D2 2

The progression of group G follows the tempo of the performer. If the tempo inference if defective during the repeated notes, it is possible to fix it by hand

NOTE C4 1  
  $tempo_value_at_C4 := $RT_TEMPO   ; $RT_TEMPO is the current value of the infered tempo  
  Group G @tempo $tempo_value_at_C4   
  { ... }

In this way, the group G follows the tempo of the performer as detected on note C4, not the tempo detected during the repeated events.

Hello JLG,

thank you for your response.

My remark regarding fast-forwarded events being “late” was rather pour plaisanter (my fault to have omitted the smiley), because lateness actually is not important here. When enabling the “missed” outlet of the Max object, “EARLY”, “LATE” and “Missed” events are logged to the Max console. When fast-forwarding, all events until the target label are “LATE”.

Regarding repeated notes, yes, I already learned that these must be handled specifically. Because of this I’ve already re-grouped the actions in some passages very similar to your example. But sometimes the tight variant works quite well – not because synchronisation actually is tight, I guess, but because Antescofo seems to infer the loose variant.

Still, I’m sure that my score can be improved regarding synchronisation strategies.

Regarding the instantiation of a process in a global tight group, this is the point to which I narrowed down the difference between a version of the score crashing in fast-forwarding and a version waiting seemingly healthy at the destination label. The only mysterious fact is that during the rehearsal on the same day (yesterday) we also encountered a crash at about the critical point (between labels “L” and “M”) but we still were able to fast-forward beyond that point (label “O”) and execute the score until the final event. I’ll send you the score separately.