输入队列回调调用但没有数据

为了开始进入macOS编程,我试图制作一个简单的程序,用于录制来自输入设备的音频(例如我的MacBook Pro上的内置麦克风)。 我在Xcode中创建了一个Objective-C Cocoa项目,代码是来自developer.apple.com的本教程的一个稍微改编的版本。

这是我的代码:

// AppDelegate.m:  

#include <AudioToolbox/AudioToolbox.h>  

- (void)applicationDidFinishLaunching:(NSNotification *)aNotification {  

     struct AQRecorderState S;  

#define PRINT_R do{  
printf("%d: r = %dn",__LINE__, r);  
}while(0)  

    AudioStreamBasicDescription *fmt = &S.mDataFormat;  

    fmt->mFormatID         = kAudioFormatLinearPCM;  
    fmt->mSampleRate       = 44100.0;  
    fmt->mChannelsPerFrame = 1;  
    fmt->mBitsPerChannel   = 32;  
    fmt->mBytesPerFrame    = fmt->mChannelsPerFrame * sizeof (float);  
    fmt->mFramesPerPacket  = 1;  
    fmt->mBytesPerPacket   = fmt->mBytesPerFrame * fmt->mFramesPerPacket;  
    fmt->mFormatFlags      = kAudioFormatFlagIsFloat | kAudioFormatFlagIsNonInterleaved;  

    OSStatus r = 0;  

    r = AudioQueueNewInput(&S.mDataFormat, HandleInputBuffer, &S, NULL, kCFRunLoopCommonModes, 0, &S.mQueue);  

    PRINT_R;  

    UInt32 dataFormatSize = sizeof (S.mDataFormat);  

    r = AudioQueueGetProperty (  
                       S.mQueue,  
                       kAudioConverterCurrentInputStreamDescription,  
                       &S.mDataFormat,  
                       &dataFormatSize  
                       );  

    S.bufferByteSize = 22050;      

    for (int i = 0; i < NUM_BUFFERS; ++i) {        
        r = AudioQueueAllocateBuffer(S.mQueue, S.bufferByteSize, &S.mBuffers[i]);  
        PRINT_R;  

        r = AudioQueueEnqueueBuffer(S.mQueue, S.mBuffers[i], 0, NULL);  
        PRINT_R;  
    }  

    S.mCurrentPacket = 0;        
    S.mIsRunning = true;        

    r = AudioQueueStart(S.mQueue, NULL);  
    PRINT_R;  

    r = AudioQueueStop(S.mQueue, true);  
    S.mIsRunning = false;  

    PRINT_R;  

    r = AudioQueueDispose(S.mQueue, true);  
}

这是我的输入回调函数(在单独的C文件中定义):

void HandleInputBuffer (  
                           void                                *aqData,             
                           AudioQueueRef                       inAQ,                
                           AudioQueueBufferRef                 inBuffer,            
                           const AudioTimeStamp                *inStartTime,        
                           UInt32                              inNumPackets,        
                           const AudioStreamPacketDescription  *inPacketDesc          
) {  

    struct AQRecorderState *pAqData = (struct AQRecorderState *) aqData;               

    if (inNumPackets == 0 && pAqData->mDataFormat.mBytesPerPacket != 0) {  
        inNumPackets =  
        inBuffer->mAudioDataByteSize / pAqData->mDataFormat.mBytesPerPacket;  
    }  
    printf("%fn", *(float*)inBuffer->mAudioData);  
    if (pAqData->mIsRunning == 0)                                      
        return;  

    AudioQueueEnqueueBuffer(pAqData->mQueue, inBuffer, 0, NULL);  
}  

当程序运行时,所有的核心音频函数调用返回0,我相信这代表“没有错误”,而HandleInputBuffer被称为NUM_BUFFERS次,以非常快的速度或者几乎立即(绝对不是每0.5秒一次)在此采样率下,建议22050的缓冲区大小),并且所有的第一个样本都是0.0。 我在这里错过了什么?


S.bufferByteSize是以字节为单位的,而不是帧,因此22050字节不是半秒,而是22050/sizeof(float)帧,因此约为八分之一秒。

如果你想半秒钟,试试

S.bufferByteSize = fmt->mSampleRate * fmt->mBytesPerFrame / 2; 

在你的上面的代码中(以及你链接的git AudioQueueStop ),你立即AudioQueueStopAudioQueueDisposeAudioQueueStart之后AudioQueueStart音频队列。 不要这样做。

链接地址: http://www.djcxy.com/p/60195.html

上一篇: Input queue callback called but no data

下一篇: Audio devices plugin and plugout event on chrome browser