iPhone Low Level Audio Part II : AudioQueue Output

| | Comments (0) | TrackBacks (0)
Note: This entry (and everything before it) refers to firmware version 1.x...i.e. the original jaibroken/toolchain type.  This information will be of limited use for development on firmware version 2.0+.

AudioQueue Header

To start off, you will need the AudioQueue.h file...this wasn't included in original toolchain releases, but it should be fairly common now.  Check your usr/local/arm-apple-darwin/include/AudioToolbox folder for it.  If it's not there, you will need to put it there. 

The Output Callback

AudioQueue output is pretty straightforward.  I strongly recommend you check out the documentation on Apple's website (in the AudioToolbox part for Leopard).  As far as explaining goes, It does a better job than I plan on doing.  It will also have sample sourcecode ...AudioQueueTest...I recommend you use this as a template...

Notice that AudioQueue is a C routine, and not an Objective C one.  The main function is a "callback"...if you are strictly a Java person, then you might not be familiar with this concept.  Instead of you calling a method everytime you want to play something, you instead designate a callback function, and the system calls YOU whenever it's ready for more audio data.  "Don't call us...we'll call you," says the sound system.

And because this is C (and not ObjC), this callback method won't be inside of any class...it won't be "object oriented".  It's a static function that doesn't have access to member variables of a class it may or may not be affiliated with.  (It can still be in the same file, it just won't technically be part of that class).  And let's assume you aren't going to use static variables...then how will this static function know what to send?  Through a custom struct...you design it yourself, and the system will pass it to the callback whenever it is called.  This way, you can make the callback function independent. 

In Apple's example, the callback is named AQTestBufferCallback, and the custom data struct is called AQTestInfo.  Don't reuse "AQTestInfo" in the Apple example...start from scratch and make the custom struct contain whatever you think it should.

I would get rid of all the XThrowIfError stuff...it's good to check for errors, but you can do it other ways later.  DON'T get rid of the stuff inside of the XThrowIfError part...it cocoons the important function calls.

The two main things you need to have in the callback are:
1)inCompleteAQBuffer->mAudioDataByteSize = (# of bytes you plan on putting in the queue)
2)AudioQueueEnqueueBuffer command...this is what actually sends the audio data off to the system.

The Rest

AudioQueue works by recycling a certain number of buffers.  While it's playing the data in one, it's letting you fill a different one.  It's sort of like the security checkpoint in an airport...those trays that you stick the carry-on bags into so they can run through the x-ray machine.  While one is being scanned, a few others are being filled by passengers.  After the one being scanned has made it out the other end, it is returned to be filled again.  And so on.  You get to choose how many buffers you want in circulation.  I recommend 3.

Before the callback gets called, you obviously need to inform the audio system that you will be supplying audio data.
This is done by these essential calls:
  • AudioQueueNewOutput - creates the new output system...you specify your callback function here.
  • AudioQueueAllocateBuffer - this is called each time you want to create a buffer.  So you would probably want to call this three times.
  • AudioQueueStart - this starts the AudioQueue...surprise.
The example has a while-loop following the AudioQueueStart.  This is needed if you are running the AudioQueue in its own thread.  You don't need this if either 1) you are running the AudioQueue in the main thread, or 2) you let the AudioQueue choose its own thread to run it in,  (The latter is accomplished by passing a NULL in the AudioQueueNewOutput function instead of CFRunLoopGetCurrent).

  • AudioQueueDispose - This isn't part of the init, but rather part of the destruction of the AudioQueue.  This is VERY important...you need to free up the audio hardware...don't assume this will be done automatically when the program ends.



0 TrackBacks

Listed below are links to blogs that reference this entry: iPhone Low Level Audio Part II : AudioQueue Output.

TrackBack URL for this entry: http://mauvilasoftware.com/cgi-bin/mt/mt-tb.cgi/27

Leave a comment

About this Entry

This page contains a single entry by JLA published on April 12, 2008 9:10 AM.

Low level audio on the iPhone : a brief introduction was the previous entry in this blog.

A Brief Intro to Objective C Protocols is the next entry in this blog.

Find recent content on the main index or look in the archives to find all content.



Powered by Movable Type 4.1-en-release-26-r1120-20071224