2011-01-11 3 views
0

Я входе в поток поплавков, поступающих от микрофона (должно быть молчание)IOS AudioQueues: глюки в аудио флоат-поток

У меня есть настройки аудио очереди с размером буфера 256 поплавков

Типичным буфер выглядит следующим образом:

ПАКЕТ 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.045593,0.052032,0.0453 80,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.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, ~

Я не могу понять, почему я, кажется, имеют случайные пучки нулей во входном сигнале. Кажется, что-то прерывисто.

Сначала я подумал, что у меня был правый и левый каналы, а правый канал всегда записывал ноль. Но, просматривая мой код, я четко определил его для одного канала.

Тогда я подумал, что, возможно, это только места молчания в сигнале.Но это не имеет смысла. Если бы у меня всего было дюжина нулей, то, вероятно, я бы ожидал очень маленьких цифр, например .000007 .000014, но отличные от нуля цифры, похоже, около отметки 0,01.

Я только что попробовал переключить свой аудиовход на внешний USB-микрофон, что улучшает разрешение. Ненулевые числа теперь, кажется, вокруг отметки .001. но все же есть заметный разрыв ...

Интересно, выполняется ли какой-либо расчет на чипе, который округляет до 0. Если это так, можно ли его откалибровать? Что происходит?

Вторая действительно странная проблема, которую я замечаю, - это значения изгоев.

Вот пример пакета, который содержит некоторые из этих значений (на этот раз с помощью микрофона USB, вы можете увидеть, как разрешение улучшается):

~ ПАКЕТ -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, - 00007, -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,00 0000,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,

Это сбивает с толку меня. появление этих сбоев невелико; менее одного в 10 кадрах.

Означает ли это, что мне нужно предварительно обработать мой аудиопоток?

В прошлый раз, когда я использовал аудиоустройства, я никогда этого не делал. Я просто передал звук прямо в рутину определения высоты тона. И это не имело проблем. Так интересно, если я получаю глюки там хорошо ..

я глюки как с встроенным микрофоном MacBook и внешним микрофоном USB

Вот мой код:

// 
// 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]; 
} 
+0

Я голосую, чтобы закрыть это, я обнаружил, что проблема была моей собственной дрянной кодировкой. У меня был malloc'd (n), а не n * sizeof (float), поэтому он читал случайный мусор. –

+0

Вы также можете удалить этот вопрос, который является быстрым и легким. Рад, что вы нашли проблему. – mtrw

ответ

1

Моим первым предложение было бы перемещение любого printf s из обратного вызова самого низкого уровня. Если они медленные, вполне возможно, что вам может не хватать буфер здесь или там. Я не знаю, будет ли это отображаться как блоки нулей или ложных выборок, которые вы наблюдаете, но это возможно.

Что произойдет с вашей очередью, если вы заполните ее быстрее, чем вы ее опорожнили?

+0

Это действительно хорошее предложение, и я его реализовал. Благодарю. К сожалению, он все еще не взламывает проблему. Я заметил, что сумасшедшие значения всегда встречаются в середине кадра 12. Мне нужно будет более тщательно изучить код ... –

+0

Нули всегда в кадре 12 или ложные образцы находятся в кадре 12? Вы получаете либо нули, либо мусор? Не изменилось ли движение 'printf' вообще? – mtrw