Search This Blog

Sunday, August 28, 2011

XCode, AudioUnits, Breakpoints and NSLog Misery...

So I am debugging an iOS AudioUnit render callback function.

I have the exact same code working in a standalone project so I know that everything is correct.  The code in question looks something like this:

OSStatus recordingCallback(void *inRefCon,
                 AudioUnitRenderActionFlags * ioActionFlags,
                 const AudioTimeStamp *inTimeStamp,
                 UInt32 inBusNumber,
                 UInt32 inNumberFrames,
                  AudioBufferList *ioData)
{   
  AudioBuffer buffer;
  AudioBufferList bufferList;
   
  ...
 

   buffer.mNumberChannels = 1;
  buffer.mDataByteSize = inNumberFrames * 2;
  buffer.mData = malloc( inNumberFrames * 2 );
  bufferList.mNumberBuffers = 1;
  bufferList.mBuffers[0] = buffer;

  ...

  status = AudioUnitRender(audioUnit,
                           ioActionFlags,
                           inTimeStamp,
                           inBusNumber,
                           inNumberFrames,
                           &bufferList);


  if (status != noErr)
  {
    NSLog(@"An AudioUnitRender error occurred (%d).", status);
  }
  ...
}

 
The buffer arrangement is such that only a single buffer is being used.

In the stand alone project status is always equal to noErr and the NSLog function is never called and the render works fine.

When I copy this code without change into the main project suddenly all hell breaks loose.

First off, status starts reliably returning -50 (which indicates a bad parameter is being passed to AudioUnitRender).  

Bad parameter? 

How on earth can that be as the exact same parameters work perfectly in the standalone project.  After endless diddling to ensure that I am not doing something stupid I start to look for other reasons this might be failing.

Eventually I discover a post on some Apple developer list where someone else has a similar problem.  They trace this to the use of AVAudioPlayer and its associated start method.  (Basically this means if you have some other part of the project playing background music the above code ceases to work correctly and indicates bad parameters are being passed.)

Commenting out this code (the AVAudioPlayer code along with some MixerHostAudio-derived code) appears to make the project work but I notice that I am no longer seeing NSLog output (the project barfs out all kinds of status as it boots up).  Then breakpoints seem to no longer work so I cannot tell if removing the use of AVAudioPlayer is really working or not.

Now I become extremely frustrated. 

How can NSLog simply cease to work?

So I think - well, this must be an XCode 4 problem...

I open the project in the latest version of XCode 3 and NSLog does not work there either nor do breakpoints...!!!

What the hell?  I curse Apple, Jobs, and the iOS development staff.

(This is made worse by recently discovering that Adobe CS 2 will not work on Lion, Lion being required to have the newest XCode 4 and no doubt iOS 5.  I want a law passed that requires Apple to compensate me for taking away functionality with required software releases...)

Now what?

More hours of Googling and diddling until if find this on StackOverflow (with some changes):

    1. Quit XCode 3/4.
    2. Open a terminal window and cd to the project directory
    3. cd into the .xcodeproj directory
    4. Delete everything except the .pbxproj file.

Or, in Finder Right/Option-Clicking on the .xcodeproj bundle, pick "Show Package Contents," and remove all but the .pbxproj file.

This seems to work - at least some of the time and sort of magically the breakpoints and NSLog output reappear and work as expected!

But then it flakes out again - sometimes working - sometime not.

I guess at this point the only things I can come up with are either

A) Somehow the render function is messing things up.  Everything works save for the microphone callback just fine - or at least it did - no flakies until I added in that extra AudioUnit code.  It seems as if this addition permanently wacked out XCode4 for this project (others at least appear to still work correctly including the standalone version of the AudioUnit.

B) Mixing to much AudioUnit stuff is a problem or flakey...  Others report the AVAudioPlayer problem with AudioUnit and other things (like playing movies).

More to come...



No comments:

Post a Comment