Also from Andrew Faraday

Where else can you find me?

Monday, 30 September 2013

Using Midi, and Pure Data, and mashing up sound

It's been too long, readers, since I posted anything to blogger. I've been busy, and sadly the blog is one of the first things to go, even when I'd just reached the point of putting gifs on a post

Well, this time round I thought we'd have some fun with audio, so let's start with a short clip of sound like this one. I'd download it, it's only two seconds long.

For those interested, this is from the Teabot and it regularly does a good job of informing me and my colleagues that there's a cuppa ready for the drinking.

Let's try analysing the sound the sound a little, it's short, contains three distinct notes, two of which are part of the same syllable, and has quite a hard 'st' sound in the middle of it.

There isn't much more to say about what we're hearing, but what about how the computer makes the sound. As I've said before digital audio is actually a long stream of numbers, each between 1 and -1, which are played at a rate of thousands per second (44.1 thousand, usually). These are interpreted as how far a speaker membrane is pushed or pulled (either side of 0, the resting position) which produces the same pattern as a pressure wave in the air, which you can then hear as sound.

I've also said before that an array in Pure Data holds a list of numbers, which you can then feed into your sound card, to control your speakers.

You can probably see where I'm going with this, if we feed all of the numbers (known as samples) from this sound file into an array in Pure Data, we can then control that sound in a similar way to how we control synthesizers. So, first things first, how do we get it into an array? Try This.

Part 1: Loading sounds in to a Pd array

So, there's an array, named tea, containing my tea sample, but how did it get there?

Once again, let's follow the Pd chain from the top. First is a bang, a button which outputs an activation message, which goes to openpanel. This brings up your usual file opening dialog, when you choose a file in there, it outputs the path to that file (e.g. /home/ajfaraday/Downloads/tea.wav), which is then being passed to a message. As discussed earlier, message boxes send a message down the line, and substitute placeholders (marked with $1, $2, etc.) with whatever is placed in the top, so $1 here will be replaced with the file path. The message itself is fairly simple.

read... resize... the file... the name of the array

this will read the named file, and put it in the array, tea, and re-size it to the size of the file. But only when it is passed to the next object, soundfiler. That's pretty much what soundfiler does, dump sound files into arrays.

So, after clicking the bang and choosing the file, we have it all in an array, it even looks a bit like the waveform you can see on soundcloud (above). Now, what can we do with it?

Step 2: Simply playing a sound

Pure Data can be very simple some times, when we want to play the contents of an array (or table), we can use tabplay~ (as ever, the tilde, ~, means this is an audio object). This, with the name of the array as an argument, plays the sound when it is given a bang. I'm then feeding it into a volume control (*~) and out to my sound card with dac~.

This is very simple, and offers very little control of how the sound is being played, only when.

As I discussed way back in Pure Data and BACON (Part 1), you don't have to keep hitting bangs manually, you can automate them with a metro object and control how regularly that outputs its bang with a number.

Part 3: Automating audio triggers, a simple stutter effect

You'll find what this start's to have an incessant, droning quality, mostly because you're hearing that first (not very well produced) note over and over again. You can have fun with moving that number down to make a very quick repeat (if it's low enough it won't even reach the start of the word), and then moving it back up, in what's known as the 'bouncing ball' effect. This kind of fast audio re-triggering is used by quite a few DJ's, if you listen out for it.

However, this all the time, with no changes, gets difficult to listen to. Let's try taking control of what's going on here with two simple facts, tabread~ can accept a number, which tells it which sample to start on, and any number you can get into Pd, such as MIDI controls, can control anything.

Part 4: Adding position to our stutter

So what're we doing here? Well, I've got the data from the midi keyboard coming in via notein, which gives me the most recently pressed key as a number between 1 and 127. On the two octaves of my small midi keyboard, these are between 48 and 72.

In MIDI Controllers in Pure Data I used spigot to filter out the note-off signals from the keyboard, on this occasion I'm using stripnote, which does the same thing, it's just a little lazier for me to do it that way.

I'm then using maxlib/scale (as I did in How To Make A Musical Instrument in 10 Minutes) to change that range to between 0 and 88,200. Which seems a large, scary, and quite specific number. You might wonder where it's come from. Well, back to the idea of digital audio as a stream of numbers. CD quality audio is usually at 44.1 kHz. Meaning that 44.1 thousand of these numbers are in every second of audio. So, for a two second clip, we need 88.2 thousand, or 88200.

That's a bit of a cheat, not every clip of audio is 2 seconds long. You can find the exact length of our resized array by right-clicking on it and selecting properties. Or, within your patch using arraysize, like so (you may want to do this in future to avoid having to type the length of an array manually):

So we've now taken the range of our keyboards midi numbers and transformed it into the range of samples in the array (give or take a few).

Now, float boxes (f) simply store a number, and if a bang is placed in the left-hand inlet, it will output that number, time and time again. So when we press a key, it changes the number it's storing to a position within the array and whenever the metro fires, the tea sound is played from that point.

When you start the metro, you can press keys and effectively play the different parts of the sound on your keyboard! Like so:

Okay, so it's not the best video, and the screen flickers (this is to do with frame rates, but don't worry about it, just don't, usually, point a camera at a tv or computer screen), but you get the idea. I'm taking direct control of the position of playback from my keyboard.

Well, this is a little limited. But I we can use some of my earlier teaching in Pure Data to take control of other parts of the sound, how loud it's playing, how fast the metro is and when to start and stop the metro direct from the keyboard. Take a look at this...

Part 5: Some more direct controls

I've added comments for which midi controls are entering via which ctlin box (if you don't know what these are, have a look at my earlier post on MIDI) so, from the top-left, lets look at what they're doing.

The first control, labelled 'button', is a button, when it's pushed it alternately outputs 0 or 127, which I've fed into a bang, so every push will be treated the same way. That then feeds a toggle, which will turn the metro on and off. (I may have said before, turning it off is a very valuable feature).

The rotary control is turned, producing figures from 0 to 127, which I've scaled to 0 to 600 which control the speed of the metro re-triggering in milliseconds. Then there's the keys, which I've described in the last part.

Then the mod wheel has been used (via line~ to smooth out the rough edges) to control the volume.

So I can start and stop the sound, control how fast it triggers, where in the sound it starts and how loud it is, all with tactile controls on the keyboard, and I don't have to touch my computer. The only major flaw so far is that the sound won't start when you press a key, as you might expect.

To do this, I'm going to take a send (s) from the key input and send it to the float (f).

Part 6: Triggering with the keys as well...

There's a lot in there, now. It's just starting to get to the point where Pure Data patches get a little difficult to follow. But we should reflect on what's been done here. We've turned a fairly boring sound clip into an instrument we can use to manually control three attributes of sound (the position of playback, a speed we've enforced on it and volume) to make sounds we might not expect to be able to hear from the initial sound.

Again, please excuse some low-quality video, but I think it would be a shame to make this tea-board and not use it to make a little 'teamix'.

I'm exploring some of the sounds it can make here, and not, necessarily attempting to make sounds which are 'commercial', or even musical. But you can see that this is really quite powerful. The important factors here are that every sound I make is repeatable with the same physical actions, every key will always be the same part of the sound.

Next time, I feel, we can probably take this further, notably we haven't changed the speed of playback so far, or tried any effects. There is more we can do with this instrument, but that's for another blog post, I think.

There's a few unfamiliar concepts in this post, and I may not have explained everything very well. If you're confused, feel free to drop me a line at @MarmiteJunction and ask any questions you like. I'm always up for a bit of audio-chatter.

So, until next time, take care, God bless and keep coding.

P.S. As a little extra bonus, here's my second attempt at the 'teamix'