当我使用AudioQueue作为具有低延迟的输入时,AudioQueueBuffer数据在几秒钟后变为ZERO

时间:2012-11-25 17:54:59

标签: ios buffer recording audioqueue

我对AudioQueueInput有严重问题。我为每个音频队列缓冲区分配512个样本(采样率为44.1kHZ)。我的回调函数编写如下:

void MyAudioQueueInputCallback (
                                void                                *inUserData,
                                AudioQueueRef                       inAQ,
                                AudioQueueBufferRef                 inBuffer,
                                const AudioTimeStamp                *inStartTime,
                                UInt32                              inNumberPacketDescriptions,
                                const AudioStreamPacketDescription  *inPacketDescs
                                )
{    
    ANSampleInput *input = (__bridge ANSampleInput *)inUserData;

    Float32 * samples = (Float32 *)inBuffer->mAudioData;
    Float32 * data = malloc(input.framesPerBuffer * sizeof(Float32 *));
    memcpy(data, samples, input.framesPerBuffer * input->audioFormat.mBytesPerFrame );
    AudioQueueEnqueueBuffer(input->audioQueue, inBuffer, 0, NULL);

    for (int i = 0; i < 512; i ++) {
        printf("%f",data[i]);
    }
}

这段代码是为测试目的而编写的,所以我没有添加任何其他方法。但只是这个简单的代码会导致问题。

当我按下按钮开始录制时,数据阵列将填充原始PCM值。然而,几秒钟后数据全部变为零。

当我在iPod touch 4中测试我的项目时,首先出现这个问题。在此之前,我的iPhone模拟器中的一切正常(数据不会为零)(延迟非常低)。我想也许iPod touch 4的CPU功能不足以处理非常低延迟的回调。但现在没有任何理由我的iPhone模拟器有同样的问题(根据调试器中弹出的信息也有高延迟)。

我检查了我的代码,我认为它与许多示例代码相同。现在我真的很困惑,因为模拟器也不起作用。

我的AudioQueueInput的初始化代码如下:

- (id)initWithSampleRate:(NSUInteger)rate bufferSampleCount:(NSUInteger)sampleNumber
{
    if ((self = [super init])) {
        self.sampleRate = rate;

        audioFormat.mFormatID = kAudioFormatLinearPCM;
        audioFormat.mChannelsPerFrame = 1;
        audioFormat.mBitsPerChannel = 8 * sizeof(Float32);
        audioFormat.mFramesPerPacket = 1;
        audioFormat.mSampleRate = rate;
        audioFormat.mBytesPerFrame = sizeof(Float32);
        audioFormat.mBytesPerPacket = sizeof(Float32);
        audioFormat.mFormatFlags = kAudioFormatFlagIsNonInterleaved | kAudioFormatFlagIsPacked | kAudioFormatFlagIsFloat;


        OSStatus status = AudioQueueNewInput(&audioFormat, MyAudioQueueInputCallback,
                                             (void *)CFBridgingRetain(self), CFRunLoopGetCurrent(),
                                             kCFRunLoopDefaultMode, 0, &audioQueue);
        if (status != noErr) {
            return nil;
        }

        self.framesPerBuffer = sampleNumber;

        for (int i = 0; i < kBufferCount; i++) {
            status = AudioQueueAllocateBuffer(audioQueue, sizeof(Float32) * self.framesPerBuffer, &buffers[i]);
            if (status != noErr) {
                for (int j = i - 1; j >= 0; j--) {
                    AudioQueueFreeBuffer(audioQueue, buffers[j]);
                }
                AudioQueueDispose(audioQueue, NO);
                return nil;
            }
            AudioQueueEnqueueBuffer(audioQueue, buffers[i], 0, NULL);
        }
    }
    return self;
}

请有人帮助我!

编辑:

无意中,当我删除for循环以打印样本数组中的每个值时,它工作正常,即使我在样本数组上有一些进程。这很奇怪,因为printf不应该花费比FFT算法更多的时间。无论如何,它现在有效。

0 个答案:

没有答案