Emulating Csound score parser's time warping feature

Given an Aggregate (or a ScoreSection, if you prefer) we can perform time warping using the timewarp() method.

Let's say we have a file (trivialcloud.sco) containing a score fragment and we want to apply some tempo change. Suppose you can't use the t statement for some reason. We can do it using OMDE even from an interactive Python shell.

Python 2.0 (#2, May 22 2001, 11:42:51) [GCC 2.96 20000731 (Red Hat Linux 7.1 2.96-81)] on linux2 Type "copyright", "credits" or "license" for more information. > > > from omde.all import * > > > score = read_score('trivialcloud.sco') > > > stdout.write(score) i 1.0 0.0 0.4 60.0 261.0 i 1.0 1.0 0.4 60.0 261.0 i 1.0 2.0 0.4 60.0 261.0 i 1.0 3.0 0.4 60.0 261.0 i 1.0 4.0 0.4 60.0 261.0 i 1.0 5.0 0.4 60.0 261.0 i 1.0 6.0 0.4 60.0 261.0 i 1.0 7.0 0.4 60.0 261.0 i 1.0 8.0 0.4 60.0 261.0 i 1.0 9.0 0.4 60.0 261.0 > > > f = Tempo((0, 60), (5, 60), (5, 320), (10, 120)) > > > score.timewarp(f) > > > stdout.write(score) i 1.0 0.0 0.4 60.0 261.0 i 1.0 1.0 0.4 60.0 261.0 i 1.0 2.0 0.4 60.0 261.0 i 1.0 3.0 0.4 60.0 261.0 i 1.0 4.0 0.4 60.0 261.0 i 1.0 5.0 0.4 60.0 261.0 i 1.0 5.21875 0.4 60.0 261.0 i 1.0 5.5 0.4 60.0 261.0 i 1.0 5.84375 0.4 60.0 261.0 i 1.0 6.25 0.4 60.0 261.0 > > >

With the first line

from omde.all import *

you import everything from the omde package. It is a shortcut that I don't like very much but can be useful sometimes like when doing an interactive Python session for a quick and dirty job.

Then we load our score excerpt from a file using the read_score() function.

score = read_score('trivialcloud.sco')

read_score() returns a ScoreSection containing the score except. At the moment only i and f statements are imported. Everything else is ignored. Special features (carry, ramping, warping) are not supported.

Note

In this section I use the two terms ScoreSection and Aggregate as the were the same thing. Tecnically speaking ScoreSection is a subclass of Aggregate. This means that ScoreSection has every property and ability of an Aggregate: for example, just like all possible kinds (or subclasses) of Aggregate you can timewarp() it. But ScoreSection is/has something more that a simple Aggregate: it knows how to transform in a Csound standard numeric score.

After priting the score we create a Tempo object in a way very similar to Csound's t statements, indicating pairs (time, tempo) where the time is expressed in unwarped units name "beats".

f = Tempo((0, 60), (5, 60), (5, 320), (10, 120))

And finally we perform the time warping for real:

score.timewarp(f)

If you prefer, feel free to combine the last two commands in a single line like this:

score.timewarp(Tempo((0, 60), (5, 60), (5, 320), (10, 120)))

Speaking more generally the timewarp() method remaps all events in an Aggregate using the specified function to map time to time.

score.timewarp(f)

f(t) must be a function-like object returning the new onset of an event which currently begins a time t. The Tempo is just an easy way to build such a function in terms of tempo and tempo variations.

If you plan to do this operation several times you may prefer to write a script, something like the following one:

from omde.csound import read_score, save, Tempo

score = read_score('trivialcloud2.sco')
score.timewarp(Tempo((0, 60), (5, 60), (5, 320), (10, 120)))
save('timewarped.sco', score)

That's all.