“AAC” is “evil”

Problem

Few days ago, I wrote a post on which is the best audio format we should choose when developing an iPhone app. The conclusion is using IMA4, it’s the best choice if you want to record audio on the device.

Today, I was trying to use the System Sound service to play a short audio and in order to save the spaces, I chose the “AAC” format to encode my sound effects. I just thought it’s would be capable for a system sound and didn’t searched the documentation for which format is suit for System Sound. Everything went fine in the simulator. But, when I load the app into the device, and, BOOM~~, it failed to play the sound effect! My first reaction was somewhere programmatic mistake in my code, and after a careful review, I thought the reason could  be the format. So I changed the format back to IMA4, and this time, it went well!

Apparently, System sound did not support AAC format, and I could not find the appropriate document where described it. Apple just pushes us to use IMA4 and other linear PCM format to reduce the CPU and power consume. Yeah, I understand that, but please, place such kind of important information some where we can find it easily! The API documentation could be a good place.

If I am the director of the documentation team, I would promote such information and place it in a notable place! Damn it.

Why I’m angry?

Because if you using AAC for recording or System Sound, it works fine on the simulator, but will be failed on the device! If the device does not support AAC for recording and System Sound, please disable it on the simulator!

Conclusion

The conclusion is if you want to playback a song or something like this, you can choose AAC as your primary format for it is well supported by hardware codec, but only for this purpose please. If you want to record audio or play system sound effect, please choose IMA4, it’s is the second best format for iPhone.

“AAC” is a good compressed format, but it’s also has its cost.

Don’t use [AVAudioPlayer pause]

AVAudioPlayer is providing a very convenient way to play iPhone supported audio file. Especially, if you want to implement fast forward and rewind, AVAudioPlayer is the best choice.

But I just found an odd problem. If I use [AVAudioPlayer pause] method, next time if I invoke [AVAudioPlayer play], it had no responde. But after I changed pause to stop, it worked fine. The problem looks like it somewhere inside AVAudioPlayer to control the AudioQueue Object to resume playing. Whatever, by using [AVAudioPlayer stop], you can archive the same goal as [AVAudioPlayer pause] do, I mean FFW and RWD.

BTW, the document said, pause will return YES/NO, but clearly, it is a no return value instance method. The guy who is responsible for this method might copied the same comment from play!

Picture 1

What a joke. This line was there since iPhone 2.2, and is still there in 3.0b5. Didn’t there anybody reported this problem? Should I fire a bug?

AVAudioPlayer could not play after recording via AudioQueue Object.

Problem

I’ve been fighting for AVAudioPlayer and AudioQueue object for 2 days,

Here is my Dev environment:
iPhone: 3.0Beta 5
OSX 10.5.7

Here is my scenario:
1. I need to use AVAudioPlayer to play a CAF with IMA4 data format. Including fast forward and rewind.
2. I need to use AudioQueue Object to record audio, because 3.0 has not go public yet.
3. A common scenario is record an audio A, then play the original audio A’(Not the one recorded) or vice versa.

The problem is I could NOT play the A’ file  after I record file A.
[theAVAudioPlayer play] always return NO, but [theAVAudioPlayer prepareToPlay] return YES.
This situation only happened after I used the AudioQueue Object for recording. If I did not record, it always worked fine.

About the clean up.
1. I released the theAVAudioPlayer object and set to nil each time after I finished playing.
2. I closed the audio file and deposed the AudioQueue Object each time after I finished recording.

Solution

Thanks to Vitali Molodtsov[Open the original post Needs login], the solution is reset the AudioSessionCategory to kAudioSessionCategory_MediaPlayback just after finish recording. Then every thing goes fine.

Conclusion

I think this is a bug for AVAudioPlayer. Each time, when we initialize an AVAudioPlayer object, it should set the correct AudioSessionCategory for us silently, but it doesn’t. So I’ve fired a bug for Apple.

A Weird Exception from iPhone Simulator

Today I met a weird exception from AUGraphStart().

Basically, I was running an old sample code written by myself. The main function is mix 2 audio files a playback them simultaneously. I worked fine before, but when I run it, I got this exception:

[00:23:58.425 <AURemoteIOServer>] AQMEIOBase::DoStartIO: timeout
[00:23:58.701 <AURemoteIOServer>] AQMEDevice::StartIO: AudioOutputUnitStart returned -66681
[00:23:58.701 <0xa084a720>] AUIOClient_StartIO failed (-66681)
AUGraphStart FFFEFB87 

Obviously, it wasn’t came from my code, and I have no idea on this exception now. Did anybody get a same exception recently?

I had tried these:

   1. Restart the XCode. — No effects.

   2. Restart the machine(Mac Pro, 10.5.7), and restart the XCode. — No effects.

   3. Reinstall the most recent SDK(Build 9M2735), restart the XCode. — No effects.

   4. Set the base SDK to 2.2.1 and target to Simulator 2.2.1 Debug. — No effects.

It’s really odd!

Please, if anybody had met similar exception and got a solution, help me out!

Still don’t know how to resolve it now. I need  help!

[Update 2009-06-11]

A week ago, Apple’s engineer had confirmed that they had a bug in UIKit framework.

We do have a simple workaround for this UIKit bug. In UILocalizedIndexedCollation.hm change this:

  UIKIT_EXTERN @interface UILocalizedIndexedCollation : NSObject

to

  UIKIT_EXTERN_CLASS @interface UILocalizedIndexedCollation : NSObject

Having done that, we can build your project and confirm that AUGraphStart returns 0 in the 3.0 simulator.

 

But, after I installed the 3.0 GM Version today, it’s still not included in the GM Version. So that means I still can not play audio in the simulator. I can ONLY do it on the device!