makemachine.utils

I’ve consolidated a handful of helpful utility functions into a single library. Each utility is it’s own class and is used as a package function. I was introduced to the concept of package functions when I started using Eaze by Philip Elsass. With package functions you don’t need to instantiate an instance of a class to use it. You just import the class and use it’s name as a method call. For more details on when and why to use a package function check out this blog post by Eric Feminella.

Source Code @ GitHub

Currently there are about 20 utilities. I’ll keep adding to it as I find/write useful helper methods. If you have any utility methods that you think would make for a good addition to this library, feel free to paste into the comments or send them in an e-mail.

Below is an example of the introspect utility. Using flash.utils.describeType, this utility zips through all of the properties and the value of the properties of an object and prints them to the console in a neat and orderly fashion.

Here is what the introspect class looks like minus the actual logic:

package makemachine.utils
{
	import flash.utils.describeType;
	
	/**
	 * Prints all read and read-write properties of an object to console
	 */
	public function introspect( caller:Object, obj:Object ):void
	{
		// -- logic for introspect util goes here
	}
}

Here is an example using a simple Person class:

// -- Person class
package
{
	public class Person
	{
		public var name:String;
		public var age:int;
		public var occupation:String;
		
		protected var _id:int;
		
		public function Person( personId:int )
		{
			_id = personId;
		}
		
		public function get id():int { return _id; }
		
		public function toString():String { return 'Person'; }
	}
}

// -- Test class
package
{
	import makemachine.utils.introspect;
	
	public class Test
	{
		public function Test()
		{
			var person:Person = new Person( 12345 );
			person.name = 'Jeremy'
			person.age = 29;
			person.occupation = 'Programmer';
			
                         // -- prints the properties & values of the object
                         // -- does not instantiate the class
                        introspect( this, person );
		}
		
		public function toString():String { return 'Test'; }
	}
}

// -- call to introspect prints the following to the console
print[ Test: instrospect ] :: Person
print[ Test ] :: Person.id = 12345
print[ Test ] :: Person.name = Jeremy
print[ Test ] :: Person.occupation = Programmer
print[ Test ] :: Person.age = 29

I use this introspect utility all of the time. I’ve found it most useful when building model classes from dynamic data sources. Other methods in the lib include string manipulators, array sorting and various mathematical operations.

Posted in Actionscript | Tagged , , , , , , , , , , , | 3 Comments

Hello Git

Up until now I’ve been using Google Code w/ Subversion. I was introduced to Git a few weeks back and have decided to switch to using it for makemachine projects. I really like the concept of maintaining an entire clone of a repository locally and only pushing code when needed.

The social element to GitHub is also quite cool. Google Code does very little for connecting coders with similar interests. I’ve set up an account with GitHub and will be posting new work very soon.

Hello social coding…
http://github.com/makemachine/

Posted in General | Tagged , , | Leave a comment

Welcome Back to the Machine

Wow, what an intense few weeks I’ve had. I landed a contract to build an interactive museum exhibit with a studio in New York called Potion Design. I worked on the project with my good friend Kieran from Octothorp. We worked fast and furious and as a result I had zero minutes for experiments or writing for makemachine. However, I’m really happy with the project. It was a great experience and I even got to take a trip up to New York for the installation. I’ll be writing more about the project on my portfolio site in the near future.

Next week I’m saying goodbye to the countryside of Maryland and heading up to Montreal for three weeks of exploring. After that it is back to Germany for a while! Yes, lots of adventures are in my future.

As for makemachine, there is much in the channel. Before I started working on the contract job, I finished a prototype for a new set of user interface components. In the past few days I have been working on the API design and finalizing a few approaches. You should begin to see a more posts regarding this quite soon.

Of course more audio experiments are also in the works. There is a good chance that I will soon be looking at implementing some of the the things I have learned in the past six months in other languages too. I’m really interested in exploring the dynamic audio capabilities of the Cinder framework.

Fall is here, it is a great time to hunker down and learn.

Posted in General | 2 Comments

Calculating Beats Per Minute

In this article we’ll take a look at how to create a basic b.p.m. calculator based on sample rate and tempo. This information could be used as the foundation for a step sequencer or other b.p.m. based music arranger. A basic understanding of digital audio would be very helpful to understanding the following, but I’ll attempt to make it as painless as possible.

The first concept to understand is how digital audio is read from memory. Very simply, you can imagine a digital audio signal as a series of numbers, ones and zeros actually. Over time that series is read by a device and ultimately sent to your speakers as audible sound. There is a time interval at which the data is read. This is called the sample rate. The sample rate determines how many samples of data are read in a given time frame. An audio sample is not a one or a zero though. Depending on the bit-rate of the audio, the sample size changes. For instance in 16-bit audio, one sample is sixteen ones and zeroes. In this example we will be working with 16-bit audio at a sampling rate of 44,100 samples per second. To put it another way, every second of audio we are working with is made up of 44,100 samples. I’m skimming over some otherwise very interesting topics here, so we can quickly get to how it applies to the topic of calculating beats per minute.

For this topic we need not concern ourselves with the intricate details of bits and bytes and instead, we’ll focus on the concept of sample rates as applied to b.p.m. What we are most interested in, is where notes begin in time. This is what creates the sense of pulse and rhythm.

The above graphic represents the concept of calculating the space between notes so as to determine where notes begin. For the sake of this example lets assume that a note is one pulse of a bass drum ( much nicer than the click of a metronome ). Because we know that 44.1k samples occur in one second we can then deduce the the starting place for each note at a given tempo. For example lets say that the b.p.m. or our audio is one beat per second or 60 b.p.m. That means that a whole note would occur once every ( 44.1k * 4 ) samples and a quarter note would occur once every 44,100 samples.

Lets bump up the b.p.m. for the rest of this example to 90 b.p.m. and determine the interval at which to begin a quarter note. To do that we use a little math. If we multiply the sample rate by 60 ( as in 60 seconds in a minute, we get the number of samples in a minute ).

Samples per minute
44100 * 60 = 2646000

Next, we can divide the samples per minute by the b,p.m. This results in the interval at which a quarter note begins at the given b.p.m.

Sample interval for 90 b.p.m
SPM = samples per minute
T  = sample interval
SPM / BPM = T 
( 44100 * 60 ) / 90 = 29400

In the above example we determine that the sample interval for a 90 b.p.m. pulse is 29400 samples. This seems like a good time to start looking at how this might be accomplished through code. Here is some pseudo code that demonstrates the idea.

int position = 0; // -- this is an index that keeps track of where we are in time, incremented for every sample processed
int buffersize = 8192; // -- how many samples to create every time process() is called
int beat = 0;
int bpm = 90;
int samplerate = 44100;
int interval = ( samplerate * 60 ) / bpm;
function process()
{
     for( i = 0; i < buffersize; i++ )
     {
          // -- if the remainder of the position by the interval is 0, we are at a sample where a quarter note begins
          if( position % interval == 0 ) {
               // -- NEW NOTE STARTS HERE!
               beat++;
          }
          position++;
     }
}

The above pseudo code demonstrates how to go about finding the position at which quarter notes begin. This works well enough, but what if we'd like to add notes other than quarter notes. This can be accomplished by using a very similar technique to the previous example. This time we will make the interval shorter by dividing the tempo by as many non-quater notes as we want. If our b.p.m. is 120 and we want 16th notes we can multiple the tempo by 16 and decrease the interval.

Sample interval for 90 b.p.m with 16th notes
SPM = samples per minute
T  = sample interval
ST = steps ( 8th/16th/32nd notes )
SPM / ( BPM * ST ) = T 
( 44100 * 60 ) / ( 90 * 16 ) = 1838 ( rounded up )

Taking the modulus of ST ( steps ) by the position by interval will produce a value representing the current beat. Again, here is a snippet of pseudo code representing this concept.

int position = 0; // -- this is an index that keeps track of where we are in time, incremented for every sample processed
int buffersize = 0; // -- how many samples to create every time process() is called
int beat = 0;
int bpm = 90;
int samplerate = 44100;
int steps = 16; // -- the number of sub-notes or steps in our sequence
int interval = ( samplerate * 60 ) / ( bpm * steps ) // -- decreasing the step interval by multiplying by steps
int currentStep = -1;
function process()
{
     for( i = 0; i < buffersize; i++ )
     {
          // -- this time we use the modulus of the steps by position by interval
          int newStep = ( position / interval ) % steps
          if( newStep != currentStep ) {
               // -- NEW NOTE STARTS HERE!
               currentStep = newStep;
          }
          position++;
     }
}

The above example now allows us to create a pulse with as many sub-quarter notes as we want. The next step would be to take measures and time signatures into account. This post is rather lengthy. I'll save measures and time signatures for the next post. In which, I'll include an actual code implementation. Thanks to Balazs from 28-inch for inspiring this post.. Also, I wrote a simple metronome that demonstrates some of these concepts back in June. It could make a nice next step in understanding b.p.m. calculations.

Continued Reading:

Posted in Audio | Tagged , , , | 10 Comments