格式化错误设置AudioQueue进行录制,但只会偶尔发生一次

时间:2015-05-22 21:11:23

标签: ios iphone audio-recording audioqueueservices

奇怪的是,当我们设置音频队列时,这个错误只会偶尔发生一次(即使我以同样的方式做所有事情)。设备iPhone 5,iOS8.3:

mediaserverd[37] <Error>: 15:14:24.594 ERROR:     [0x2883000] >aq> 323: AudioConverterNew from AudioQueueNew returned 'fmt?'
    io:     0 ch,  44100 Hz, 'lpcm' (0x00000029) 32-bit little-endian float, deinterleaved
    client:    0 ch,  44100 Hz, 'lpcm' (0x0000000C) 16-bit signed integer

以下是触发它的代码。

        SetupAudioFormat(kAudioFormatLinearPCM);

        // create the queue
        XThrowIfError(AudioQueueNewInput(
                                      &mRecordFormat,
                                      MyInputBufferHandler,
                                      this /* userData */,
                                      NULL /* run loop */, NULL /* run loop mode */,
                                      0 /* flags */, &mQueue), "AudioQueueNewInput failed");

其中mRecordFormat的设置如下:

void AQRecorder::SetupAudioFormat(UInt32 inFormatID)
{
    memset(&mRecordFormat, 0, sizeof(mRecordFormat));

    UInt32 size = sizeof(mRecordFormat.mSampleRate);
    mRecordFormat.mSampleRate=[AVAudioSession sharedInstance].sampleRate;

    size = sizeof(mRecordFormat.mChannelsPerFrame);
    mRecordFormat.mChannelsPerFrame=(UInt32)[AVAudioSession sharedInstance].inputNumberOfChannels;
    mRecordFormat.mFormatID = inFormatID;

    mRecordFormat.mBytesPerFrame =mRecordFormat.mChannelsPerFrame * sizeof (SInt16);
    if (inFormatID == kAudioFormatLinearPCM)
    {
        // if we want pcm, default to signed 16-bit little-endian
        mRecordFormat.mFormatFlags = kLinearPCMFormatFlagIsSignedInteger | kLinearPCMFormatFlagIsPacked;
        mRecordFormat.mBitsPerChannel = 16;
        mRecordFormat.mBytesPerPacket = mRecordFormat.mBytesPerFrame = (mRecordFormat.mBitsPerChannel / 8) * mRecordFormat.mChannelsPerFrame;
        mRecordFormat.mFramesPerPacket = 1;
    } else if(inFormatID==kAudioFileAIFFType) {
        mRecordFormat.mFramesPerPacket  = 1;
        mRecordFormat.mFormatFlags =
        kLinearPCMFormatFlagIsBigEndian
        | kLinearPCMFormatFlagIsSignedInteger
        | kLinearPCMFormatFlagIsPacked;
    }
}

我对错误的解释是手机正在记录为32位小端浮点数,解交织,我正在尝试设置一个格式为16位有符号整数的队列。但为什么我不是每次都得到错误?如何解决?

1 个答案:

答案 0 :(得分:0)

AudioStreamBasicDescriptions真的很烦人。这是我使用的。我有把typeDefed AudioStreamBasicDescription添加到ASBD

ASBD asbdWithInfo(Boolean isFloat,int numberOfChannels,Boolean interleavedIfStereo){
    ASBD asbd = {0};
    int sampleSize          = isFloat ? sizeof(float) : sizeof(SInt16);
    asbd.mChannelsPerFrame  = (numberOfChannels == 1) ? 1 : 2;
    asbd.mBitsPerChannel    = 8 * sampleSize;
    asbd.mFramesPerPacket   = 1;
    asbd.mSampleRate        = 44100.0;
    asbd.mBytesPerFrame     = interleavedIfStereo ? sampleSize * asbd.mChannelsPerFrame : sampleSize;
    asbd.mBytesPerPacket    = asbd.mBytesPerFrame;
    asbd.mReserved          = 0;
    asbd.mFormatID          = kAudioFormatLinearPCM;
    if (isFloat) {
        asbd.mFormatFlags = kAudioFormatFlagIsFloat;
        if (interleavedIfStereo) {
            if (numberOfChannels == 1) {
                asbd.mFormatFlags = asbd.mFormatFlags | kAudioFormatFlagsNativeEndian | kAudioFormatFlagIsPacked | kAudioFormatFlagIsNonInterleaved;
            }
        }
        else{
            asbd.mFormatFlags = asbd.mFormatFlags | kAudioFormatFlagIsNonInterleaved | kAudioFormatFlagIsPacked ;
        }
    }
    else{
        asbd.mFormatFlags = kAudioFormatFlagIsSignedInteger | kAudioFormatFlagsNativeEndian | kAudioFormatFlagIsPacked;
        if (!interleavedIfStereo) {
            if (numberOfChannels > 1) {
                asbd.mFormatFlags = asbd.mFormatFlags | kAudioFormatFlagIsNonInterleaved;
            }

        }
    }
    return asbd;
}