General param error retrieving record format with

2019-09-12 19:55发布

问题:

I am getting a -50 (general param error) from a call to AudioQueueGetProperty. Please help me as it has been several months since I've touched XCode and any iPhone work. This is likely a simple goof on my behalf but I cannot resolve it. My code leading to the -50:

//Setup format
AudioStreamBasicDescription recordFormat;
memset(&recordFormat, 0, sizeof(recordFormat));
recordFormat.mFormatID = kAudioFormatMPEG4AAC;
recordFormat.mChannelsPerFrame = 2;
CCGetDefaultInputDeviceSampleRate(&recordFormat.mSampleRate);
UInt32 propSize = sizeof(recordFormat);
AQ(AudioFormatGetProperty(kAudioFormatProperty_FormatInfo, 0, NULL,
                                  &propSize, &recordFormat), 
           "AudioFormatGetProperty throws unexpected errors.");

//Setup Queue
//listing 4.8-4.9
AudioQueueRef theQueue = {0};
self->queue = theQueue;
AQ(AudioQueueNewInput(&recordFormat, CCAudioRecordingCallback, 
                              self, NULL, NULL, 0, &self->queue),
           "AudioQueueNewInput throws unexpected errors.");
UInt32 size = sizeof(recordFormat);
AQ(AudioQueueGetProperty(self->queue,
                                 kAudioConverterCurrentOutputStreamDescription, 
                                 &recordFormat, 
                                 &size), 
           "Getting audio property kAudioConverterCurrentOutputStreamDescription throws unexpected errors.");

I have verified that I have a valid queue just as I make the call to AudioQueueGetProperty. I've tried both ways of passing the queue "self->queue", and "self.queue" and they both result in the same error. The queue is defined as follows:

@interface CCAudioRecorder()
//...
@property (nonatomic, assign) AudioQueueRef queue;
//...

@end

@implementation CCAudioRecorder
@synthesize queue;

AQ is a #def:

#define AQ(expr, msg) if(nil!=CheckError((expr), msg)) [NSException raise:@"AudioException" format:@"Unexpected exception occured."];

Which resolves to the following error checking function:

static NSString* CheckError(OSStatus error, const char* operation)
{
    if (noErr == error) return nil;

    NSString *errorMessage = nil;
    char errorString[20];
    //See if it appears to be a 4-char code
    *(UInt32 *)(errorString+1) = CFSwapInt32HostToBig(error);
    if ( isprint(errorString[1]) && isprint(errorString[2]) 
        && isprint(errorString[3]) && isprint(errorString[4]) ) 
    {
        errorString[0] = errorString[5] = '\'';
        errorString[6] = '\0';
    } else {
        sprintf(errorString, "%d", (int)error);
    }
    errorMessage = [NSString stringWithFormat:
                    @"Audio Error: %@ (%@)\n", 
                    [NSString stringWithUTF8String:operation], 
                    [NSString stringWithUTF8String:errorString]];
    NSLog(@"%@", errorMessage);
    return errorMessage;
}

I've also tried calling AudioFormatGetProperty on a queue created with a local variable, avoiding the class instance level iVar and still get the same error:

AudioQueueRef theQueue = {0};
AQ(AudioQueueNewInput(&recordFormat, CCAudioRecordingCallback, 
                              self, NULL, NULL, 0, &theQueue),
           "AudioQueueNewInput throws unexpected errors.");
UInt32 size = sizeof(recordFormat);
AQ(AudioQueueGetProperty(theQueue,
                                 kAudioConverterCurrentOutputStreamDescription, 
                                 &recordFormat, 
                                 &size), 
           "Getting audio property kAudioConverterCurrentOutputStreamDescription throws unexpected errors.");

** Update ** I have the following code which works on the simulator and not on the device. (I have not cross referenced it with what I posted earlier but I believe it's either similar or the exact.)

AudioQueueRef theQueue = {0};
self->queue = theQueue;
AQ(AudioQueueNewInput(&recordFormat, CCAudioRecordingCallback, 
                              self, NULL, NULL, 0, &self->queue),
           "AudioQueueNewInput throws unexpected errors.");
UInt32 size = sizeof(recordFormat);
AQ(AudioQueueGetProperty(self->queue, 
                                 kAudioConverterCurrentOutputStreamDescription, 
                                 &recordFormat, 
                                 &size), 
           "Getting audio property kAudioConverterCurrentOutputStreamDescription throws unexpected errors.");

Running it on device I get a crash in the same spot with error -50 general param error. My device is an iPhone 4S running iOS6 I'm working with XCode 4.5.

回答1:

You are following the code from the learning core audio book right? Chapter 4 about implementing a recorder? I noticed a difference between your code and the book's code, in the book they simply initialize the Queue and use it as is:

AudioQueueRef queue = {0};
UInt32 size = sizeof(recordFormat);
CheckError(AudioQueueGetProperty(queue, kAudioConverterCurrentOutputStreamDescription,
                                 &recordFormat, &size), "couldn't get queue's format");

I'm not sure why you're throwing self in the mix. But that's definitely what's causing your bug. If all fails simply download the complete code for that chapter here and see where you can identify your mistake.