Примечание.
Для доступа к этой странице требуется авторизация. Вы можете попробовать войти или изменить каталоги.
Для доступа к этой странице требуется авторизация. Вы можете попробовать изменить каталоги.
Метод Initialize инициализирует аудиопоток.
Синтаксис
HRESULT Initialize(
[in] AUDCLNT_SHAREMODE ShareMode,
[in] DWORD StreamFlags,
[in] REFERENCE_TIME hnsBufferDuration,
[in] REFERENCE_TIME hnsPeriodicity,
[in] const WAVEFORMATEX *pFormat,
[in] LPCGUID AudioSessionGuid
);
Параметры
[in] ShareMode
Режим общего доступа для подключения. С помощью этого параметра клиент сообщает обработчику аудиоданных о том, нужно ли предоставлять общий доступ к устройству конечной точки аудио с другими клиентами. Клиент должен задать для этого параметра одно из следующих значений перечисления AUDCLNT_SHAREMODE:
AUDCLNT_SHAREMODE_EXCLUSIVE
AUDCLNT_SHAREMODE_SHARED
[in] StreamFlags
Флаги для управления созданием потока. Клиент должен задать для этого параметра значение 0 или побитовое значение OR одного или нескольких констант AUDCLNT_STREAMFLAGS_XXX или констант AUDCLNT_SESSIONFLAGS_XXX.
[in] hnsBufferDuration
Емкость буфера в качестве значения времени. Этот параметр имеет тип REFERENCE_TIME и выражается в 100 единицах nanosecond. Этот параметр содержит размер буфера, который вызывающий запрашивает буфер, к которому звуковое приложение будет совместно использовать звуковой модуль (в общем режиме) или с устройством конечной точки (в монопольном режиме). Если вызов выполнен успешно, метод выделяет буфер, который является наименее большим. Дополнительные сведения о REFERENCE_TIME см. в документации по пакету SDK для Windows. Дополнительные сведения о требованиях к буферизации см. в примечаниях.
[in] hnsPeriodicity
Период устройства. Этот параметр может быть ненулевой только в монопольном режиме. В общем режиме всегда задайте для этого параметра значение 0. В монопольном режиме этот параметр задает запрошенный период планирования для последовательных доступа к буферу устройства аудио конечной точки. Если запрошенный период устройства находится за пределами диапазона, заданного минимальным периодом устройства и максимальным периодом системы, метод зацепляет период с этим диапазоном. Если этот параметр равен 0, метод задает период устройства значением по умолчанию. Чтобы получить период устройства по умолчанию, вызовите метод IAudioClient::GetDevicePeriod . Если флаг потока AUDCLNT_STREAMFLAGS_EVENTCALLBACK задан и AUDCLNT_SHAREMODE_EXCLUSIVE задан как ShareMode, то hnsPeriodicity должен быть ненулевой и равен hnsBufferDuration.
[in] pFormat
Указатель на дескриптор формата. Этот параметр должен указывать на допустимый дескриптор формата типа WAVEFORMATEX (или WAVEFORMATEXTENSIBLE). Дополнительные сведения см. в разделе "Примечания".
[in] AudioSessionGuid
Указатель на GUID сеанса. Этот параметр указывает на значение GUID, определяющее звуковой сеанс, к которому принадлежит поток. Если GUID идентифицирует сеанс, который был открыт ранее, метод добавляет поток в этот сеанс. Если GUID не определяет существующий сеанс, метод открывает новый сеанс и добавляет поток в этот сеанс. Поток остается членом одного сеанса в течение своего существования. Задание этого параметра значение NULL эквивалентно передаче указателя на значение GUID_NULL.
Возвращаемое значение
Если метод выполнен успешно, он возвращает S_OK. В случае сбоя возможные коды возврата включаются, но не ограничиваются значениями, приведенными в следующей таблице.
| Код возврата | Description |
|---|---|
|
Объект IAudioClient уже инициализирован. |
|
Флаг AUDCLNT_STREAMFLAGS_LOOPBACK задан, но конечное устройство является устройством записи, а не устройством отрисовки. |
|
Заметка Применяется к Windows 7 и более поздним версиям.
|
|
Заметка Применяется к Windows 7 и более поздним версиям.
|
|
Указывает, что длительность передачи процесса превысила максимальное использование ЦП. Звуковой модуль отслеживает использование ЦП, сохраняя время ожидания процесса, превышающее максимальное использование ЦП. Максимальное использование ЦП вычисляется как процент периодичности двигателя. Процентное значение — это значение регулирования ЦП системы (в диапазоне от 10% и 90%). Если это значение не найдено, то значение по умолчанию 40% используется для вычисления максимального использования ЦП. |
|
Устройство конечной точки звука было отключено, или звуковое оборудование или связанные аппаратные ресурсы были перенастроены, отключены, удалены или недоступны для использования. |
|
Ресурсы потока были недействительны. Эта ошибка может возникать по следующим причинам: — поток приостановлен. — Поток эксклюзивной или разгрузки отключен. — Упаковаемое приложение с монопольным режимом или потоком разгрузки. — Поток "защищенных выходных данных" закрыт. |
|
Устройство конечной точки уже используется. Либо устройство используется в монопольном режиме, либо устройство используется в общем режиме, и вызывающий попросил использовать устройство в монопольном режиме. |
|
Метод не удалось создать конечную точку звука для отрисовки или устройства записи. Это может произойти, если устройство аудио конечной точки было отключено, или звуковое оборудование или связанные аппаратные ресурсы были перенастроены, отключены, удалены или недоступны для использования. |
|
Заметка Применяется к Windows 7 и более поздним версиям.
|
|
Звуковой модуль (общий режим) или устройство конечной точки аудио (монопольный режим) не поддерживает указанный формат. |
|
Вызывающий объект запрашивает использование устройства конечной точки в монопольном режиме, но пользователь отключил использование монопольного режима устройства. |
|
Флаг AUDCLNT_STREAMFLAGS_EVENTCALLBACK задан, но параметры hnsBufferDuration и hnsPeriodicity не равны. |
|
Звуковая служба Windows не запущена. |
|
Параметр pFormat имеет значение NULL. |
|
Параметр pFormat указывает на недопустимое описание формата; или флаг AUDCLNT_STREAMFLAGS_LOOPBACK задан, но ShareMode не равен AUDCLNT_SHAREMODE_SHARED; или флаг AUDCLNT_STREAMFLAGS_CROSSPROCESS задан, но ShareMode равен AUDCLNT_SHAREMODE_EXCLUSIVE.
Перед вызовом SetClientProperties была выполнена недопустимая категория для потоков аудио и отрисовки. |
|
Нехватка памяти. |
Замечания
После активации интерфейса IAudioClient на устройстве конечной точки аудио клиент должен успешно вызвать инициализацию аудиопотока только один раз, чтобы инициализировать аудиопоток между клиентом и устройством. Клиент может напрямую подключаться к звуковому оборудованию (монопольный режим) или косвенно через звуковой механизм (общий режим). В вызове Initialize клиент указывает формат звуковых данных, размер буфера и звуковой сеанс для потока.
Если поток инициализирован для управления событиями и в общем режиме, ShareMode имеет значение AUDCLNT_SHAREMODE_SHARED, а один из установленных флагов потока включает AUDCLNT_STREAMFLAGS_EVENTCALLBACK. Для такого потока связанное приложение также должно получить дескриптор, выполнив вызов IAudioClient::SetEventHandle. Когда время отставать от потока, подсистема аудио может использовать дескриптор для освобождения объектов потока. Сбой вызова IAudioClient::SetEventHandle перед освобождением объектов потока может вызвать задержку в течение нескольких секунд (период ожидания), пока звуковой модуль ожидает доступного дескриптора. После истечения срока ожидания звуковой подсистемы затем освобождает объекты потока.
Происходит ли попытка создания потока в монопольном режиме, зависит от нескольких факторов, в том числе от доступности устройства и управляемых пользователем параметров, которые управляют операцией в монопольном режиме устройства. Дополнительные сведения см. в разделе Exclusive-Mode Streams.
Объект IAudioClient поддерживает ровно одно подключение к звуковому подсистеме или звуковому оборудованию. Это соединение длится в течение всего времени существования объекта IAudioClient .
Клиент должен вызывать следующие методы только после вызова инициализации:
- IAudioClient::GetBufferSize
- IAudioClient::GetCurrentPadding
- IAudioClient::GetService
- IAudioClient::GetStreamLatency
- IAudioClient::Reset
- IAudioClient::SetEventHandle
- IAudioClient::Start
- IAudioClient::Stop
Перед вызовом инициализации для настройки подключения к общему режиму или монопольного режима клиент может вызвать метод IAudioClient::IsFormatSupported , чтобы определить, поддерживает ли звуковой модуль или устройство конечной точки звука определенный формат в этом режиме. Перед открытием подключения к общему режиму клиент может получить формат смешивания звукового модуля, вызвав метод IAudioClient::GetMixFormat .
Буфер конечной точки, общий для клиента и звукового модуля, должен быть достаточно большим, чтобы предотвратить сбои в звуковом потоке между обработкой проходит клиент и звуковой подсистемой. Для конечной точки отрисовки поток клиента периодически записывает данные в буфер, а поток звукового модуля периодически считывает данные из буфера. Для конечной точки записи поток обработчика периодически записывает в буфер, а клиентский поток периодически считывает из буфера. В любом случае, если периоды клиентского потока и потока подсистемы не равны, буфер должен быть достаточно большим, чтобы вместить дольше двух периодов, не позволяя возникать сбои.
Клиент задает размер буфера через параметр hnsBufferDuration . Клиент отвечает за запрос буфера, который достаточно велик, чтобы убедиться, что сбои не могут возникать между периодическими процессами обработки, которые он выполняет в буфере. Аналогичным образом, метод Initialize гарантирует, что буфер никогда не меньше минимального размера буфера, необходимого для обеспечения того, чтобы сбои не выполнялись между периодическими процессами обработки, которые выполняет поток подсистемы в буфере. Если клиент запрашивает размер буфера, который меньше минимального требуемого размера буфера звукового модуля, метод задает размер буфера для этого минимального размера буфера, а не для размера буфера, запрошенного клиентом.
Если клиент запрашивает размер буфера (через параметр hnsBufferDuration ), который не является целым числом звуковых кадров, метод округляет запрошенный размер буфера до следующего целого числа кадров.
После вызова Initialize клиент должен вызвать метод IAudioClient::GetBufferSize , чтобы получить точный размер буфера конечной точки. Во время каждого прохождения обработки клиенту потребуется фактический размер буфера, чтобы вычислить объем данных для передачи в буфер или из нее. Клиент вызывает метод IAudioClient::GetCurrentPadding , чтобы определить, сколько данных в буфере доступно для обработки.
Чтобы обеспечить минимальную задержку потока между клиентским приложением и устройством конечной точки аудио, поток клиента должен выполняться в тот же период, что и поток звукового модуля. Период потока подсистемы фиксирован и не может контролироваться клиентом. Что делает период клиента меньше периода ядра ненужным образом увеличивает нагрузку клиентского потока на процессор, не увеличивая задержку или уменьшая размер буфера. Чтобы определить период потока подсистемы, клиент может вызвать метод IAudioClient::GetDevicePeriod . Чтобы задать буфер минимальному размеру, требуемому потоком подсистемы, клиент должен вызвать инициализацию с параметром hnsBufferDuration значение 0. После вызова инициализации клиент может получить размер результирующего буфера, вызвав IAudioClient::GetBufferSize.
Клиент имеет возможность запрашивать размер буфера, который больше, чем то, что строго необходимо, чтобы сделать сбои времени редкими или несуществующими. Увеличение размера буфера не обязательно увеличивает задержку потока. Для потока отрисовки задержка через буфер определяется исключительно разделением указателя записи клиента и указателем чтения подсистемы. Для потока записи задержка через буфер определяется исключительно разделением указателя записи модуля и указателем чтения клиента.
Флаг обратного цикла (AUDCLNT_STREAMFLAGS_LOOPBACK) включает функцию обратного цикла звука. Клиент может включить обратный цикл звука только в конечной точке отрисовки с потоком общего режима. Звуковая обратная связь предоставляется в основном для поддержки акустической отмены эхо(AEC).
Для клиента AEC требуется как конечная точка отрисовки, так и возможность записи выходного потока из звукового модуля. Выходной поток подсистемы — это глобальный набор, который звуковое устройство воспроизводит через динамики. Если включена обратная связь звука, клиент может открыть буфер записи для глобального звукового набора, вызвав метод IAudioClient::GetService для получения интерфейса IAudioCaptureClient в объекте потока отрисовки. Если звуковая обратная связь не включена, попытка открыть буфер записи в потоке отрисовки завершится ошибкой. Данные обратного цикла в буфере записи приведены в формате устройства, который клиент может получить, запрашивая свойство PKEY_AudioEngine_DeviceFormat устройства.
В версиях Windows до Windows 10 клиент записи в режиме извлечения не получит никаких событий, когда поток инициализирован с помощью буферизации на основе событий (AUDCLNT_STREAMFLAGS_EVENTCALLBACK) и включен цикл обратной передачи (AUDCLNT_STREAMFLAGS_LOOPBACK). Если поток открыт с этой конфигурацией, вызов инициализации завершается успешно, но соответствующие события не вызываются для уведомления клиента записи каждый раз, когда буфер становится готов к обработке. Чтобы обойти эту проблему, инициализировать поток отрисовки в режиме на основе событий. Каждый раз, когда клиент получает событие для потока отрисовки, он должен сигнализировать клиенту записи, чтобы запустить поток записи, который считывает следующий набор примеров из буфера конечной точки записи. По состоянию на Windows 10 соответствующие дескрипторы событий теперь задаются для потоков с поддержкой цикла, которые являются активными.
Обратите внимание, что все потоки должны быть открыты в режиме общего доступа, так как потоки монопольного режима не могут работать в режиме обратного цикла. Дополнительные сведения об обратном цикле звука см. в разделе "Запись loopback".
Флаг AUDCLNT_STREAMFLAGS_EVENTCALLBACK указывает, что обработка звукового буфера клиентом будет управляться событием. WASAPI поддерживает буферизацию на основе событий, чтобы обеспечить низкую задержку обработки потоков общего и монопольного режима.
Первоначальный выпуск Windows Vista поддерживает буферизацию на основе событий (то есть использование флага AUDCLNT_STREAMFLAGS_EVENTCALLBACK) только для отрисовки потоков.
В первоначальном выпуске Windows Vista для потоков записи флаг AUDCLNT_STREAMFLAGS_EVENTCALLBACK поддерживается только в общем режиме. Установка этого флага не влияет на потоки записи в монопольном режиме. То есть, хотя приложение указывает этот флаг в монопольном режиме через вызов Initialize , приложение не получит никаких событий, которые обычно требуются для записи звукового потока. В выпуске windows Vista с пакетом обновления 1 этот флаг работает в общем режиме и монопольном режиме; Приложение может задать этот флаг, чтобы включить буферизацию событий для потоков записи. Дополнительные сведения о захвате аудиопотока см. в разделе "Запись потока".
Чтобы включить буферизацию на основе событий, клиент должен предоставить дескриптор событий системе. После вызова вызоваIAudioClient::Start для запуска потока клиент должен вызвать метод IAudioClient::SetEventHandle , чтобы задать дескриптор события. Во время выполнения потока система периодически сигнализирует о событии, указывая клиенту, что звуковые данные доступны для обработки. Между обработкой поток клиента ожидает дескриптора событий, вызвав функцию синхронизации, например WaitForSingleObject. Дополнительные сведения о функциях синхронизации см. в документации по пакету SDK для Windows.
Для потока общего режима, использующего буферизацию на основе событий, вызывающий объект должен задать значение hnsPeriodicity и hnsBufferDuration равным 0. Метод Initialize определяет, насколько большой буфер выделяется на основе периода планирования звукового модуля. Хотя поток обработки буфера клиента управляется событиями, базовый процесс управления буферами, как описано ранее, не учитывается. Каждый раз, когда поток просыпается, он должен вызывать IAudioClient::GetCurrentPadding , чтобы определить объем данных для записи в буфер отрисовки или чтения из буфера записи. В отличие от двух буферов, выделенных методом Initialize для потока монопольного режима, использующего буферизацию на основе событий, для потока общего режима требуется один буфер.
Для потока монопольного режима, использующего буферизацию на основе событий, вызывающий объект должен указывать ненулевое значение для hnsPeriodicity и hnsBufferDuration, а значения этих двух параметров должны быть равными. Метод Initialize выделяет два буфера для потока. Каждый буфер равен длительности значению параметра hnsBufferDuration . После вызова инициализации потока отрисовки вызывающий объект должен заполнить первый из двух буферов перед запуском потока. Для потока записи буферы изначально пусты, и вызывающий объект должен предположить, что каждый буфер остается пустым, пока событие для этого буфера не будет сигнализировать. Во время выполнения потока система также отправляет один буфер или другой клиенту— эта форма двойного буферизации называется "ping-ponging". Каждый раз, когда клиент получает буфер из системы (который система указывает, сигнализируя о событии), клиент должен обработать весь буфер. Например, если клиент запрашивает размер пакета из метода IAudioRenderClient::GetBuffer , который не соответствует размеру буфера, метод завершается ошибкой. Вызовы метода IAudioClient::GetCurrentPadding не нужны, так как размер пакета должен всегда совпадать с размером буфера. В отличие от режимов буферизации, рассмотренных ранее, задержка для потока на основе событий, монопольного режима зависит непосредственно от размера буфера.
Как описано в аудиосеансах, поведение по умолчанию для сеанса, содержащего потоки отрисовки, заключается в том, что его том и параметры отключения сохраняются во время перезапуска приложения. Флаг AUDCLNT_STREAMFLAGS_NOPERSIST переопределяет поведение по умолчанию и делает параметры неперсистентными. Этот флаг не влияет на сеансы, содержащие потоки записи, — параметры для этих сеансов никогда не сохраняются. Кроме того, параметры сеанса, содержащего поток обратного цикла (поток, инициализируемый флагом AUDCLNT_STREAMFLAGS_LOOPBACK), не являются постоянными.
Только сеанс, который подключается к устройству конечной точки отрисовки, может иметь постоянный том и отключить параметры. Первый поток, добавляемый в сеанс, определяет, являются ли параметры сеанса постоянными. Таким образом, если флаг AUDCLNT_STREAMFLAGS_NOPERSIST или AUDCLNT_STREAMFLAGS_LOOPBACK задан во время инициализации первого потока, параметры сеанса не сохраняются. В противном случае они постоянны. Их сохраняемость не влияет на дополнительные потоки, которые впоследствии могут быть добавлены или удалены во время существования объекта сеанса.
После успешного инициализации экземпляра интерфейса IAudioClient последующий вызов Initialize для инициализации того же экземпляра интерфейса завершится ошибкой и возвратом кода ошибки E_ALREADY_INITIALIZED.
Если начальный вызов инициализации завершается ошибкой, последующие вызовы инициализации могут завершиться ошибкой и вернуть код ошибки E_ALREADY_INITIALIZED, даже если интерфейс не инициализирован. Если это происходит, отпустите интерфейс IAudioClient и получите новый интерфейс IAudioClient из API MMDevice перед вызовом инициализации еще раз.
Примеры кода, вызывающие метод Initialize , см. в следующих разделах:
Начиная с Windows 7 инициализация может возвращать AUDCLNT_E_BUFFER_SIZE_NOT_ALIGNED для отрисовки или устройства записи. Это означает, что размер буфера, указанный вызывающим объектом в параметре hnsBufferDuration , не выравнивается. Этот код ошибки возвращается только в том случае, если вызывающий запрос запрашивает поток монопольного режима (AUDCLNT_SHAREMODE_EXCLUSIVE) и буферизацию на основе событий (AUDCLNT_STREAMFLAGS_EVENTCALLBACK).Если инициализация возвращает AUDCLNT_E_BUFFER_SIZE_NOT_ALIGNED, вызывающий объект должен снова вызвать инициализировать и указать выровненный размер буфера. Выполните следующие действия.
- Вызовите IAudioClient::GetBufferSize и получите следующий максимальный размер буфера (в кадрах).
- Вызовите IAudioClient::Release, чтобы освободить звуковой клиент, используемый в предыдущем вызове, который вернул AUDCLNT_E_BUFFER_SIZE_NOT_ALIGNED.
- Вычислите выровненный размер буфера в 100-наносекундах (hns). Размер буфера равен
(REFERENCE_TIME)((10000.0 * 1000 / WAVEFORMATEX.nSamplesPerSecond * nFrames) + 0.5). В этой формуле используется размер буфера,nFramesполученный GetBufferSize. - Вызовите метод IMMDevice::Activate с параметром iid , заданным как REFIID IID_IAudioClient, чтобы создать новый звуковой клиент.
- Снова вызовите инициализацию в созданном звуковом клиенте и укажите новый размер буфера и периодичность.
Начиная с Windows 10, аппаратные разгрузки аудиопотоков должны быть управляемыми событиями. Это означает, что если вызвать IAudioClient2::SetClientProperties и задать параметр bIsOffload для AudioClientProperties значение TRUE, необходимо указать флаг AUDCLNT_STREAMFLAGS_EVENTCALLBACK в параметре StreamFlags значение IAudioClient::Initialize.
Примеры
В следующем примере кода показано, как реагировать на код возврата AUDCLNT_E_BUFFER_SIZE_NOT_ALIGNED .
#define REFTIMES_PER_SEC 10000000
HRESULT CreateAudioClient(IMMDevice* pDevice, IAudioClient** ppAudioClient)
{
if (!pDevice)
{
return E_INVALIDARG;
}
if (!ppAudioClient)
{
return E_POINTER;
}
HRESULT hr = S_OK;
WAVEFORMATEX *pwfx = NULL;
REFERENCE_TIME hnsRequestedDuration = REFTIMES_PER_SEC;
UINT32 nFrames = 0;
IAudioClient *pAudioClient = NULL;
// Get the audio client.
CHECK_HR( hr = pDevice->Activate(
__uuidof(IAudioClient),
CLSCTX_ALL,
NULL,
(void**)&pAudioClient));
// Get the device format.
CHECK_HR( hr = pAudioClient->GetMixFormat(&pwfx));
// Open the stream and associate it with an audio session.
hr = pAudioClient->Initialize(
AUDCLNT_SHAREMODE_EXCLUSIVE,
AUDCLNT_STREAMFLAGS_EVENTCALLBACK,
hnsRequestedDuration,
hnsRequestedDuration,
pwfx,
NULL);
// If the requested buffer size is not aligned...
if (hr == AUDCLNT_E_BUFFER_SIZE_NOT_ALIGNED)
{
// Get the next aligned frame.
CHECK_HR( hr = pAudioClient->GetBufferSize(&nFrames));
hnsRequestedDuration = (REFERENCE_TIME)
((10000.0 * 1000 / pwfx->nSamplesPerSec * nFrames) + 0.5);
// Release the previous allocations.
SAFE_RELEASE(pAudioClient);
CoTaskMemFree(pwfx);
// Create a new audio client.
CHECK_HR( hr = pDevice->Activate(
__uuidof(IAudioClient),
CLSCTX_ALL,
NULL,
(void**)&pAudioClient));
// Get the device format.
CHECK_HR( hr = pAudioClient->GetMixFormat(&pwfx));
// Open the stream and associate it with an audio session.
CHECK_HR( hr = pAudioClient->Initialize(
AUDCLNT_SHAREMODE_EXCLUSIVE,
AUDCLNT_STREAMFLAGS_EVENTCALLBACK,
hnsRequestedDuration,
hnsRequestedDuration,
pwfx,
NULL));
}
else
{
CHECK_HR (hr);
}
// Return to the caller.
*(ppAudioClient) = pAudioClient;
(*ppAudioClient)->AddRef();
done:
// Clean up.
CoTaskMemFree(pwfx);
SAFE_RELEASE(pAudioClient);
return hr;
}
Требования
| Требование | Ценность |
|---|---|
| целевая платформа | Windows |
| Header | audioclient.h |