2016-11-14 2 views
1

sample code of WASAPI capture on MSDN, петля до возвращения GetNextPacketSize 0. Я просто хочу понять, когда это произойдет:Когда WASAPI GetNextPacketSize возвращает 0

  1. Будет ли это произойдет, если там тишина зарегистрирована на микрофоне? (В этом случае он будет вращаться бесконечно, если я продолжаю шуметь на микрофоне?)
  2. Это зависит от некоторой фундаментальной концепции захвата звука, которую я пропускаю (я совершенно новичок в аудио API :)).

ответ

1

API помогает определить размер буфера данных, который должен быть захвачен, чтобы API-клиент не нуждался в угадывании или распределении избыточного буфера и т. Д. API будет возвращать ноль, когда нет данных для захвата (не один кадр). Это может произойти в текущем сеансе аудиозахвата, когда/если вы вызываете API слишком рано, и вызывающий абонент, как ожидается, попробует еще раз позже, так как новые данные все равно могут быть сгенерированы.

В некоторых условиях нулевой возврат может указывать на конец потока. В частности, если вы снимаете с устройства loopback и нет активных сеансов воспроизведения, которые могут генерировать данные для доставки loopback, API захвата может продолжать предоставлять данные до тех пор, пока не появится новый сеанс воспроизведения.

Цикл кода примера проверяет нулевой размер пакета в сочетании с вызовом Sleep. Таким образом, цикл ожидает, что по меньшей мере некоторые данные будут генерироваться во время сна, а в обычных условиях непрерывной генерации аудиоданных нет нулевой длины, возвращаемой при каждом первом вызове во внешнем цикле. Внутренний цикл пытается считать как можно большее количество непустых буферов до тех пор, пока нуль не покажет, что все данные, которые были готовы к доставке, уже были возвращены клиенту.

Наружный цикл продолжает работать до тех пор, пока раковина не пройдет событие конца захвата через переменную bDone. Здесь есть уловка, что какая-то внутренняя петля может катиться, не врываясь во внешний цикл - в соответствии с образцом кода - и захват некорректно остановлен. Образец предполагает, что приемник обрабатывает данные достаточно быстро, так что внутренний цикл может обрабатывать все доступные в данный момент данные и выходить из него, чтобы достичь вызова Sleep. То есть, вызовы WASAPI не являются блокирующими и в предположении, что эти циклы работают довольно быстро, идея состоит в том, что аудиоданные обрабатываются быстрее, чем они захвачены, и цикл тратит большую часть времени потока на вызов Sleep. Возможно, это не лучший пример кода для начинающих. Вы можете улучшить это, проверив bDone во внутреннем цикле, чтобы сделать его более надежным.

+0

Спасибо, Роман за разъяснения. Теперь это ясно для меня. Но есть еще одна путаница для сценария «stop stop» в примере кода. Есть 2 цикла (внешний цикл while, который проверяет, чтобы остановить или нет и внутренний цикл while, который проверяет размер пакета). Если pMySink возвращает «bDone» как истинный, и пакеты все еще идут, запись будет продолжаться, даже если pMySink сигнализируется о прекращении. С другой стороны, если мы будем проверять bDone во внутреннем цикле, тогда есть возможность потерянных пакетов, если в потоке еще есть данные. – Nitin

+0

Я добавил выше. Предполагается, что 'bDone' является сигналом« окончания захвата », означающим, что приемник не нуждается в новых данных. По-видимому, в целом могут появляться новые данные, особенно. если источник жив. Образец не имеет в виду, что вам может потребоваться продолжить захват после этого с точки, указанной вами с помощью 'bDone'. –

+0

Спасибо, теперь я это понимаю. На самом деле я делаю приложение для захвата звука, и пользователь может нажать кнопки записи и остановки, чтобы начать и остановить запись. Запись (захват WASAPI) выполняется в отдельной не-ui-потоке, и пользовательский интерфейс будет сигнализировать о прекращении записи, поэтому я намерен не захватывать дополнительные, но также не иметь никаких отключений. Ваше объяснение освобождает меня от путаницы, и теперь я буду точно настраивать свою реализацию. – Nitin

Смежные вопросы