Непрерывный отбор проб с кольцевым буфером WASAPI - PullRequest
0 голосов
/ 18 ноября 2018

Как использовать WASAPI (или что-то подобное) для непрерывной выборки аудио в кольцевой буфер (безопасный для потоков), чтобы потребительский поток мог читать из этого буфера через заданный интервал?

В настоящее время у нас есть метод .sample(), который возвращает порцию выборок после заданного интервала выборки, но это приводит к дополнительным издержкам из-за выделения памяти и т. Д. Возможно, этот метод можно было бы оптимизировать; Я почти уверен, что мы делаем это неправильно.

std::vector<short> sampler2::sample()
{
    // prepare header
    waveInPrepareHeader(hWaveIn, &WaveInHdr, sizeof(WAVEHDR));

    // insert a wave input buffer
    waveInAddBuffer(hWaveIn, &WaveInHdr, sizeof(WAVEHDR));

    // commence sampling input
    waveInStart(hWaveIn);

    // sleep for the duration of a sample interval
    std::this_thread::sleep_for(milliseconds(SAMPLE_INTERVAL));

    // create vector
    std::vector<short> samplesChunk(&waveIn[0], &waveIn[0] + NUMPTS);

    // return vector
    return samplesChunk;
}

Ссылки на GitHub: sampler2.h & sampler2.cpp

Код очень дерьмовый, и мы понятия не имеем, как правильно использовать WASAPI. Нашей целью было (быстро) создать класс сэмплера, который может использовать интервал сэмплирования> 10 мс.

1 Ответ

0 голосов
/ 19 ноября 2018

В вашем примере используется Waveout API.Вы можете проверить MSDN для справки и использования WASAPI.Вот основное описание использования WASAPI: клиент вызывает методы в интерфейсе IAudioRenderClient для записи данных рендеринга в буфер конечной точки. Чтобы запросить буфер конечной точки определенного размера, клиент вызывает IAudioClient :: Initialize метод.Чтобы получить размер выделенного буфера, который может отличаться от запрошенного размера, клиент вызывает метод IAudioClient :: GetBufferSize .Чтобы переместить поток данных рендеринга через буфер конечной точки, клиент поочередно вызывает метод IAudioRenderClient :: GetBuffer и метод IAudioRenderClient :: ReleaseBuffer .Клиент обращается к данным в буфере конечной точки в виде серии пакетов данных.Вызов GetBuffer извлекает следующий пакет, чтобы клиент мог заполнить его данными рендеринга.После записи данных в пакет клиент вызывает ReleaseBuffer для добавления завершенного пакета в очередь рендеринга.Существует также этот Microsoft C ++ WASAPI пример .

...