Also on AndrewFaraday.com

Where else can you find me?

Monday, 28 July 2014

Who want's to be a Rails Coder? (Part 2) - Our first Model

So, I've just written a lightening-tour of Ruby on Rails, right up until the point where we're ready to get started writing some code. If you want to skip this, install RVM and run the following commands on the command line:

  rvm install 2.1.1
  rvm --default use 2.1.1
  gem install rails --version=4.1.0
  rails new who_wants_rails
  cd who_wants_rails
  rake db:create

Now, the aim of this series of tutorials is to implement a popular quiz format with Ruby on Rails, learning about the components of the framework as we go. Let's start with a model, as I said in Part 1, models handle interaction with the underlying database and house the logic of your application, defining things it can do.

A model is a type of class, which can broadly be defined as a type of thing. You can create an instance of that class, which is one of that type of thing. A class defines methods which are actions which can be done to instances and class methods which can be done. Also an instance of a class can have attributes, which are specific pieces of information about that thing.

I realise that's a little vague, but it's a brief introduction to the terminology I'm using.

Lets put some of this into practise:

Now, the word 'model' is not an accidental term, in software, we use classes to represent (or 'model') other things. As a general principal, if we can define what something is, what we know about it, and what it does in logical terms, we can model it with software. So lets define what we know about a question in our popular quiz format.

  1. It has some text, the question itself, which people want to see before answering it
  2. It has 4 possible answers
  3. One answer is correct
  4. It is used at one of 15 points in the quiz format
  5. Users may answer the question, and uncover whether or not they have answered correctly.
So, with this logical definition, we have already found a need for three types of thing: Question, Answer and Level (which is the point at in the question will appear). 


Lets start with the simplest of these, the Level model. Rails provides a command which will create a model, along with the other files we need for it to work. We need to define what attributes an instance of the Level class will have. It'll have a name (for instance, "£100") and a level number (which will define it's order in the format). So, lets try using `rails g` (short for generate) to create this:

  rails g model Level name:string level:integer

This tells us not only the attributes of a level, but what type of data each one will contain, it says that the name will be a string, which is computer-speak for some text and that level will be an integer, which is maths-speak for a whole number.

The result will look a little something like this:


Models in Ruby on Rails are a class which handles what is called object-relational mapping, maps a table of data in the database to the class, and each row in that table to an instance of the model. This means that there has to be a table in the database, to store attributes for instances of the model. The fisrt file mentioned in the output of the `rails g` action, above, is a migration. This is a rails definition of a change in the database. The content of the migration looks like this...


We can run any migrations which haven't yet been run with this command:

  rake db:migrate

This will add the 'levels' table to the database we created at the start of this tutorial. It looks like this:


More importantly, it creates the model itself, stored in the file at app/models/level.rb, currently, it's got almost nothing in it:


What it does do, is define a class called Level, the next part, ActiveRecord::Base is the part of Ruby on Rails which handles the above-mentioned ojbect-relational mapping. Since this is our first model, lets try it out with the rails console, which we can open with
  rails console

or, more concisely:

  rails c

Once this is opened, we can use our application directly using lines of Ruby code. We'll start by making a new instance of Level (with `Level.new`) and assigning it to a variable named `level`.


You'll notice that we have a run-down of the attributes of our new level, they are all, so far, nil (which means nothing). But you may also notice that it has an id (which is a primary key, used to uniquely identify a specific level), and created_at and updated_at columns. The last two are defaults of Rails models, created_at is set when you first save, and updated_at is set whenever you save it.

First things first, however, lets feed the attributes we want to Level.new, to make a level with the attributes we want:


Oops, I've accidentally named it $100, but I meant it to be £100. I'll use the instance of Level, but change it's name attribute to £100...


You'll notice that `level.name` means the name attribute of that object, and that `level.name = ` defines that attribute. But when we close the terminal, this instance of the Level class will be lost, unless, of course, we save it to the database:


So, level.save ran an SQL statement (it shows this for people who are familiar with SQL, the standard language for interacting with databases, but you don't need to worry about it for now), and then returned 'true' meaning it's saved.

Now when we look at the level object, we see that it's had an id assigned, as well as the time it was created and updated.

As I mentioned above, id is used to find this specific level again, even if we close the console and open it again. So lets try that:


So we've used a class method, find, to find an instance of Level, and we've passed it an argument (which is a specific piece of information telling a method how to do what it does) with the id of the level we want.

Lets try this with a few new levels:


Here I've used Level.create to both make a new instance of Level and save it to the database in one action, with it I've created 4 new instance of Level, in the database.

But I won't always know the id of everything instance of all my models, so how do I find them again? Here are some useful methods to call on your models...

  • Level.find - find a n instance of Level by it's id
  • Level.first - returns the first instance found in the database
  • Level.all - returns all of the instances of that model
  • Level.where - You can pass this conditions to find one or more Levels
First of all, let's try find, first and all:


These are useful for finding out what data is in your database for a given model. But lets think of something more specific. I've just answered a question at level 1, and I want to get level 2. The id of this may not always be 2, so I need to search by the level attribute:



That's found it (although that's actually a collection of objects, with one in it, to get the object itself you should use

  Level.where(:level => 2).first

Hopefully this has been a useful starter in how to use Models in Ruby on Rails, there's still a lot to learn here, validations to make sure the data saved to your database is suitable, relationships between instances of different models, more advanced querying, and writing your application logic as methods for instances of a class. But all that is other blog posts, for other days.

Yes, we haven't got very far, but Rails is big, and to understand it, you need to take baby steps. Suffice to say we will eventually be able to produce a quiz with this.

For now, I hope this is helpful. As ever feel free to contact me (@MarmiteJunction) and ask about anything that doesn't make sense to you. I may not be explaining all of this very well.

Who want's to be a Rails Coder? (Part 1) - Brief Introduction to Rails

So, I've not blogged for some time. I've written enough to provide a fair grounding in Pure Data, but so far I've said nothing about the thing I actually do, which earns my money and occupies the majority of my waking hours, Ruby on Rails. Partly because it is a very large framework, it took me years to become proficient (from being unable to code at all) and quite often opinion is divided on the correct way to use it.

Another reason to avoid writing about Rails is that you need to think of a project to display both the specifics of working with Rails and the principals of application design. There's no shortages of tutorials which show you how to write a very basic blog application.

So I've started on this series because I happened to be watching a popular quiz show from my youth (which I've decided not to name here, but which will, no doubt, become clear) and realised that implementing it as a Web Application would serve very well as a demonstration of how to think about creating an application, and to go about implementing an idea with software.

It's not a very ordinary use of Ruby on Rails, to create a quiz. So this probably isn't the best choice as a first-time piece of programming, or beginning look at web development. I'm going to talk about what interests me, the thinking behind development, and try to introduce parts of Rails in-depth at the same time. If you want to try from scratch, go and find one of those tutorials on how to make a blog.

This is aimed at people who have some knowledge of using the command line and some knowledge of programming. But if you don't you may well be able to follow. Hopefully if you already have some knowledge of Ruby on Rails this will contain some insight into the individual parts of Rails and how to think objectively about the work we do with it.

Fistly, I'm working here with Rails 4.1 and Ruby 2.1.1, but most of what I'm talking about could be written with earlier, or later versions. A lot of working as a developer involves learning to think about the problem ahead of you and learning reusable 'patterns' for solving them.

Start by installing RVM, which is a version manager and allows you to work with specific versions of Ruby and it's related libraries, once it's installed you can get ruby 2.1.1. Open a command line terminal and install ruby 2.1.1 like so:

  rvm install 2.1.1
  rvm --default use 2.1.1

From this point anything you do with ruby-related applications (ruby, gem, rails etc.) will be using version 2.1.1 and also any Ruby libraries (aptly named gems) will be installed in that specific context. So when you want to try a new version, you still have this version of Ruby intact to work with. Lets start by installing Rails, the most commonly used web development framework for Ruby.

  gem install rails --version=4.1.0

Let's start by generating a rails app, use the command `rails new` and follow it with the name of your new application.

  rails new who_wants_rails

All being well, you'll see a long list of files, which have been created in a folder named who_wants_rails, as a check, change to the folder and check it's content. It'll look a little like this:


Now, web applications mostly act within a spefic 'scope', meaning every thing it does starts when a browser makes a request (most simply, by loading a website), and is then removed from the computers memory. For anything to persist longer than this the data needs to be stored somewhere. In Rails this is usually done with a database, as the name suggests that's simply a place to store data. For this glancing look we're going to use sqlite, which is a default for Rails, and works for development, although we will need to look at swapping it out for another database later.

The config/ folder houses a configuration file named database.yml, this names which piece of database software we're using, and where it will be stored. For sqlite, it also defines which file it will be saved into within your Rails app's db/ folder.

The contents of config/database.yml looks like this:


Don't worry, there's no need to change this file just yet. But you will need to create the database. Rails provides a convenient script (run via Ruby's `rake` application, and known as a rake task) for creating the database defined in your confg/database.yml file:

  rake db:create

Now we need to look at writing some code, Ruby on Rails implements a pattern called Model, View, Controller (or MVC), which means that the majority of the work you do with it belong in one of these types of file:
  • Model - the objects you are manipulating with your application, data from a database is retrieved by a model, saved to the database, and can be modified in the meantime. Most of the actual logic of your application should be written here.
  • View - the point at which your application interacts with the user. It's a web application so it generates HTML (the markup language which makes up websites) which displays content derived from your database.
  • Controller - these usually map one-to-one with your models, and handles input from a browser and handles which views are displayed and which actions from your model take place. 
If you look at the app/ folder you will see folders to house these three types of file. In my next tutorial I intend to look at creating our first model and tell you a little more about it.

Wednesday, 5 February 2014

Making music with Ruby and Beep (Linux only)

I've not posted in a long time, I know. This is mostly because I've explained most of what I know about Pure Data which can be explained in a blog post without relying 100% on prior knowledge. So this is a little about Ruby, and a little about Linux. A nice, short topic which can get you writing a little bit of code in a short time. 

Firstly, you will need two applications, Ruby and Beep, these are easily installed with a simple command. On Ubuntu distributions you can use apt-get, like so. 


If you are using a Redhat variation of Linux, such as CentOS you might need to use yum instead. 

Now, beep is an application for controlling the internal speaker in most computers (towers), although for laptops it will usually work through the sound card, with the in-built speakers. So, to use it in it's simplest form, use this command:


Unsurprisingly, your computer will make a beeping sound. It's not very interesting, or very musical, but it beeps. 

There are two problems you may well run into at this stage, firstly, it might not beep at all. If this is the case, I suggest you check out this forum topic, for some linux jiggery pokery on fixing that issue. You may also find that it comes through VERY LOUDLY, if this happens, try alsamixer, which usually has a volume level entitled beep, which you can navigate to and lower using the arrow keys.

Back to beep, a single beep, on it's own, or a few one after another, still don't really sound musical, but we can take a little more control. As with most command line applications, you can bring up a help page by using the -h command, like so.


 Okay, so this may be a little baffling if you're not used to using the command line, but basically there's a list of flags, preceded by a hyphen(-), which you can add to the command while calling beep, to change change the result in one way or another. Some of these would be followed by an attribute (after the flag but within the same brackets) to control this more directly. 

Now, the first two options on a beep are frequency, and length. These two options are, really, the minimum you need to start producing musical sequences. The frequency is in Herz (as I've covered before, this means it's roughly between 20 and 20,000 and increases the pitch by an octave every time it is doubled), so we can try a simple sequence by typing these commands one after another...



Now, you'll notice a couple of things here. Firstly, those three tones sound quite nice in sequence. More importantly, however, you'll notice that you can't type quickly enough to hear them as any kind of tune. Clearly this is not something you can easily control directly from the command line. 

But, again as I've mentioned before, the beauty of programming computers is that when you don't want to (or aren't able to) keep controlling a computer directly, you can give it some rules and let the computer follow these. So, the first thing we need to do is use a programming language capable of running terminal commands for us. I'm using my main programming language, Ruby. 

We'll use irb (or instant ruby) for now, which just runs ruby commands line-by-line, instead of reading through a file.


You'll notice the start of the line has changed, but you're still being prompted to type. 

We're going to use a standard Ruby method, system, with a single argument which is a string of text. So we'll make our argument, that last beep command, for now.


This returned true, which basically says, yes, this worked. You'll also hear the beep. You may also notice that you typed a longer, slightly more complicated line for exactly the same result. This part is just a primer, however, to show you ruby running the terminal command. Next we're going to use a single variable, which we'll substitute for the frequency number. 

First let's take a step back, a variable is a single piece of named information within Ruby (and most other programming languages). You can think of it a little bit like doing algebra at school, if we set a variable called f (say, f = 440) we can then do some actions on f, which would be the same as doing those on the original number. For instance...


You can see that we've done some maths with f, the results are worked out for us, and if we define f again as something different, the answers to the other lines would change. Although in this case, f doesn't change unless we use f = something again. 

We can define f as the result of some of this maths, like so...


You'll see that this time f has changed with each line. So the result of the each bit of maths is based on the one before. 

For these maths functions, we can usually shortcut this by putting the = and the operator together (like *= to multiply and set the variable...


 Notice how the results are the same as the method I used before. 

So what has this got to do with making music with beep? Well, once we have our variable we can do a string substitution to put it into the beep command, then send it to the terminal with system. 

So if we change f, and then run the beep command again, the pitch will change. 

String substitutions in Ruby can be done on double quotes ("") and are a hash followed by curly brackets. That might not make sense but they look like this: "Solid string: #{variable}" For instance: 


What this substitution (#{}) does is evaluate the ruby code within, and then put it in that place in the string, so we could put one of our *= commands in there, so f would be multiplied by the same figure whenever we run that line...


To help you do this, in irb (and in the terminal) you can re-run lines by pressing up until you see the previous line you want to run, then pressing enter. 

This may look the same, but you'll hear that the pitch has increased by an octave each time and see at the end that our variable f has been doubled four times. 

So, we've established that we can make the frequency change by running the same line of code a few times over, hearing the beep each time. The next step is to run that line a few times over without having to run each one manually. For this we're going to use a ruby times loop, this does the thing which is in curly brackets ({}) after it a given number of times. like:

4.times {system("beep")}

Lets try that last sequence, but in just 2 lines of Ruby:


This will sound the same, but a lot more fluent than the previous example, the four beeps sounding one after another. 

When using a times loop, we can also set a variable which comes from times to use inside the loop, which is defined within pipe characters (|) at the start of the loop. For instance:


This uses the Ruby puts method (which simply puts it's argument down in the terminal) to show you what i is each time this loop is run, you can clearly see it's the numbers from 0 to 7. It's basically the number of times that loop has been run so far. 

So if we use this alongside our f variable, we listen to the pitch changing based on algorithm which changes in the same way each time, based on how many times the loop has been run. 

Lets apply some pure data knowledge here, way back in June last year in Algorithms of the Street: Part 3 - Additive Synthesis I told you that when you multiply a frequency by whole numbers, you get what is known as the harmonic series, which is a set of frequencies which go together, often they are present together when you hear musical notes, and strings tuned to the first of these will vibrate in sympathy when a tone is played at one of the other frequencies in the list. 

So frequencies which are multiples of the same note go together. 

So lets try that times loop, but multiplying f by i each time. I'm going to start a little lower down and run this line 8 times (although because i starts at 0, I'm putting a little bit of ruby in brackets to use i + 1, so we actually get the numbers 1 to 8):


You'll now hear beep running through the harmonic series, from that initial frequency of 220 hertz.

Let's try a different approach, let's use a method called rand, which generates a random number. When we give it an argument, it will generate a random number between 0 and 1 less than that number (the same as pure data's random object). 

 
This time you'll hear a sequence of 8 beeps at random pitches, and if you run it again you'll hear different random sequence. 

Incidentally, you could substitute 8.times with loop, which is an infinite loop in Ruby (followed by the curly brackets in the same way). However, you will have to press ctrl + c to stop this running. 

Lets try combining the last two approaches, a loop which randomly chooses a value for f, then runs up the first 8 partials in it's harmonic series.

Sounds complicated? Well it is, and if you do any coding, you'll wind up doing some complicated things, that's just the way it is. So let's start by making it simpler. Firstly, this shouldn't be done on just one line. And because we're relying on a few lines, it's probably best to use a ruby file (a text file who's name ends in .rb). 

Also, because we are working across multiple lines we'll replace those surrounding curly brackets with the words do to start and end to end. The convention to make these more readable is to indent the lines between these two words by two spaces, so you can scan down the left hand side of the file and see that those which are indented are inside that block. 

So, in your favourite text editor (but not word processor, just a simple text editor. I'm using vim) put this in a file and save it as beeps.rb in your home directory. 

(notice that I've replaced system with back-ticks(`), which do the same thing, only they wait for the command to finish, if you use system here you might get a shock when you try to stop the ruby file from running)



I've added a -l flag of 100 milliseconds to make this slightly faster. So you see the { and } have been replaced with do and end and the lines between are indented, so you can scan down from the do line to the end line without any interruption. You don't have to understand this at first, but please do it. This makes code readable! 

You can now run this in the terminal, in your home folder, with this command:

ruby beeps.rb

press ctrl and c to stop this script

You'll hear the same kind of random melody. 

Now we're going to put a times block inside our loop block. Again, replacing curly brackets with do and end, and the line within will be indented a further 2 spaces. 

I'm also going to add a puts line so you can see the frequency as the script runs.


Now when you run ruby beeps.rb, you'll hear a random note, beeps running up it's harmonic series, then a new random note and it's harmonic series, and so on. 

And that is some algorithmic music made in Ruby and Beep, no pure data at all this time. 

I realise it will be very heavy for people who haven't written any code before, but it's quite rewarding. Remember that code is, above all else, very logical, you can often work out problems as you are writing it with a few rules:

  • Finish everything you start
  • Read error messages carefully, they may be talking about something you're not currently thinking about.
  • If stuck, ask google
  • If stuck, ask someone who knows about it. 
That last rule is important, the internet is full of well-meaning techies who will often help beginners with a little leg-up in the world of code. I'm amongst them (feel free to grab me on twitter, @MarmiteJunction). 

I hope you found this little tutorial interesting, informative, or even fun. By all means tell me what parts of it make no sense to you. 

God bless and have fun coding

- Andrew F

Monday, 14 October 2013

USB controllers in PD

Todays blog post is about a deceptively simple subject which can instantly expand your capabilities in Pure Data, Human Interface Devices or HID.

This was one of the things to excite me about Pd usage in the early days because it introduces what could be termed the 'alchemy' of  computer programming. Simply termed, we can turn a kind of thing with a specific purpose, such as a joypad, into the same thing, with a very different purpose, a musical instrument.

So today I'm working with this rather simple setup:



Now, that's a nice, cheap, third-party USB joypad, I bought for £15, but if you fish around online you can find cheaper, still. Now, almost all game controllers for computers use a set of standards known as HID (Human Interface Device). Which strangely enough is also the name of the object which we can use to get this information into Pd.

Try this patch (remember to plug in a USB controller before opening Pd):

Step 1: Finding your HID device



This is a simple patch to start with, because hid is quite complicated there's a few different messages you can feed into the top. The message 'print' when you haven't told it which device to listen to yet will print out a list of available hid devices in your Pd terminal, looking something like this...


Now, we can see a list of devices, and that hte USB joystick (curiously named MY-POWER when the name ORB is printed on the pad itself) is Device 12. You may also see keyboards, mice, graphics pads etc on this list.

Note that next time you plug in your joypad (or other kind of controller) it may not have the same device number, so you might have to go through this process again when you open a saved patch.

The next step is to open this device and see what information Pd can read from it...

Step 2: Look at the device, having found it



Now, clicking on 'open 12' will tell hid to read the device we found in the previous step, and then the purpose of 'print' has changed. Instead of listing devices Pd can see, it will tell you what parameters it can read from that device. So clicking 'print' will result in a readout like this one...


Now, you can see that we have messages which Pd can get from the controller, 12 btn messages (which will send 1 when a button is pushed, and 0 when it is released) and 7 absolute axes, which are sliding-scale type messages. If, having opened a hid device, we feed hid a 1 (usually from a toggle, but you could feed it in from a message, too) it will start polling (basically, listening to) these events from the controller.

Let's try setting this to poll, then feeding the results out to the terminal via an object called print (not to be confused with print from the message, mentioned above.

Step 3: have a look at what's available 



All we've done here is pipe the output of hid into print, which puts everything it sees onto the terminal, so when I push some buttons on my controller we see something a little bit like this...


Now, this is just a list of messages, but we can see that there's a certain structure there. Firstly there's three things separated by a space, which Pd reads as a list. Firstly the contents of the TYPE column we saw above, then the name of that parameter, then a value of 0 or 1.

There's also a miscellaneous scan parameter, which seems to identify the button being used. I don't really know what this is for, but I know we can safely ignore it.

You'll also notice that every message (1 for on, 0 for off) is sent twice. This is a problem known as 'debouncing' which some controllers are prone to. There are ways around this, but for everything we're going to do here, it won't matter.

The next thing we need to know in order to make this information useful is how to just get the last part of the list, for just one button. For this we're going to use route. All route does is list (without that first item), and everything else out of it's right-hand outlet.

If route has more than one argument, it will gain additional outlets, if the first item in an incoming list matches the first argument, it'll be output via the first outlet. The second argument, the second outlet, and so on...

Step 4: Use route to focus on the controls you're interested in.



So all I've done here is route the lists starting with 'key' to the second route, where it takes the messages btn_0, btn_1, btn_2 and btn_3 and outputs them to four toggles. When I took this screenshot I was holding one of those buttons, so you can see that one toggle is selected.

And that's basically all you need to know about getting (or Mapping) inputs from a hid device into Pd. But we don't want to stop there, what about those joysticks? and the d-pad? Well, with the same process we can route their inputs into our patch, too.

Step 5: A few more mappings...



So there you have it, both of the joysticks output two axes, and moving them around I can easily learn that they range from 0 (at the top, or far left of it's range of motion) to 255 (at the bottom, or far right) and the resting position has both at 128.

The d-pad (direction control on the left hand side of the pad) also outputs two axes of motion, although these are only ever -1 (up and left), 0 (resting) or 1 (down and right).

In the snapshot above I was holding one stick to the bottom-right and also the d-pad.

I think it's time for a little alchemy, let's hide the patch so far in a sub-patch (see Putting Pure Data in a Box) and use some of these controls to make music.

Step 6: Mapping controllers to a simple synth




Now there's a few things here from previous patches, firstly the object 'pd controller' contains the hid patch we've been working on, only I've added a few sends to it (named b1 for button 1 etc. lx for the left stick's x axis etc.). As you can see here:


The patch outside it contains a few things from previous tutorials, an array with 15 numbers (representing two octaves of the major scale), a maxlib/scale which converts the 0 to 255 we have to the 0 to 15 we want. This goes through i to make sure it's an integer (whole number) and to tabread, which reads a number from the array, scale. we add 50 then smooth out the edges with a line~. This is converted to a frequency with mtof~ and feeds an oscillator.

I've then brought in one of my buttons (b1) to turn the volume on or off for the oscillator, multiplied it down a little and fed it to the sound card with dac~

Once again I've described each part of a Pd chain to tell you it's function, but if you haven't read all my other blog posts, this basically turns the left-right motion of the left joystick into a pitch control, in a given scale, and one of our buttons into an on-off switch. This is a simple musical instrument. With a little practise you can play a tune on this.

Now, just for fun, I'm going to use the up-down motion as a volume control and lengthen the envelope on the button control...


So the left stick is taking on the duties of a bit more expression. This also opens the patch up to something of a money shot. Why not have a synth on each of these 4 buttons, an octave apart? One of the strengths of Pd is to quickly duplicate and modify code, so let's try it...

Step 7: A modified joypad quartet



Now, I've done a few things here. Firstly I've moved that volume control to the top of the patch, and sent it to the bottom part of the patch with an audio send (s~ vol), then I've duplicated the bottom part of my patch 4 times. I added 12 to each successive midi note (making it an octave higher), then I used a different button send to turn each one on and off. Hey presto, I can play at a different octave by pressing each of the four buttons.

I also changed all the osc~ objects to phasor~ for a different tone, and lowered the initial + to make the lowest tone a bit lower.

Now is probably the time for a little demo, but first, I should warn of some of the pitfalls of working with cheap and cheerful gaming controllers.

Firstly, you'll find the range of motion on joypads is much narrower than you think. That is, the range which isn't the extreme top or bottom end, or dead centre only takes up a small amount of the space you can move the joystick.

Also, you'll probably trip up over the fact that the top of a stick's motion is 0, and not the bottom.


Well, that range of motion issue has made it a little limited, and it is a very simple instrument, but here it is. My custom joypad instrument and a little exploration of the sounds it's making...

video


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:

video


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'.

video


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'

video