Nested Tempi ============ *Example directory* (scamp): `examples/Tutorial/11_nested_tempi `__ *Download:* :download:`11_nested_tempi.zip ` Music running with nested tempi: a trombone plays a cyclic quarter-note pattern on the session's accelerating pulse, while a trumpet, forked onto a child clock, plays a similar eighth-note pattern. After a few beats, while the overall session is still accelerating, the trumpet clock starts decelerating to half speed. The music is then notated two ways: nested_tempi.py transcribes from the session's point of view so that the trombone plays straight quarter notes, while the trumpet shows a written-out deceleration from eighth to quarter notes; nested_tempi_child_clock.py records from the trumpet clock's point of view, yielding plain eighth notes in the trumpet and more complex rhythmic notation in the trombone. *Topics:* :doc:`Time & clocks › Advanced ` .. raw:: html
score
.. raw:: html
.. code-block:: python :caption: nested_tempi.py: Recorded from the session/master clock. from scamp import * import itertools s = Session() trumpet = s.new_part("trumpet", default_spelling_policy="c phrygian") trombone = s.new_part("trombone", default_spelling_policy="c phrygian", clef_preference="bass") trumpet_note_pattern = itertools.cycle([67, 72, 67, 68]) trombone_note_pattern = itertools.cycle([60, 55, 48, 49, 48]) # A forked function runs on its own child clock, nested under the session that forked it. def trumpet_part(): # play the trumpet figure in eighth notes until the session reaches beat 3 while s.beat < 3: trumpet.play_note(next(trumpet_note_pattern), 1, 0.5) # slow this child clock to half its current rate over the next 7 beats of the parent # note that this doesn't necessarily mean that we will land on the beat in this child clock # `align_to=MetricPhaseTarget(0)` is what ensures that that happens. set_rate_target(0.5, Moment.after_time(7), align_to=MetricPhaseTarget(0)) # keep playing eighth notes until the session reaches beat 16 while s.beat < 16: trumpet.play_note(next(trumpet_note_pattern), 1, 0.5) # speed the whole session up to 100 BPM over its first 14 beats s.set_tempo_target(100, Moment.after_beats(14)) s.fork(trumpet_part) # transcribe from the session's main timeline -- the default when no clock is given s.start_transcribing() # play the trombone figure in quarter notes until the session reaches beat 16 while s.beat < 16: trombone.play_note(next(trombone_note_pattern), 1, 1) # Stop recording and show the result performance = s.stop_transcribing() performance.to_score(time_signature="3/4").show() .. raw:: html
score
.. raw:: html
.. code-block:: python :caption: nested_tempi_child_clock.py: Recorded from the forked child clock. from scamp import * import itertools s = Session() trumpet = s.new_part("trumpet", default_spelling_policy="c phrygian") trombone = s.new_part("trombone", default_spelling_policy="c phrygian", clef_preference="bass") trumpet_note_pattern = itertools.cycle([67, 72, 67, 68]) trombone_note_pattern = itertools.cycle([60, 55, 48, 49, 48]) # A forked function runs on its own child clock, nested under the session that forked it. def trumpet_part(): # play the trumpet figure in eighth notes until the session reaches beat 3 while s.beat < 3: trumpet.play_note(next(trumpet_note_pattern), 1, 0.5) # slow this child clock to half its current rate over the next 7 beats of the parent # note that this doesn't necessarily mean that we will land on the beat in this child clock # `align_to=MetricPhaseTarget(0)` is what ensures that that happens. set_rate_target(0.5, Moment.after_time(7), align_to=MetricPhaseTarget(0)) # keep playing eighth notes until the session reaches beat 16 while s.beat < 16: trumpet.play_note(next(trumpet_note_pattern), 1, 0.5) # speed the whole session up to 100 BPM over its first 14 beats s.set_tempo_target(100, Moment.after_beats(14)) # fork returns the child clock it created, which we hand to the transcriber below trumpet_clock = s.fork(trumpet_part) # transcribe from the trumpet clock's timeline, so the same music is notated against its tempo curve s.start_transcribing(clock=trumpet_clock) # play the trombone figure in quarter notes until the session reaches beat 16 while s.beat < 16: trombone.play_note(next(trombone_note_pattern), 1, 1) # Stop recording and show the result performance = s.stop_transcribing() performance.to_score(time_signature="3/4").show()