开发者

iOS AudioQueues: glitches in audio float-stream

开发者 https://www.devze.com 2023-02-03 19:03 出处:网络
I am logging the stream of floats coming from the microphone (should be silence) I have setup audio queueswith a buffer size of 256 floats

I am logging the stream of floats coming from the microphone (should be silence)

I have setup audio queues with a buffer size of 256 floats

A typical buffer looks like this:

PACKET 0.004791, 0.012512,0.008423,0.000122,-0.000519,-0.002991,-0.000031,0.001801,-0.000641, 0.001190,-0.003143,-0.001587,0.001587,-0.015503,-0.019440,-0.015167,-0.017670, -0.018158,-0.019928,-0.019409,-0.024017,-0.019684,-0.024719,-0.044128,-0.043579, -0.043152,-0.046417,-0.045380,-0.050079,-0.050262,-0.049164,-0.040710,-0.036713, -0.051056,-0.045868,-0.035034,-0.033722,-0.028534,-0.027161,-0.022186,-0.018036, -0.012207,0.004303,-0.000824,-0.000610,0.014496,0.018005,0.019745,0.019226, 0.016144,0.013184,0.009003,0.014557,0.003357,-0.011353,-0.007751,-0.007660, -0.006409,-0.003357,-0.003510,-0.001038,-0.000092,0.007690,0.002655,0.000000, 0.000000,0.000000,0.000000,0.000000,0.000000,0.000000,0.000000,0.000000, 0.000000,0.000000,0.000000,0.000000,0.000000,0.000000,0.000000,0.000000, 0.000000,0.000000,0.000000,0.000000,0.000000,0.000000,0.000000,0.000000, 0.000000,0.000000,0.000000,0.000000,0.000000,0.000000,0.000000,0.000000, 0.000000,0.000000,0.000000,0.000000,0.000000,0.000000,0.000000,0.000000, 0.000000,0.000000,0.000000,0.000000,0.000000,0.000000,0.000000,0.000000, 0.000000,0.000000,0.000000,0.000000,0.000000,0.000000,0.000000,0.000000, 0.000000,0.000000,0.000000,0.000000,0.000000,0.000000,0.000000,0.000000, 0.000000,0.000000,0.000000,-0.006897,-0.000549,0.003174,0.003540,0.003632, 0.004578,0.005280,0.001831,0.014771,0.014954,0.001801,0.009247,0.011139, 0.005249,0.008087,0.008636,0.007385,0.007263,0.016571,0.020264,0.010590, 0.014801,0.023132,0.027039,0.031128,0.031799,0.037109,0.038757,0.049438, 0.057098,0.042786,0.04开发者_C百科5593,0.052032,0.045380,0.045227,0.045837,0.043793, 0.041931,0.043976,0.046570,0.030182,0.024475,0.029877,0.026184,0.026001, 0.026611,0.031921,0.035736,0.040710,0.053070,0.042572,0.039917,0.051636, 0.053009,0.053528,0.053009,0.054962,0.055603,0.053833,0.060638,0.050171, 0.041779,0.049194,0.046356,0.000000,0.000000,0.000000,0.000000,0.000000, 0.000000,0.000000,0.000000,0.000000,0.000000,0.000000,0.000000,0.000000, 0.000000,0.000000,0.000000,0.000000,0.000000,0.000000,0.000000,0.000000, 0.000000,0.000000,0.000000,0.000000,0.000000,0.000000,0.000000,0.000000, 0.000000,0.000000,0.000000,0.000000,0.000000,0.000000,0.000000,0.041931, 0.038879,0.034515,0.031494,0.026337,0.034576,0.028992,0.014038,0.018127, 0.017822,0.015137,0.015778,0.013519,0.015564,0.014832,0.023285,0.022034, 0.006317,0.010254,0.010742,0.004303,0.003784,-0.000153,-0.002502, ~

I can't understand why I seem to have random bunches of zeros in the input signal. There seems to be something discontinuous.

I first thought maybe I had left and right channel, and the right channel was always recording zero. But looking through my code, I have clearly set it up for a single channel.

Then I thought maybe these are just places of silence in the signal. But that doesn't make sense. If I have just had a dozen zeros, 0.000000 surely I would expect very very small numbers to follow, like .000007 .000014 but nonzero numbers seem to be around the 0.01 mark.

I have just tried switching my audio input to an external USB microphone, and this improves the resolution. The nonzero numbers now seem to be around the .001 mark. but still there is a noticeable discontinuity...

I wonder if some calculation is being performed on the chip that rounds to 0. if this is the case, can it be calibrated? What is going on?

A second really strange problem I'm noticing is rogue values.

Here is a sample packet which contains some of these values (this time using the USB microphone; you can see how the resolution is improved):

~ PACKET -0.001343, -0.001190,-0.001526,-0.001373,-0.000946,-0.001526,-0.001221,-0.001190,-0.001221, -0.001251,-0.001373,-0.001190,-0.001312,-0.001312,-0.001434,-0.001282,-0.001312, -0.001099,-0.001007,-0.001221,-0.001160,-0.001312,-0.001343,-0.001221,-0.001007, -0.001099,-0.001404,-0.001068,-0.001038,-0.001404,-0.001038,-0.001190,-0.001404, -0.001099,-0.001282,-0.001221,-0.001007,-0.001007,-0.001099,-0.001221,-0.001160, -0.001038,-0.001038,-0.001007,-0.000946,-0.001129,-0.000916,-0.000946,-0.000946, -0.000946,-0.000824,-0.000824,-0.001007,-0.000763,-0.001038,-0.000854,-0.000977, -0.000916,-0.000641,-0.000977,-0.000916,-0.000946,-0.000732,-0.000824,0.000000, 0.000000,0.000000,0.000000,0.000000,0.000000,0.000000,0.000000,0.000000, 0.000000,0.000000,0.000000,0.000000,0.000000,0.000000,0.000000,0.000000, 0.000000,0.000000,0.000000,0.000000,0.000000,0.000000,0.000000,0.000000, 0.000000,0.000000,0.000000,0.000000,0.000000,0.000000,0.000000,0.000000, 0.000000,0.000000,0.000000,0.000000,0.000000,0.000000,0.000000,0.000000, 0.000000,0.000000,0.000000,0.000000,0.000000,0.000000,0.000000,0.000000, 0.000000,0.000000,0.000000,0.000000,0.000000,0.000000,0.000000,0.000000, 0.000000,0.000000,0.000000,0.000000,0.000000,0.000000,0.000000,0.000000, 0.000000,0.000000,0.000000,0.000000,0.000000,0.000000,0.000000,0.000000, 0.000000,0.000000,0.000000,0.000000,0.000000,0.000000,0.000000,0.000000, 0.000000,0.000000,0.000000,0.000000,0.000000,0.000000,0.000000,0.000000, 0.000000,0.000000,0.000000,0.000000,0.000000,0.000000,0.000000,0.000000, 0.000000,0.000000,0.000000,0.000000,0.000000,0.000000,0.000000,0.000000, 0.000000,0.000000,0.000000,0.000000,0.000000,0.000000,0.000000,0.000000, -0.000000,2.000000,-2.000000,0.000000,-0.000000,36893488147419103232.000000,-36893488147419103232.000000,0.000000, -0.000000,8589934592.000000,-8589934592.000000,0.000000,-0.000000,158456325028528675187087900672.000000,-158456325028528675187087900672.000000,0.000000, -0.000000,131072.000000,-131072.000000,0.000000,-0.000000,2417851639229258349412352.000000,-2417851639229258349412352.000000,0.000000, -0.000000,562949953421312.000000,-562949953421312.000000,0.000031,-0.000031,10384593717069655257060992658440192.000000,-10384593717069655257060992658440192.000000,0.000000, 0.000000,0.000000,0.000000,0.000000,0.000000,0.000000,0.000000,0.000000, 0.000000,0.000000,0.000000,0.000000,0.000000,0.000000,0.000000,0.000000, 0.000000,0.000000,0.000000,0.000000,0.000000,0.000000,0.000000,0.000000, 0.000000,0.000000,0.000000,0.000000,0.000000,0.000000,0.000000,0.000000, 0.000000,0.000000,0.000000,0.000000,0.000000,0.000000,0.000000,0.000000, 0.000000,0.000000,0.000000,0.000000,0.000000,0.000000,0.000000,

This is confusing me. the occurrence of these glitches is low; less than one in 10 frames.

Does this mean I have to preprocess my audio stream?

Last time when I was using audio units, I never did that. I just piped the audio straight into a pitch detection routine. And that had no problems. So I wonder if I was getting glitches there as well..

I get glitches both with the inbuilt MacBook microphone and the external USB microphone

Here is my code:

//
//  MicRecord.m
//  PitchDetect
//
//  Created by Pi on 05/01/2011.
//

#import "MicRecord.h"

void AudioInputCallback(
                        void * inUserData, 
                        AudioQueueRef inAQ, 
                        AudioQueueBufferRef inBuffer, 
                        const AudioTimeStamp * inStartTime, 
                        UInt32 inNumberPacketDescriptions, 
                        const AudioStreamPacketDescription * inPacketDescs) ;


@implementation MicRecord

@synthesize fftFrame;

/*
- (id) init 
{
    if (self = [super init]) 
    {
        [self setupWithSampleRate: 44100
                          buffers: 12
                           bufLen: 512 ];
    }

    return self;
}
 */

// - - - - - - - -

- (void) setupWithSampleRate: (int) in_sampRate
                     buffers: (int) in_nBuffers
                        step: (int) in_step
                   frameSize: (int) in_frameSize
                      target: (id) in_target
                         sel: (SEL) in_sel
{
    sampRate = in_sampRate;

    nBuffers = in_nBuffers;

    bufLen = in_step;

    frameSize = in_frameSize;

    targ = in_target;
    sel = in_sel;

    audioBuffer = calloc(nBuffers, sizeof(AudioQueueBufferRef *) );
    [self setupAudioFormat];
    [self setupAudioQueue];

    fftFrame = calloc(frameSize, sizeof(float) );
}

// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -

- (void) setupAudioFormat
{
    // Set the format to 32 bit, single channel, floating point, linear PCM
    const int four_bytes_per_float = 4;
    const int eight_bits_per_byte = 8;

    memset(& dataFormat, 
           (int) 0x00, 
           sizeof(dataFormat) );

    dataFormat.mSampleRate = sampRate;
    dataFormat.mFormatID = kAudioFormatLinearPCM;
    dataFormat.mFormatFlags = kAudioFormatFlagsNativeFloatPacked | kAudioFormatFlagIsNonInterleaved;
    dataFormat.mBytesPerPacket = four_bytes_per_float;
    dataFormat.mFramesPerPacket = 1;    
    dataFormat.mBytesPerFrame = four_bytes_per_float;       
    dataFormat.mChannelsPerFrame = 1;   
    dataFormat.mBitsPerChannel = four_bytes_per_float * eight_bits_per_byte;
}

// - - - - - - - - - - - - - - - - -

- (void) setupAudioQueue
{
    currentPacket = 0;

    OSStatus status;

    status = AudioQueueNewInput(& dataFormat,
                                AudioInputCallback,
                                self,
                                CFRunLoopGetCurrent(),
                                kCFRunLoopCommonModes,
                                0,
                                & queue);

    for(int i = 0; i < nBuffers; i++)
    {
        status = AudioQueueAllocateBuffer(queue,
                                          bufLen, 
                                          & audioBuffer[i]);

        status = AudioQueueEnqueueBuffer(queue,
                                         audioBuffer[i], 0, NULL);
    }

    status = AudioQueueFlush (queue);

    printf("Status: %d", (int) status);
}

// - - - - - - - - - - - - - - - - -

- (void) start
{
    OSStatus status = AudioQueueStart(queue, NULL);

    printf("Status: %d", (int) status);
}

// - - - - - - - - - - - - - - -

- (void) stop
{
    AudioQueueStop(queue, true);

    for(int i = 0; i < nBuffers; i++)
        AudioQueueFreeBuffer(queue, audioBuffer[i]);

    AudioQueueDispose(queue, true);
}

// - - - - - - - - - -

- (void) dealloc
{
    [self stop];

    free (audioBuffer);

    [super dealloc];
}


@end

// = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = 

void AudioInputCallback(
                        void                    * inUserData, 
                        AudioQueueRef           inAQ, 
                        AudioQueueBufferRef     inBuffer, 
                        const AudioTimeStamp    * inStartTime, 
                        UInt32                  inNumberPacketDescriptions, 
                        const AudioStreamPacketDescription * inPacketDescs
                        )
{
    MicRecord * x = (MicRecord *) inUserData;

    //if(inNumberPacketDescriptions == 0 && recordState->dataFormat.mBytesPerPacket != 0)
    //{
    //    inNumberPacketDescriptions = inBuffer->mAudioDataByteSize / recordState->dataFormat.mBytesPerPacket;
    //}

    if (0)
        printf("Handling buffer %d\n", (int) x->currentPacket);

    int step = x->bufLen;

    if (inBuffer->mAudioDataBytesCapacity != step)
    {
        printf("---");
    }

    static int k = -1;
    k++;
    static float lastVal = 0;
    static int count = 0;
    if (k < 32) {
        if (k == 0)
            printf("\nfloat buf[32*%d=%d] = {", step, 32*step);
        float * in_buf = (float *) inBuffer->mAudioData;
        printf("\n ~\nPACKET\n");
        for (int i = 0; i < step; i++)
        {
            /*
            if (fabs(in_buf[i]) < .0001 && fabs(lastVal) > .0001)
            {
                printf("%d Nonzeros\n",count);
                count = 0;
            }
            if (fabs(in_buf[i]) > .0001 && fabs(lastVal) < .0001)
            {
                printf("%d Zeros\n",count);
                count = 0;
            }
            count++;
            lastVal = in_buf[i];*/
            printf("%f,", in_buf[i] );

            if (i % 8 == 0)
                printf("\n");
            //if (count % (8 * 64) == 0)
            //  printf("\n");

            count++;
        }
        if (k == 31)
            printf("}\n");
    }


    // shifty frame data down by 'step' elements 
    // to make room for new data
    // imagine cutting out elts [0] thru [step-1] (ie 'step' of them)
    // first new elt at pos [0] will be [step]
    memmove(& x->fftFrame[0], // dest first
            & x->fftFrame[step], // src
            x->frameSize - step
            );

    memcpy(& x->fftFrame[x->frameSize - step],
           inBuffer->mAudioData,
           step * sizeof(float)
           );

    x->currentPacket += inNumberPacketDescriptions;
    // }

    AudioQueueEnqueueBuffer(x->queue, inBuffer, 0, NULL);

    [x->targ performSelector: x->sel];
}


My first suggestion would be to move any printfs out of the lowest-level callback. If these are slow, it's entirely possible you could be missing a buffer here or there. I don't know if that would show up as the blocks of zeros or spurious samples that you're observing, but it might.

What happens to your queue if you fill it faster than you empty it?

0

精彩评论

暂无评论...
验证码 换一张
取 消

关注公众号