teaching machines

Counting in Time

June 26, 2019 by . Filed under electronics, music, public.

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.