Friday, 26 April 2013

How to make a musical instrument in 10 minutes.

First things first, an update.

My talk at this years BACON has been released for the whole world to see. Needless to say I'm pretty excited about the whole thing. If you've been enjoying the Pure Data tutorials I'd recommend you take a little time to check out the video.

The really excited part is that on the strength of that, I wound up showing off one of my old Pd party pieces at this months Music Tech Meetup at the London offices of Mozilla. Great location and fantastic crowd of techies and musos alike, it's definitely my kind of evening. Including talks on a new music aggregation service and an almost literally viral marketing campaign. 

Then there was myself, once again it seems techies like to see music software come together in short order. So I did one of my old favourites, How to make a musical instrument in 10 minutes. I know it's a big claim, but I've managed it a few times now. It's a simple system to control a synth with your mouse position, start and stop the tone (with a little volume envelope) and a simple effect for good measure. I thought it was time I popped it online so folks can try it themselves at a more leisurely pace. So here it is:

How to make a musical instrument in 10 minutes. 

Groundwork here, you've seen it in earlier posts, and if not, I'd start a little earlier than this and get some basics. It's an oscillator, with a multiply to reduce the volume. Actually, it's probably time for a little maths refresher to help us out with volume controls in pure data. 

Multiply anything by 0, the result is 0.

Multiply anything by 1, the result is what you started with.

Now, digital audio is actually a high speed stream of numbers, between 1 and -1. The further this stream of numbers gets from 0, the louder your sound will be. Simple enough? The raw output from an oscillator ranges from 1 to -1, meaning it uses all of the digital audio stream, and potentially produces quite a loud sound. Also, when and if we add anything else, it can't output numbers higher than 1, we lose some of the definition of the sound we're producing. So we multiply by less than one to give ourselves some head room. 

We can also multiply by 1 or 0 to simply turn the sound on and off. But if we do that all at once, we tend to hear a click as this stream of numbers moves between where it happens to be, and 0 all at once. So, to avoid this unwanted click we use something like this...

Step 1: Add a volume envelope

The new object here, line~, simply creates a line, or envelope, which takes a given amount of time to move from the number it's on, to another number. The tilde(~) denotes that it's an audio object, so it draws this line, but outputs it as a digital audio signal. 

The boxes above the line~, are messages (Put > Message or ctrl + 2), for the time being they just output their content when clicked. There are other things you can do with them, but more on that a little later.

The messages being passed to it consist of a target figure, and how long it will take to get there. So if you click the message on the left, the volume will take a tenth of a second to get up to volume, and if you click the one on the right it will take a whole second to fade out. Simple enough, now all we need to do is make life a little easier...

Step 2: Turn two messages into one. 

As a tiny refresher, the toggle box (Puts > Toggle, or ctrl + shift + t) expresses booleans as 0 and 1, and switches between the two. Also, I've replaced the number 1 with $1, which is simply substituted by the first thing passed in to the message. So when we click the toggle, it will ramp up to 1, or down to 0 in a tenth of a second. The result is a short fade in or out of that tone. 

Step 3: Take direct control

Okay, I've done a few things here. Firstly I've used the object MouseState, there's no particular concept for that to illustrate, it just feeds some data from your mouse into Pd. Although first you've got to pass it the message 'poll'. For more on that, like almost everything else in Pd, you can right click on MouseState and see a working help patch which demonstrates exactly what it does. So I don't have to talk much about it, except that once it's had the 'poll' message, that left hand inlet tells us if the mouse button is pressed or not. 

It's then being passed to a mysterious object called s. This is short for send (you could also type the word send), and a name I've given it. As it's telling me about my mouse button I've called it btn. Then, if something's sent, it re-appears on the patch where you see r, for receive, and the same name. So when you click your mouse, it will send a toggle into the send called btn and the receive called btn will get it and send it to the volume envelope. In short, when you click your mouse, that note will be heard. 

But it's just one note...

Step 4: Take control of the pitch, too.

Well, I've just added a send to the second outlet of MouseState (which the help patch will tell you is the X, or horisontal position of your mouse) to a send called x. You may have to click poll again to make sure this number's changing but when you do, you'll find that moving your mouse left or right will change it, this depends on the size and resolution of your screen, but it will be 0 on the far left hand side and something higher than 1000 at the far right. 

Above the oscillator, we're receiving the send called x and putting it in to something that looks a lot like the volume envelope we made earlier. It's actually identical, do make this easier drag select the message box and the line~ and press ctrl + d, which simply duplicates the selected objects and you can drag them up there. This will take the harsh edges off the numbers we're getting from the mouse position, which then controls the oscillator. 

However, it's controlling the pitch of our oscillator, not it's volume, so we'd call that a volume envelope. 

And you're done!

No, really. It's a musical instrument. Clicking your mouse starts a note, releasing it stops the note and moving your mosue pointer around changes the pitch. It's not very precise or easy to control, but it's essentially a musical instrument. It only listens to clicks made on a Pure Data window, so you might want to full screen the window for more playing space. 

Try a simple rendition of the Dr Who theme, it'll sound horrible. 

But you don't want to leave it there...

Step 5: Cause a little delay

Another pair of corresponding objects here, delwrite~ and delread~, these work a little like send but, oddly enough, with a delay. So delwrite~ builds up a buffer with a given name, in this case d1, and a length in milliseconds, we're using 1000 milliseconds, or a second. 

delread~ is reading d1 and outputting it 1000 milliseconds later, to another dac~ which also outputs the sound to your sound card. 

It doesn't take a genius to realise that what you'll hear now when you click your mouse is the same sound you heard earlier, but repeated a second later. It's a kind of echo, only a really strange echo because its exactly the same volume as the initial sound and it only echoes once. We can fix both of these problems like so:

Step 6: Feed it back

More new objects! 

These ones are pretty straight forwards, tho. s~ and r~ are audio sends and receives, they work in the same way but they move audio around on a named bus, instead of control signals. So after your sound is delayed by a second it is then fed back into the delay machine. 

And I've added a *~ to reduce the volume of this echo by half every time it feeds back. So sounds you make will repeat every second at half of their volume, until they can't be heard any more. It's a real, big, spacey echo and if you use it a lot you'll quickly start to hear a fairly busy soundscape. It build up pretty quickly, tho. I'd suggest you use it quite sparsely.

One last thing to do to this patch...

Step 7: Take control of your feedback

Again, a handful of things have happened here, I've used the third outlet of MouseState to get the vertical position of my mouse and sent it to a send called y. But between those is something a little scary with 4 arguments. 

This used to be called range, but someone involved in the development of Pure Data decided it would be better named maxlib/scale. It simply transforms a range of numbers, the first two arguments (it will be 0 at the top, and your screen height at the bottom, mine is 767 pixels so that's what it is) into another range, the second two arguments. So here we're making the height of our screen change the send y between 0 and 1. 

This is received just above our delay line, fed into the multiply via a line~ (notice that I've taken out the argument, and this means the right inlet is a heavy audio inlet, instead of an empty signal inlet) and that's the feedback level of our delay generator. 

Now if you click your mouse to make a sound and hold your mouse pointer at the bottom of the screen that sound will not decrease in volume and will continue indefinitely. If you move your mouse to the very top, there will be no delay at all. 

I generally hover somewhere three quarters of the way down.

Anyway, that's it. As ever you can follow me @MarmiteJunction and feel free to ask any questions about this tutorial, let me know how you found it. Does it make sense? What would you like to see next? 

No comments:

Post a Comment