views:

61

answers:

2

I'm attempting to write an app that can arrange timed playback of some (mostly tiny) audio files. The catch: it needs to be timed with accuracy worthy of music. The sounds won't be played frequently (it's not, for example, a sampler or a drum kit), but they will need to be absolutely precisely placed. There are two parts to this question:

  1. How should I organize the timing? I've heard NSTimer is inaccurate, or at least unreliable? Should I use MIDI somehow? Or a tight loop and some time-getting function with high resolution?

  2. Once I've got the timing set up, and I know when to play my sounds... how should I play them? Is NSSound fast and reliable enough to maintain the accuracy needed?

+1  A: 

NSTimer is accurate enough for most purposes as long as you don't dilly-dally on whatever thread the timer is scheduled on long enough for the timer to be late. You need to return to the run loop in time for its next fire date. Fortunately, NSSound plays asynchronously, so this shouldn't be a problem.

What usually causes problems with NSTimers is when people set the interval really low (one question I saw had it at 1 centisecond). If what you do takes longer than that interval (and taking longer than 1 centisecond is really easy), then you will return to the run loop after the timer was supposed to fire, which will make the timer late, which will screw up your timing.

You just need to make your timer method implementation as fast as possible, and if you can't make it fast enough, make an NSOperation subclass to do the job and have your timer method just instantiate the operation, set it up, and add it to an operation queue. (The operation will run on another thread, so it won't tie up the thread whose run loop you scheduled your timer on.) If the timer may be really frequent, then this is one case where micro-optimization (guided by Instruments and Shark, of course) may be warranted.

Peter Hosey
This makes an `NSTimer`/`NSSound` implementation seem very promising! Just what I was hoping for! We'll see how it goes...
andyvn22
I'd be sceptical about an NSTimer implementation. How quickly it fires will be entirely dependent on what the app is doing.
JeremyP
+2  A: 

I doubt that you would be able to achieve sample-accurate timing for audio using an NSTimer/NSSound approach.

I think your best bet is to use Core Audio directly. Unfortunately, the learning curve is a bit steep because it is a C API that isn't as well documented as Cocoa.

The easiest way to start out would be AudioQueue- it should provide all the functionality you'll need to playback audio and has provisions for timing.

Another option is to use the lower level AUGraph and Audio Units- a simple AUGraph with two Audio Units- an AudioFilePlayer (or ScheduledSoundPlayer) connected to the default output unit would work well also.

sbooth