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