Counting in Time
This post is part of a series of notes and exercises for a summer camp on making musical instruments with Arduino and Pure Data.
Musicians are servants of the beat. But who controls the beat? In this exercise, we do. We will create an abstraction named ticker
that provides a steady pulse that will drive our music forward.
Client View
Clients of ticker
will want to start ticking and stop it, so we’ll need to send two different types of messages to our abstraction. Let’s use a bang to start and an explicit stop
message to stop. To keep things simple, let’s pass the delay between beats as a creation argument.
Here, for example, we drop a beat every 1000 milliseconds:
We don’t hear the beat, but we see the bottommost bng
flash in time.
Steady Pulse
With the client’s view in mind, we are ready to implement our abstraction in ticker.pd
. A couple of objects will be very helpful here.
The first is route
, which we use to fire off different parts of our patch depending on whether we are starting or stopping. Object route
expects a list of possible messages and sends a bang along the matching outlet.
The second is metro
, which fires off bang messages every so many milliseconds. It starts pulsing when it receives a bang message and stops when it receives a stop
message. But isn’t this exactly what we want ticker
to do? Why not just use metro
directly? Ultimately, as you’ll see, we want to send more than just bang messages, but our first step is to wrap around metro
.
To keep the patch organized in cohesive chunks, let’s use send
and receive
to communicate between chunks. This may seem to add unnecessary complexity, but it will pay off later. Here’s our first draft:
Note how we pick up the creation argument using metro $1
. The pulse is sent back to the client through outlet
. When we fire off a bang in the client, we should see our ticker
give a steady pulse.
MIDI Beat
Instead of just pulsing a bng
, let’s use ticker
to generate MIDI notes. When the client receives a pulse, we use makenote
and noteout
to play MIDI note 60 for 500 milliseconds:
Counting
Currently ticker
just provides a flat pulse. What if we wanted to tick through a range of numbers instead, just like we do with loops in other programming languages? We could use the numbers that are output to generate scales or indices. This client, for example, plays a chromatic scale from MIDI notes 60 to 72:
Note how we’ve added two more creation arguments to ticker
to express the range of numbers we want to tick through. The output is now a number, not a bang.
Let’s add counting to ticker
in several stages.
Outputting Lo
First, instead of walking through the whole range, let’s just emit the starting number on every pulse. The starting number will arrive in our abstraction under the name $2
.
We’ll add two new chunks to our patch. The first, which will be triggered by an initialize
signal, will be responsible for initializing the cold inlets of various objects based on our creation arguments.
The second, which will be triggered by a tick
signal, will be responsible for handling each tick of the metronome. For the time being, we just emit a float that has been initialized to the starting number, which we call lo
.
With our two new chunks, our abstraction looks like this:
Note how route
first signals initialize
and then start
when the ticking begins.
Incrementing
Our next step is to start counting up. We need only make one change, but it’s a weird, mind-bending change. At the same time that we emit a number back to the client, we also feed that number into a + 1
object. This incremented number is then fed back into our float
that’s serving as our counter. The patch looks like this:
In any normal programming language, this would cause an infinite loop. But because we’re feeding the incremented number into the cold inlet of the float
, nothing breaks, and the number does start counting up.
Stopping at Hi
Our last step is to stop ticking once we’ve reached the maximum value of the range. We use the moses
object to trigger a stop
message when we’ve gone past the maximum value. moses
expects a threshold value and behaves a bit like this:
function moses(threshold) value = read left inlet if value >= threshold emit value on right outlet else emit value on left outlet
Our patch needs to be changed in a few places. We add the moses
object to the chunk that handles ticks. It sends a stop
message when it sees the first number beyond the range. Otherwise the number is emitted to the client as before. Also, we need to initialize the threshold value in the initialize chunk. We receive the ending number under the name $3
. We add 1 to it and feed it to moses
.
All told, our patch now looks like this:
When we fire off ticker
in our client, we should now hear an octave of the chromatic scale.