Tuesday, 21 May 2013

Sequencing and wavetables, part 1: Arrays in Pure Data

So, programmers will know that an array is a list containing pieces of data, referenced numerically. I can tell you that in pure data, it's a list of numbers, which is expressed visually as a graph.

As described in Pure Data and BACON: Part 1, you can create one with Put > Array and define it's length (number of items), size on screen and the numbers it represents by right clicking it and selecting Properties. You can set the actual numbers with a message (connected to nothing) starting with a semicolon, it's name, the first index (usually zero) and then a list of numbers. Finally, you can select numbers from your array with tabread, feeding it the position of the number you want to pull out of your array.

Well, that was a short blog post...






Okay, once again, I can't leave it there without showing you how to make something cool, and for a change I'm beginning to write this without being entirely sure where it's going to finish. So lets start with our basic, start of post patch...

Step 1: How to count upwards, the easy way.



Okay, so what's happening here? Firstly, I've introduced a new object here, f, short for float. Now a float (or, to give it it's real name, Floating Point Variable) keeps hold of a number, and when it receives a bang (the activation message which is generated by metro), it outputs it's number. The right inlet will set the number it's holding, without it being output.

The practical upshot of this is that when we send our float out to + 1, and then back into the right inlet, the number it's holding increases (or increments) by 1. So every time the metro fires, it will move our number upwards, in this case every half second.

Now, you'll also notice this doesn't make any sound yet, and it will, but this would make an awful musical sequence because it would just keep increasing, go beyond human hearing and then back to human hearing via a digital side-effect called foldover (I won't to in to this now, but it's not a terribly desirable sound). Instead we're going to muzzle the numbers this is creating with something called modulus...

Step 2: Make it loop


Modulus is nothing to be scared of! A fact I didn't realise in my early days of Pure Data coding. Modulus (represented here by a percent sign, %) is the remainder after your number is divided by that amount. So here every multiple of 8 will return zero, followed by 1, 2, 3 etc. until it reaches 7, at which point the number will be a multiple of 8 again, and it returns 0.

The practical upshot of this is that you've now got a number which cycles from 0 to 7, providing 8 specific numbers.

So now we can make ourselves some sound...

Step 3: A very simple sequence



I've modified our counter, for a start, it's now one fifth of a second, and counting up to 16. Then, just like my typically starting patch, I've added sixty (to put us in the middle of the range for midi notes), converted this from midi to frequency using mtof, fed that to an oscillator then out to the sound card via dac~.

Do take note that you could write a version of this patch with any of the Algorithms of the Street in place of that osc~, but I'm keeping it simple here.

Now you'll hear a maddening pattern increasing by a semitone (known in music as a chromatic scale), you may want to mute the sound as you start building the next part of the patch.

Step 4: Time to add an array.



So, I created an array, and set it's Properties like so...


So it's got 16 members, and they range from 0 to 24 (at least within the box, you can set numbers outside this range if you want). The I wrote the message to start at index 0 and put that list of numbers in the array. That's a fairly listenable melody based on a minor scale, but you could have any list of numbers here and you will hear the changes in the melody, but I recommend you keep it between 0 and 24.

Actually, I had to sit here writing out the notes of a minor scale in terms of their relationship to the root, in semitones, then write this melody using notes from that list. But we're programming here, and I shouldn't have to sit here choosing from members of a list, I can get Pd to do that for me, so here comes another array.

Step 5: A second array, a scale.



Wait a second, I hear you cry, what second array? I can only see one.

Well, the object 'table' is an array, hidden away. Because we don't need to worry about it's visible dimensions, we don't need to set up any attributes, and a scale looks fairly dull anyway (it's just a line upwards, we can't learn anything from the shape of it) we don't really need it taking up space on screen.

The sequence array, however, shows us the shape of our melody (I've changed it's vertical range to 0 to 14, to match the 15 members of our scale array. So the output of our sequence, instead of being semitones apart, are members of a minor scale apart. This may not mean much to you, but it means the notes we're hearing go together much better.

We can also draw our melody, instead of writing out the number of each note by hand. If you're out of edit mode you can click on one of the points on your sequence array and drag it around, and it's neighbours. There's just one thing we need to do...

Step 6: Drawing a melody



Can you spot the difference?

Well, I've drawn a new shape in my sequence array, and moved the table, scale, out of the way. But importantly I've added an i between my two tabreads. This is an integer or whole number box, mostly what it does is, whatever number is fed into it, it only outputs whole numbers, meaning anything that comes out of our sequence, it will only give the right values to get a member of our scale array.

This is fun in itself, true, but I've only put six steps in this tutorial, and my Pd tutorials always have seven steps, or a seven with a sneaky extra step. So lets look at what we could take more control of here...

  • The plus before mtof could move the whole sequence up or down without changing it (known as transposition)
  • We don't have to use all 16 steps of our sequence all the time, we could change our modulus to define a different sequence size.
  • The speed doesn't have to be constant, either, we can vary that pretty easily.
So, what does a patch varying these three things, as well as the sequence itself, look like?


Step 7: Taking control!

There it is, control at every possible point (although we could expand this patch a lot, some kind of array-based sequencer could be a part of just about every patch we've made so far). I've added simple number boxes (ctrl + 3) for transposition and speed and commented them, there's really no explanation needed here if you've been following so far and know what they do.

I've also introduced a new UI element, the line of boxes labelled sequence size, known as a radio (Puts, Hradio). This is simply a method of choosing one of a list of consecutive values (from 0 to one less than the size you give it, under the right click > properties dialogue, this one has 16). We've added an offset of 1 (+ 1) to make this a bit more useful and feeding it into the modulus box, this decides how far through the sequence array it will read through before restarting. So if you click near the left hand side of it, like me, you'll only get a short slice of your sequence, to the right... all of it.

So that's it, have fun playing around with your simple sequencer.

As ever, feel free to get in touch (@MarmiteJunciton) to let me know how you found it, if you had any problems putting it together, or if you just want to talk tech, music or pizza.

Thanks for reading and God bless

Andrew


4 comments:

  1. Thanks for the information, very helped :)

    ReplyDelete
  2. How did you hide the second array? Thanks

    ReplyDelete
    Replies
    1. The answer is in there. You just create an object named table with the name of the array as an argument.

      [table scale]

      Delete