analoq

Not quite analog.

Late to the party,  but I’ve recently become aware of Miller Puckette’s The Theory and Technique of Electronic Music thanks to the Volterock blog.  Taking a break from The Audio Programming Book, I decided to give the first chapter a try.  To my bemused joy there are exercises at the end of each chapter, however the answers are not available in the online version I’m reading  (I think I have to buy the book for that).  So I decided to post my answers for the first chapter here and hopefully somebody will point out any mistakes, especially for #5.

1) A sinusoid has initial phase φ = 0 and angular frequency ω = π/10. What is its period in samples? What is the phase at sample number n = 10?

Well, the sinusoid equation with these properties is going look like:

The period of a sinusoid is 2π so at what n will the phase equal that?

And the phase p at sample n=10 would simply be:

2) Two sinusoids have periods of 20 and 30 samples, respectively.  What is the period of the sum of the two?

This would just be the the LCM of 20 and 30, right?  60 samples.

3) If 0 dB corresponds to an amplitude of 1, how many dB corresponds to amplitudes of 1.5, 2.3, and 5?

Amplitude to decibels equation with numbers plugged in…

4) Two uncorrelated signals of RMS amplitude 3 and 4 are added; what’s the RMS amplitude of the sum?

Uncorrelated signal equation and RMS amplitudes plugged in…

5) How many uncorrelated signals, all of equal amplitude, would you have to add to get a signal that is 9 dB greater in amplitude?
First let’s see what the amplification multiplier of 9 dB is:

The formula for RMS amplitude of two superimposed uncorrelated signals of equal amplitude can be simplified as follows:


So for 2 uncorrelated signals of equal amplitude the amplification multiplier is sqrt(2).  Here’s where I make a leap of faith:  For any number of signals k, the amplification multiplier will be sqrt(k).  So I just need to find when sqrt(k) is equal to 10^(9/20)…


… is this even remotely correct?

6)  What is the angular frequency of middle C at 44100 samples per second?

Frequency f is ~261.626 for middle C, sample rate R is 44,100 and we’re looking for the angular frequency ω (radians per sample).

 

7) Two sinusoids play at Middle C (MIDI 60) and the neighboring C sharp (MIDI 61).  What is the difference, in Hertz, between their frequencies?

Use the formula to find the frequency of MIDI note m=60 and m=61 and subtract them…

8)  How many cents is the interval between the seventh and the eighth harmonic of a periodic signal?

This was tricky but I think I got it.  The ratio between the harmonic is 8:7.  An equal temperament half-step (100 cents) is the ratio of the twelfth root of two.  So how many half-steps do I need to make 8/7?

9) If an audio signal x[n], n = 0, … , N – 1 has peak amplitude 1, what is the minimum possible RMS amplitude?  What is the maximum possible?

The book gave this one away but I went through it in my head:  If a signal has a peak amplitude of 1 there is at least 1 sample equal to ±1 and at most N samples equal to ±1…

And there you go… yes this took way too much time to put together in LaTeX and blog it.  If I do anything like this again expect only 1-3 exercises per post :)

0

After visualizing music with animations based on MIDI sequences, I began to think about non-MIDI formats:  Tracker modules and video game chip formats.

Unlike MIDI files, these formats contain not only musical events, but information about the sonic properties as well.  They may have sample data and synthesis properties like envelopes, oscillator and filter settings, etc. which can be measured predictably. Hence there exists a potential for more detailed visualization.  Some demoscene demos have used this information for effect… I’d like to do the same.

My first experiment was real-time visualization for tracker modules, which I leveraged libmikmod to do.  It works like this:  A bar is on the screen for each channel of the module, its X position determined by the channel number, its Y position determined by the pitch the same is playing at, its color determined by what sample is playing and its brightness determined by amplitude.  Even with those few parameters and simple setup I got interesting results:

YouTube Preview Image

Next up I wrote a similar program that would record these parameters.  It would sample the pitch and amplitude for each channel and compute the average for each 24th of a second and record that to a file.  I took this data into Blender to animate glowing spheres at 24fps.  This is the result:

YouTube Preview Image

The module I used was created with a single sine sample, so the colors used in the animation are solely aesthetic.  The spheres’ position on a polar coordinate is determined by the channel number and pitch, while their luminosity is determined by amplitude.  Slightly-nauseating camera motions were manually animated.

Off to a good start, I think.

3

say what?

by analoq

Long time no blog!  And not much to offer at the moment, but upon checking my linkbacks I noticed someone has been inspired by my 3D Piano Roll animation:

“All of Me” MIDI 3D created by Dan Price is a marvel.  They used the code I put up here as a starting point and expanded upon it in ways I couldn’t have imagined.  Please check it out.

In far less interesting news, I am easily amused by YouTube’s auto-captions for my Sampler demonstration. I suppose the combination of music terminology, dodgy speech recognition and my poor diction do not produce ideal results:

Input Output
sustain pedal sustain panel
waveform overview way formal review
vibrato the bronco
modulations March elections
portamento poor two men too
soundfont player sound on player
piano sample Indiana in a sample
piano sample pillow sample
mapping acting
octave up to
loop point look point
tremolo trouble
“I’ll set the parameters on that” of police at the premise on that
“we have a pitch envelope” we have hit a new low
*sound of piano key hit repeatedly* death

We indeed have hit a new low.

1

Sampler

by analoq

When I developed my MIDI sequencer I leveraged the default General MIDI synth in order to keep things simple.  Later I began integrating AudioUnits but stopped short and remembered my goals:  To make my own music software, i.e. not rely on 3rd party software where possible.  The synths I’d developed don’t cover all the sounds I need, which means I had to tackle… the sampler.

Project VII:  analoq.samplr

YouTube Preview Image

I did not demonstrate the filter or the sensitivity adjustment for velocity, but those are pretty straight-forward.  The video covers the basics, but here are the details:

  • Plug-in architecture: I leveraged Cocoa’s loadable bundles to implement a plug-in architecture for my instruments. The code for the sampler and sequencer are separate at both compile-time and runtime.
  • Formats: This started out as a SoundFont player but I kept the code so it can import SF2 files with some level of accuracy.  I also wrote my own WAV and AIFF file parsers.  If you include MIDI, that’s four file formats under my belt now and I’ve mostly reverse engineered Apple Loops.
  • Marker Import: If you load an AIFF file with markers in it, it’ll prompt you to assign them to the Start, End, Loop Start or Loop End points.  Really handy!
  • Logarithmic Slider Response: If you create a knob for say, a filter cutoff, and have it respond 100-10,00Hz in a linear fashion, then half the range of that knob will only cover the last octave i.e. 5,000-10,00Hz.  That makes it kinda hard to fine-tune the lower octaves!  This is the first project where I actually got the knobs to have an even logarithmic response where appropriate.
  • Linear Interpolation: In the very beginning of this project I noticed samples sounded quite bad when resampled at slower rates so I wrote code to smooth out the transition between the sample points.  Turns out that technique is linear interpolation, duh!

This project turned out to be a lot of work but it was a much needed learning experience.  2009 has been quite an enlightening year!

So I’d like to import Apple Loops in a future project.  One problem:  the format specification is undocumented.  It has been reverse engineered before but I haven’t come across anyone’s findings so I figured I’d give it a shot myself…

AIFF Primer

Apple Loops are AIFF sound files with additional data chunks for transients, categorisation, etc.  ”Chunks” are the building blocks of IFF formatted files, they start with a four-byte identifier (FourCC) then an unsigned 32-bit number representing the data length and finally the data itself afterwards.

Standard AIFF chunks include the Common “COMM” chunk which details the sample rate, bit depth, channels etc. and the Sound Data “SSND” chunk which contains the raw PCM data.

PDF: Complete AIFF specifications

Apple Loop Chunk: basc

This is an 84 byte chunk with the ID “basc” that consists of information about the loop’s time signature, key, etc.

struct

{

unsigned int unknown1; // loopable flag?  always seems to be 1

unsigned int numBeats;

unsigned short key; // MIDI note 48(C) thru 59(B) or 0 for none

enum {Minor=1, Major=2, Neither=3, Both=4} scale:16;

unsigned short timeSigNum;

unsigned short timeSigDen;

char unknown2[68]; // filler? always seems to be the same

} basc;

Apple Loop Chunk: trns

This chunk with the ID of “trns” consists of information about the loop’s transient markers.  There is a 100 byte header followed by 24 byte descriptions of each transient marker.

struct

{

char unknown[100];

} trnsHeader;

The values at 0Ah and 0Bh change, but I’m not sure what  they represent.  Maybe a checksum of sorts?

struct

{

unsigned int unknown1; // flags? always seems to be 65536

unsigned int framePosition; // sample frame location of transient

char unknown2[16]; // filler? always seems the same

} Transient;

Apple Loop Chunk: cate

This chunk with the ID of “cate” consists of information about the loop’s categorisation.  I haven’t looked into this yet.

As you can see, this is a work in progress which I will update as I find out more.  Any help or corrections would be greatly appreciated.

… more like Musanim.

When I was talking about tackling overhead I was in the middle of optimising an FM piano synth that I had originally coded several months ago.  I had revisited this instrument to adapt it to a plug-in architecture I’m implementing and thought to find an interesting way to demonstrate it…

The Result

http://www.youtube.com/watch?v=p8IwQpalg8A

(I’d embed it but it’s in HD — too big for this page!)

The Story

I wanted to revisit the sort of visualisation I used at the end of my analoq.trackr video; where I leveraged Quartz Composer to represent the music sequence in a 3D patch.  Having successfully parsed MIDI files into the common “piano roll” representation in my MIDI sequencer I figured I could do a 3D piano roll for the eye candy.

The problem was I couldn’t implement this with Quartz Composer — or at least I couldn’t figure out a way to programmatically add objects to a patch with the flexibility required.  So, I started learning OpenGL and while I got all the “notes” to show up, I got frustrated trying to get everything to look presentable.  There’s a lot to learn with OpenGL and all I experienced were diminishing returns on that investment.

Fortunately, I happened to recall the open source 3D rendering software: Blender.  I figured it may have an API I could use, lo and behold it had full scripting capabilities courtesy of Python!  Well, I just so happen to speak the serpent’s tongue… oh and I know Python too!

Now there’s a lot to learn with Blender as well, especially since I have no experience with 3D software (though I played with POV-Ray back in the day…) but thanks to a variety of tutorials, instructional videos and documentation I was able to get results at an encouraging pace.

The Code

The code leverages this Python Midi Package (my own MIDI file parser is written in Objective-C, so…) But here’s a basic version of the code, without the animation and using model primitives so you get an idea of how simply it works:

import Blender
from Blender import *
from midi.MidiOutStream import MidiOutStream
from midi.MidiInFile import MidiInFile

sc = Scene.GetCurrent()

class Processor(MidiOutStream):

def __init__(self):

self.ticks480.0
# dictionary of notes and timestamps:
self.notes{}

def note_on(self, channel=0, note=0×40, velocity=0×40):

# store timestamp to note key
self.notes[note]self.abs_time()self.ticks

def note_off(self, channel=0, note=0×40, velocity=0×40):

if note in self.notes:

note_time = self.notes[note]
# create mesh
me = Mesh.Primitives.Cylinder(verts=32, diameter=1.0, length=(self.abs_time()/self.ticks) – note_time)

# add object
ob = sc.objects.new(me)
ob.LocZ = note_time
ob.LocY = note-60

del notes[note]

midi_in = MidiInFile(Processor()‘piano2.mid’)
midi_in.read()

Blender.Redraw()

More along these lines?

Even though the code did “most” of the work, it still took more time than I thought it would to put this together with all the learning required.  But it was fun and interesting as it something very different for me.  So I do hope to do more along these lines in the future.  In the meantime, I still got some code to hack…

I knew it would happen:  The projects I’m working on are reaching a point of capability where they can strain my hardware.  I’m happy to accept this as a gauge of progress but I will miss the innocence of not having to ask myself “What’s the performance overhead of this going to be?” and “What kind of memory footprint will this leave?”

Not that such questions had been entirely absent from my coding sessions but they’re not something I was forced to think about.  Now there’s literally a gun to my head… well, no.  Not literally.

Fixing Memory Leaks

Manual reference counting – that’s the name of the memory management game in Cocoa.  It’s actually something new to me;  for my first programming job memory management was a matter of malloc() and free(), then I moved onto dynamic languages like PHP and Python where it’s automated by garbage collection.  Not a problem though, just pass a retain message to an object to increment the reference count, pass release to decrement it and when the count hits 0 the object is deallocated.  Easy, right?

Well, I had a problem in which an object was curiously not being deallocated.  I checked and double checked where the reference counts were being altered but everything seemed correct.  ”It must be something stupid…” I figured, and I figured right.  Just how stupid?  Judge for yourelf:

The object refusing to be deallocated represented an amplitude envelope with some familiar properties like Attack, Decay, Sustain and Release.  Release?  Release?!  My getter for the Release property had overridden the built-in release message!  So when I’d send the Envelope a release message the reference count wouldn’t get decremented and of course it took way too long for me to notice this… ugh.

Tackling Overhead

Objective-C is a great language for UI programming.  The thing with UI code, though, is that it only needs to be fast enough to keep up with the user’s actions and accurately reflect the state of the document.  Audio processing, on the other hand, needs to be able to run 44,100 or more times every second without missing a beat and without noticeable latency.  Users probably aren’t going to be clicking a button thousands of times a second.

So with UI code, overhead isn’t a big deal but for audio code it is.  For the sake of simplicity my projects have attempted to use the same language from top to bottom and while Objective-C does function for audio processing, it does not function particularly well.

And thus I’ve been rewriting my Obj-C synths in trusty old C and have been seeing real-world performance benefits around 30%.  My personal mantra for optimisation is “If it gives me 15%, it’s probably worth doing” so in this case my efforts are doubly worthwhile.

I mentioned last time that trackers were my introduction to music software.  I also mentioned that I never got the hang of them.  So, what did I get hang of?  That would be MIDI sequencers.

Project V:  analoq.sequencr

Trackers represent music as a matrix where each row is timed to the smallest unit of measurement, usually a 16th or 32nd note.  You’d need 16 or 32 rows respectively to represent a 4/4 measure in a tracker.

With MIDI, the smallest unit of measurement is a tick and it depends on the implementation but let’s say there’s 480 ticks per beat.   If MIDI were represented in a matrix, you’d need 1,920 rows to represent a 4/4 measure – that’d be a bit hard to use.  Luckily, MIDI software has a friendlier way of representing the music: the piano roll.  And that’s precisely what my goal was to make this time:

YouTube Preview Image

I get a bit of lag from the screen capture, so do excuse my quantising.  What’s not featured in the video:

  • Loop mode:  I can set drag the markers on the measure rule to set loop points.
  • Track Muting:  The checkboxes next to the track name mute it.  No way to solo.
  • Time Signature:  This aligns the measures accordingly but the beat still has to be a quarter note e.g. 2/4, 3/4, 5/4, 7/4… you get the idea.
  • File Load/Save:  Instead of using a text format I used the Cocoa archiver. Works like a charm.
  • MIDI Import:  Inexplicably, I wrote a MIDI file parser.  It only reads Format 1 files and forget about patch/tempo/controller changes but I’m still impressed it works at all!

Overall I’m quite pleased, I’ve created something that actually resembles music software.  I’m going to try and continue on this path.

Last time I discussed my first couple attempts at making music software: a step sequencer and a subtractive softsynth.  My next project was the logical combination of these two things…

Project III:  analoq.drumachine

Taking what I learned from my Python step sequencer, I wrote another play routine in C++ to control my simple softsynth in a stand-alone app.  At this point I wasn’t very comfortable with Cocoa UI programming so I decided to use my monome for the interface:

YouTube Preview Image

I employed the jog-wheel on my Audio Kontrol 1 to “scroll” the screen of the monome across a 16×6 matrix of triggers.  This monome scrolling technique was embraced by the Max/MSP patch Soyuz.

Project IV:  analoq.trackr

By this time I was ready to get my feet wet with Cocoa’s UI framework and for inspiration I looked to my earliest experiences with making music:

Sometime around 1994 I’d found an interest in the demoscene and consequently downloaded the venerable Scream Tracker off a BBS to play with.  I never really got the hang of tracking (unlike my friend BeaT) but I did find the top-to-bottom matrix representation of the music to be an intuitive interface.

So barrelling my way through understanding bindings, delegates, outlets, action messages and whatever other object communication patterns in Cocoa I needed, I was able to build an app with the essential features for making music:

YouTube Preview Image

And that pretty much brings my series up to the present:  So far I’ve been able to make a cheesy, chippy tune with my own software.  In a cursory way, I’ve already met my goals.  But I think I can do better…

I’ve been making music for over 10 years.  I’ve been programming for over 10 years.  In that time those interests never really crossed paths.  I’m not sure why that is but perhaps it was necessary for those skills to mature independently before the synergy could be realised…

Project I:  analoq.oscr

It all started near the beginning of this year.  I had been building various Reaktor ensembles and learning about a protocol that made more sense to me than MIDI: Open Sound Control.  I wrote an OSC client in Python and created step-sequencer classes as well a basic play routine, before long  I was able to control my Reaktor ensembles from Python’s interactive interpreter.  Then I created a text-based UI:

oscr

A good first project but there was one problem:  Reaktor does not support OSC bundles, which allow you to send multiple messages at once instead of serially.  Without the assurance events that are supposed to happen at the same time will arrive together, you may not get correct timing.

Project II:  analoq.synthesizr

I began looking into software which supposedly did support bundles like Pd and SuperCollider and during my search came across something which intrigued me:  Synthesis ToolKit.  This neatly organised set of  C++ classes suddenly made the idea of building my own synthesis software attractive.  Using the STK as inspiration and adapting the oscillator and filter algorithms from the excellent site musicdsp.org I was able to build a basic subtractive synthesizer with a Cocoa UI:

YouTube Preview Image

Now that I had tackled a primitive step-sequencer and basic synth a possible goal began to emerge:

“My goal is to make some music using nothing but software that I wrote.  Should be fun to try, at least.” – Jan 12, 2009

And that’s what I’ll be discussing the progress of in this series.