Input queue callback called but no data

In an effort to start getting into macOS programming, I'm trying to make a simple program that would record audio from an input device (eg. the built-in microphone on my MacBook Pro). I have created a Objective-C Cocoa project in Xcode and the code is a slightly adapted version of this tutorial from developer.apple.com.

Here's my code:

// 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);  
}

Here's my input callback function (defined in a separate C file):

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);  
}  

When the program is run, all of the Core Audio function calls return 0, which (I believe) represents "no error", and HandleInputBuffer is called NUM_BUFFERS times in a very rapid succession or almost instantly (most definitely not every 0.5 secs like the buffer size of 22050 would suggest at this sample rate), and all the first samples are 0.0. What am I missing here?


S.bufferByteSize is in bytes, not frames, so 22050 bytes is not half a second, but 22050/sizeof(float) frames, so about an eighth of a second.

If you want half a second, try

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

In your above code (and also in the git repo you linked), you immediately AudioQueueStop and AudioQueueDispose the audio queue after AudioQueueStart ing it. Don't do that.

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

上一篇: 如何推迟使用jQuery?

下一篇: 输入队列回调调用但没有数据