Audio programming basics

Recently I wrote an app using OF to sequence MIDI notes. It synchronises with an external clock (from Live, Logic, etc.) and broadcasts MIDI notes. Here’s a video of it being used.

However, I’d like to be able to generate the clock and some simple instruments internally, so I’m working on another sequencer with those goals in mind.

To generate a clock I’m simply counting the number of samples that are written to the audio buffer during the audioOut callback, which seems to work well. If there is a better way to do this, please tell me.

Generating audio for notes, on the other hand, seems quite tricky. I’m sure that generating a sine wave with an ADSR envelope will be easy to do on its own, but I’m struggling to imagine how my program should be laid out such that the sequencer can be queried during each audio callback and the appropriate n-samples array can be computed. If a note has a long decay, for instance, how can I continually write the decay to the buffer after the playhead has passed the note?

I’ve been looking at ofxPDSP and SoundBox to try to work out how this sort of thing is done, but I’m still confused, and given that this is a fairly niche subject, it’s tricky to find the answers to these question online. I would greatly appreciate it if someone could point me in the right direction!

Thank you.

2 Likes

hey, i’m the coder for ofxPDSP, i mostly didn’t do it in a very canonical way as i wanted ofxPDSP to resemble some kind of modular synthesizer.

to see how this kind of things are managed you could also check out the JUCE source code

Thank you. I’ll check that out. ofxPDSP is excellent, by the way! Well done.

1 Like

you can try ofxPd that uses libpd / pure data patches too:

another OF addon mentioned on the forum is:

Have you made this ‘clock machine’ with OF?
I would like to check in case you have it public in github, of course…

I used some other clocks without the audio buffer link/control that you used, and do not works tight, neither using threads.

like:




I found your repository, thanks for sharing!

it looks nice that have you mixed OF with the native stuff too.

do you think it’s posible to isolate the clock with basic step sequencer engine to use into OF easy?

Thank you. I’ll check out those addons.

Yes, that should be quite easy to do. In my project, the Clock class listens for external clock ticks and broadcasts them using the OF events system. The sequencer is updated and queried on each clock tick. That’s all there is to it, basically.

i’d also like everyone interested in audio programming to read this:

http://www.rossbencina.com/code/real-time-audio-programming-101-time-waits-for-nothing

4 Likes

Thanks. But the internal clock using the audio buffer is no included, right? That would be a good addon I think.

Oh, that’s a blast from the past! I actually worked on XAudio2 back in the Xbox 360/Kinect days. A great read. Though WASAPI was horrendous as far as being prone to glitches, since it only allowed you to have two buffers of a few milliseconds to toggle between. XAudio2 was actually designed to help move away from WASAPI, as it allowed you to queue up arbitrary sample lengths and would mix for you (the problems came when callback DSPs ran too long, or calculations like reverb hit denormal forms… OMG, and priority inversions on the 360 were horrendous, because the naïve scheduler could allow for seconds of silence).

My first GDC talk was "Proactively Identifying Transients Using Digital Signal Processing " (i.e. automatically halt your game when the audio stream gets corrupted/hitched, using a simple kernel, so you can see what was happening). It was… not well attended, and I learned my lesson in creating more enticing talk names. :stuck_out_tongue:

(I’m actually perusing the forums because I’m working on a libfreenect2 6-camera merged point cloud timelapse project, and oF intrigued me greatly).

1 Like

That’s right. To be clear, the way I’m generating the clock is naive and simple. I’m simply counting the number of samples written to the buffer and sending a notification each time the number of samples is equal to one subdivided “beat”, as in BPM.

Presumably there’s some inconsistency because the rate of writing samples to the buffer is faster than the sample rate, but it seems fairly steady with a small buffer size.

int samples = 0;
int bpm = 120;
int ticksPerBeat = 4;
int samplesPerTick = (44100 * 60.0f) / bpm / ticksPerBeat;

void audioOut(ofSoundBuffer &buffer)
{
    for (size_t i = 0; i < buffer.getNumFrames(); ++i)
    {
        if (++samples == samplesPerTick)
        {
            tick();
            samples = 0;
        }
        
        // ...
    }
}
1 Like