2

我对 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 算法花费更多的时间。无论如何,它现在有效。

4

0 回答 0