2016-02-17 1 views
0

Я занимаюсь интеграцией звука порта с существующим приложением MacOSX. Вот мой код до сих пор:Звук порта, вызывающий громкое ожидание 50% тестов

static int coreAudioCallback(const void *inputBuffer, void *outputBuffer, 
          unsigned long framesPerBuffer, 
          const PaStreamCallbackTimeInfo* timeInfo, 
          PaStreamCallbackFlags statusFlags, 
          void *userData){ 
    /*(V3dAudioListener * pCallingListener = (V3dAudioListener*)userData; 
    Aquila::SampleType *out = (Aquila::SampleType*)outputBuffer; 
    pCallingListener->updateEQVals(out, framesPerBuffer);*/ 

    if (statusFlags & paInputOverflow) { 
     printf("Input underflow"); 
    } 

    if(statusFlags & paInputOverflow){ 
     printf("Input overflow"); 
    } 
    if (statusFlags & paOutputUnderflowed) { 
     printf("Output underflowed"); 
    } 
    if (statusFlags & paOutputOverflow) { 
     printf("Output overflow"); 
    } 
    return 0; 
} 

void V3dAudioListener::start(){ 
    PaError error = Pa_Initialize(); 
    if(error != paNoError){ 
     throw std::invalid_argument("Failed to initialize port audio."); 
    }; 

    PaStream *stream; 
    /* Open an audio I/O stream. */ 
    error = Pa_OpenDefaultStream(&stream, 
           0,   /* no input channels */ 
           2,   /* stereo output */ 
           paFloat32, /* 32 bit floating point output */ 
           _sampleRate, 
           _framesPerBuffer,  /* frames per buffer, i.e. the number 
                  of sample frames that PortAudio will 
                  request from the callback. Many apps 
                  may want to use 
                  paFramesPerBufferUnspecified, which 
                  tells PortAudio to pick the best, 
                  possibly changing, buffer size.*/ 
           coreAudioCallback, /* this is your callback function */ 
           this); /*This is a pointer that will be passed to 
             your callback*/ 
    if(error != paNoError){ 
     throw std::invalid_argument("Failed to set up port audio stream."); 
    } 

    error = Pa_StartStream(stream); 
    if(error != paNoError){ 
     throw std::invalid_argument("Failed to start port audio stream."); 
    } 

} 

void V3dAudioListener::stop(){ 
    int error = Pa_Terminate(); 
    if(error != paNoError){ 
     throw std::invalid_argument("Failed to terminate port audio."); 
    }; 
} 

Около половины времени код запускается, он создает громкий жужжащий звук от выходного звукового устройства. Жужжание не начинается и не заканчивается во время каждого прогона, но присутствует или нет от первоначального запуска. Чем это вызвано? Требуется ли минимальная латентность, чтобы избежать переполнения буфера? Размещение сна (1) в обратном вызове, по-видимому, устраняет проблему, если в обратном вызове не выполняется дополнительная работа.

Другая информация: OSX Версия: 10.11.3 _sampleRate: 44100 _framesPerBuffer: 256

ответ

2

Решение заключалось в увеличении значения _framesPerBuffer, которые мы переходим к выходному потоку. Значение 1024 допускало большую задержку в обратном вызове, что предотвращало жужжащий звук.

+0

Очень рад, что я наткнулся на это! Я использовал значение framePerBuffer 256, потому что это то, что было в примере «открытия потока» в документах PortAudio (http://portaudio.com/docs/v19-doxydocs/open_default_stream.html). Это было слишком мало, я просто шумел и не мог понять, почему. –