Visualizing the tempo changes and the beat progression in a group¶
This how-to details a possible approach to visualize the local position progression and the local tempo change in an arbitrary group. We illustrate the approach on a specifioc example but the reader may adapt it immediately to its proper needs.
We suppose that some external process drive a tempovar $pos_to_play
. To make the example self-contened, we emulate this
process by a loop that shrink in time:
@tempovar $pos_to_play(85,1) := 100
$p := 1
Loop DRIVE $p s
{
$ref_tempo := 60./$p
$old_p := $p
if ($p > 0.5) { $p *= 0.9 }
$pos_to_play := 1
} during [20#]
The loop DRIVE
is used as a kind of metronome
implementing an accelerando. The period is given by $p
and starts at 1 second, i.e. a tempo of 60 BPM. At each iteration, the
period is shortened until it drops below 0.5, i.e. a tempo of 120.
The tempovar is initialized with a tempo of 80. Therefore, the tempo
computed by the tempovar will start to decrease (slowly) and then
increase until is alignment to the tempo fixed by the limit valiuue of
$p
.
We suppose that the tempovar is used to control the timing of a loop spanned by a whenever:
$graincurvesduration := 50
$t := []
$tt := []
$pos := []
$rpos := []
$rcpos := []
$tpo := []
$ftpo := []
$xx := []
$top_x := []
$top_t := []
$top_delta := []
whenever ($pos_to_play == $pos_to_play)
@exclusive
{
@local $x := 0
_ := $tt.push_back($NOW)
_ := $ftpo.push_back(60./$p)
Loop L $graincurvesduration ms
@sync $pos_to_play
@Abort {
$top_x.push_back(60. * $x)
$top_t.push_back($NOW)
}
{
$x += $graincurvesduration/1000.
_ := $t.push_back($NOW)
_ := $pos.push_back($pos_to_play.position)
_ := $rpos.push_back($pos_to_play.rnow)
_ := $rcpos.push_back($pos_to_play.rcnow)
_ := $tpo.push_back($pos_to_play.tempo)
_ := $xx.push_back(60.*$x)
}
}
The nternal loop L
is used to emulate an activity whose
timing is driven by the tempovar. The period is fixed in absolute time
and the variable $x
is incremented at each iteration. The
others variables are tabs recording various informations during the
run.
The expression ::antescofo $pos_to_play.position
returns the current
position (in beat) of the tempovar. This expression could have been
replaced by @local_beat_position()
which is more
general. Function @local_beat_position returns the position in beat of
the current temporal scope. So it can be used for any kind of
synchronization reference. Similarly for ::antescofo
$pos_to_play.tempo
and @local_tempo.
The information recorded can be ploted using @gnuplot:
11 s
$gnuplot_path := "/usr/local/bin/gnuplot"
; $gnuplot_linestyle := "lines"
_ := @gnuplot(
"tempo", $t, $tpo,
"forced tempo", $tt, $ftpo,
"position", $t, $pos,
"rnow", $t, $rpos,
"curveX", $t, $xx,
"maxX", $top_t, $top_x
)
and the execution of the full program builds the following plot:
The timing and synchronization behavior can be read as follow:
-
The violet staircase curve tempo represents the tempo computed by the tempovar. It decrease and the it converges to the tempo forced by the
DRIVE
loop. The curve is a staircase because the tempo computed by a tempovar (using the E. Large approach) is updated only when the tempovar is updated. -
The tempo emulated by the
DRIVE
loop is pictured in green (curve labeled forced tempo). It increases starting from 60 until it exceeds 120. -
The value of
$x
starts at 0 eachtime the whenever is activated. It increase linearly with the iteration of the loopL
. It is ploted in yellow and labeled curveX. The body of this loop records also the local tempo and the local position. -
When the whenever is activated, the previous activation is killed (as a result of the @exclusive attribute). The abord handler of the internal loop is used to record the maximal value reached by
$x
. This value is ploted on the blue circled curve labeled _maxX_q. Because the period is shrinking, the maximal value reached by$x
decreases until the period stabilizes.