Music Mouse, Part III
This post is part of a series of notes and exercises for a summer camp on making musical instruments with Arduino and Pure Data.
Music Mouse walks the horizontal axis in steps of one right now. If we were to interpret the x-position as a MIDI number, we’d be walking the chromatic scale, which is really just all the notes that can be found in Western tonal music. Let’s walk the major scale instead.
Scaling Up
When the joystick is pressed right, we want the Music Mouse to get to the next note in the major scale. We’re probably going to need a list of the offsets between its notes.
What were those offsets again?Declare a global array named jumpUps
that holds these offsets. When right is pressed, we want to take one of these offsets and add it on to x
. But which offset?
We don’t know. We don’t have enough information to know where we’re at in the scale. So, let’s declare a global int
named scale_index_x
and assign it 0. We’ll use it to track our current position in the scale. Then when we change x
, we can use scale_index_x
to reach into the offsets array:
x += jumpUps[scale_index_x];
Also, we need to advance our position in the scale. Add 1 to scale_index_x
.
Upload and test your code. If you start at 60 and press right, you should advance to 62, 64, 65, 67, 69, 71, 72, and so on.
Wrap Around
When you advance past 72, you probably see some strange results.
Why?Scaling Down
Okay, we’ve got the joystick’s right action working.
What happens when you press left?Declare a global array named jumpDowns
. Assign it a list of seven numbers that describe how many halfsteps we should jump down to get to the previous note in the major scale.
The assignment to x
needs to get a bit more complicated. We have to choose between jumping up and jumping down. This sounds like a conditional statement, and we’ll use dx
to arbitrate between our choices. Update your code to match this pseudocode:
if old_dx and dx are different if dx isn't 0 if dx > 0 x = x + jumpUps[scale_index_x] increment scale_index_x with wraparound else x = x - jumpDowns[scale_index_x] decrement scale_index_x with wraparound old_dx = dx
For the decrementing, you might have written this:
scale_index_x = (scale_index_x - 1) % 7;
Sadly, the mod operator doesn’t quite do what we want for negative numbers. In particular, it yields negative numbers, which are inappropriate for indexing into an array. Consider the following table that shows what values we want and what mod actually yields:
value | value % 7 | what we want |
---|---|---|
6 | 6 | 6 |
5 | 5 | 5 |
4 | 4 | 4 |
3 | 3 | 3 |
2 | 2 | 2 |
1 | 1 | 1 |
0 | 0 | 0 |
-1 | -1 | 6 |
-2 | -2 | 5 |
-3 | -3 | 4 |
-4 | -4 | 3 |
-5 | -5 | 2 |
-6 | -6 | 1 |
Challenges
Hey, let’s just keep going, okay?