Condividi tramite


Metodo IAudioClient::Initialize (audioclient.h)

Il metodo Initialize inizializza il flusso audio.

Sintassi

HRESULT Initialize(
  [in] AUDCLNT_SHAREMODE  ShareMode,
  [in] DWORD              StreamFlags,
  [in] REFERENCE_TIME     hnsBufferDuration,
  [in] REFERENCE_TIME     hnsPeriodicity,
  [in] const WAVEFORMATEX *pFormat,
  [in] LPCGUID            AudioSessionGuid
);

Parametri

[in] ShareMode

Modalità di condivisione per la connessione. Tramite questo parametro, il client indica al motore audio se vuole condividere il dispositivo dell'endpoint audio con altri client. Il client deve impostare questo parametro su uno dei valori di enumerazione seguenti AUDCLNT_SHAREMODE :

AUDCLNT_SHAREMODE_EXCLUSIVE

AUDCLNT_SHAREMODE_SHARED

[in] StreamFlags

Flag per controllare la creazione del flusso. Il client deve impostare questo parametro su 0 o sull'OR bit per bit di una o più costanti AUDCLNT_STREAMFLAGS_XXX o costanti AUDCLNT_SESSIONFLAGS_XXX.

[in] hnsBufferDuration

Capacità del buffer come valore di tempo. Questo parametro è di tipo REFERENCE_TIME ed è espresso in 100-nanosecondi. Questo parametro contiene le dimensioni del buffer richieste dal chiamante per il buffer che l'applicazione audio condividerà con il motore audio (in modalità condivisa) o con il dispositivo endpoint (in modalità esclusiva). Se la chiamata ha esito positivo, il metodo alloca un buffer meno grande. Per altre informazioni su REFERENCE_TIME, vedere la documentazione di Windows SDK. Per altre informazioni sui requisiti di buffering, vedere Osservazioni.

[in] hnsPeriodicity

Periodo del dispositivo. Questo parametro può essere diverso da zero solo in modalità esclusiva. In modalità condivisa impostare sempre questo parametro su 0. In modalità esclusiva, questo parametro specifica il periodo di pianificazione richiesto per gli accessi del buffer successivi dal dispositivo dell'endpoint audio. Se il periodo del dispositivo richiesto si trova all'esterno dell'intervallo impostato dal periodo minimo del dispositivo e dal periodo massimo del sistema, il metodo blocca il periodo a tale intervallo. Se questo parametro è 0, il metodo imposta il periodo del dispositivo sul valore predefinito. Per ottenere il periodo di dispositivo predefinito, chiamare il metodo IAudioClient::GetDevicePeriod . Se il flag di flusso AUDCLNT_STREAMFLAGS_EVENTCALLBACK è impostato e AUDCLNT_SHAREMODE_EXCLUSIVE è impostato come ShareMode, hnsPeriodicity deve essere diverso da zero e uguale a hnsBufferDuration.

[in] pFormat

Puntatore a un descrittore di formato. Questo parametro deve puntare a un descrittore di formato valido di tipo WAVEFORMATEX (o WAVEFORMATEXTENSIBLE). Per altre informazioni, vedere la sezione Osservazioni.

[in] AudioSessionGuid

Puntatore a un GUID di sessione. Questo parametro punta a un valore GUID che identifica la sessione audio a cui appartiene il flusso. Se il GUID identifica una sessione aperta in precedenza, il metodo aggiunge il flusso a tale sessione. Se il GUID non identifica una sessione esistente, il metodo apre una nuova sessione e aggiunge il flusso a tale sessione. Il flusso rimane un membro della stessa sessione per la sua durata. L'impostazione di questo parametro su NULL equivale a passare un puntatore a un valore GUID_NULL.

Valore restituito

Se il metodo ha esito positivo, viene restituito S_OK. Se ha esito negativo, i codici restituiti possibili includono, ma non sono limitati a, i valori visualizzati nella tabella seguente.

Codice restituito Descrizione
AUDCLNT_E_ALREADY_INITIALIZED
L'oggetto IAudioClient è già inizializzato.
AUDCLNT_E_WRONG_ENDPOINT_TYPE
Il flag AUDCLNT_STREAMFLAGS_LOOPBACK è impostato, ma il dispositivo endpoint è un dispositivo di acquisizione, non un dispositivo di rendering.
AUDCLNT_E_BUFFER_SIZE_NOT_ALIGNED
Nota Si applica a Windows 7 e versioni successive.
 
Le dimensioni del buffer richieste non sono allineate. Questo codice può essere restituito per un rendering o un dispositivo di acquisizione se il chiamante ha specificato AUDCLNT_SHAREMODE_EXCLUSIVE e i flag di AUDCLNT_STREAMFLAGS_EVENTCALLBACK. Il chiamante deve chiamare di nuovo Inizializza con le dimensioni del buffer allineate. Per altre informazioni, vedere la sezione Osservazioni.
AUDCLNT_E_BUFFER_SIZE_ERROR
Nota Si applica a Windows 7 e versioni successive.
 
Indica che il valore di durata del buffer richiesto da un client in modalità esclusiva non è compreso nell'intervallo. Il valore di durata richiesto per la modalità pull non deve essere maggiore di 5000 millisecondi; per la modalità push il valore di durata non deve essere maggiore di 2 secondi.
AUDCLNT_E_CPUUSAGE_EXCEEDED
Indica che la durata del passaggio del processo ha superato l'utilizzo massimo della CPU. Il motore audio tiene traccia dell'utilizzo della CPU mantenendo il numero di volte in cui la durata del passaggio del processo supera l'utilizzo massimo della CPU. L'utilizzo massimo della CPU viene calcolato come percentuale della periodicità del motore. Il valore percentuale è il valore della limitazione della CPU del sistema (entro l'intervallo del 10% e del 90%). Se questo valore non viene trovato, viene usato il valore predefinito del 40% per calcolare l'utilizzo massimo della CPU.
AUDCLNT_E_DEVICE_INVALIDATED
Il dispositivo endpoint audio è stato scollegato o l'hardware audio o le risorse hardware associate sono state riconfigurate, disabilitate, rimosse o altrimenti non disponibili per l'uso.
AUDCLNT_E_DEVICE_IN_USE
Il dispositivo endpoint è già in uso. Il dispositivo viene usato in modalità esclusiva oppure il dispositivo viene usato in modalità condivisa e il chiamante ha chiesto di usare il dispositivo in modalità esclusiva.
AUDCLNT_E_ENDPOINT_CREATE_FAILED
Il metodo non è riuscito a creare l'endpoint audio per il rendering o il dispositivo di acquisizione. Ciò può verificarsi se il dispositivo dell'endpoint audio è stato scollegato o l'hardware audio o le risorse hardware associate sono state riconfigurate, disabilitate, rimosse o altrimenti non disponibili per l'uso.
AUDCLNT_E_INVALID_DEVICE_PERIOD
Nota Si applica a Windows 7 e versioni successive.
 
Indica che il periodo del dispositivo richiesto da un client in modalità esclusiva è maggiore di 5000 millisecondi.
AUDCLNT_E_UNSUPPORTED_FORMAT
Il motore audio (modalità condivisa) o il dispositivo endpoint audio (modalità esclusiva) non supporta il formato specificato.
AUDCLNT_E_EXCLUSIVE_MODE_NOT_ALLOWED
Il chiamante richiede l'uso esclusivo del dispositivo endpoint, ma l'utente ha disabilitato l'uso esclusivo del dispositivo.
AUDCLNT_E_BUFDURATION_PERIOD_NOT_EQUAL
Il flag AUDCLNT_STREAMFLAGS_EVENTCALLBACK è impostato, ma i parametri hnsBufferDuration e hnsPeriodicity non sono uguali.
AUDCLNT_E_SERVICE_NOT_RUNNING
Il servizio audio Di Windows non è in esecuzione.
E_POINTER
Il parametro pFormat è NULL.
E_INVALIDARG
Il parametro pFormat punta a una descrizione del formato non valida; o il flag di AUDCLNT_STREAMFLAGS_LOOPBACK è impostato, ma ShareMode non è uguale a AUDCLNT_SHAREMODE_SHARED; o il flag di AUDCLNT_STREAMFLAGS_CROSSPROCESS è impostato, ma ShareMode è uguale a AUDCLNT_SHAREMODE_EXCLUSIVE.

Una chiamata precedente a SetClientProperties è stata effettuata con una categoria non valida per i flussi audio/rendering.

E_OUTOFMEMORY
Memoria insufficiente.

Commenti

Dopo aver attivato un'interfaccia IAudioClient in un dispositivo endpoint audio, il client deve chiamare inizializza una sola volta e una sola volta per inizializzare il flusso audio tra il client e il dispositivo. Il client può connettersi direttamente all'hardware audio (modalità esclusiva) o indirettamente tramite il motore audio (modalità condivisa). Nella chiamata Inizializza il client specifica il formato di dati audio, le dimensioni del buffer e la sessione audio per il flusso.

Nota In Windows 8, il primo uso di IAudioClient per accedere al dispositivo audio deve trovarsi nel thread STA. Le chiamate da un thread MTA possono causare un comportamento non definito.
 
Un tentativo di creare un flusso in modalità condivisa può avere esito positivo solo se il dispositivo audio è già operativo in modalità condivisa o il dispositivo è attualmente inutilizzato. Un tentativo di creare un flusso in modalità condivisa ha esito negativo se il dispositivo è già operativo in modalità esclusiva.

Se un flusso viene inizializzato per essere basato su eventi e in modalità condivisa, ShareMode è impostato su AUDCLNT_SHAREMODE_SHARED e uno dei flag di flusso impostati include AUDCLNT_STREAMFLAGS_EVENTCALLBACK. Per tale flusso, l'applicazione associata deve anche ottenere un handle eseguendo una chiamata a IAudioClient::SetEventHandle. Quando è tempo di ritirare il flusso, il motore audio può quindi usare l'handle per rilasciare gli oggetti di flusso. Impossibile chiamare IAudioClient::SetEventHandle prima di rilasciare gli oggetti di flusso può causare un ritardo di diversi secondi (un periodo di timeout) mentre il motore audio attende un handle disponibile. Dopo la scadenza del periodo di timeout, il motore audio rilascia quindi gli oggetti di flusso.

Se un tentativo di creare un flusso in modalità esclusiva ha esito positivo dipende da diversi fattori, tra cui la disponibilità del dispositivo e le impostazioni controllate dall'utente che regolano l'operazione in modalità esclusiva del dispositivo. Per altre informazioni, vedere Flussi in modalità esclusiva.

Un oggetto IAudioClient supporta esattamente una connessione al motore audio o all'hardware audio. Questa connessione dura per la durata dell'oggetto IAudioClient .

Il client deve chiamare i metodi seguenti solo dopo aver chiamato Initialize:

I metodi seguenti non richiedono che Inizializzare venga chiamato prima: Questi metodi possono essere chiamati in qualsiasi momento dopo l'attivazione dell'interfaccia IAudioClient .

Prima di chiamare Initialize per configurare una connessione in modalità condivisa o esclusiva, il client può chiamare il metodo IAudioClient::IsFormatSupported per individuare se il motore audio o il dispositivo endpoint audio supporta un formato specifico in tale modalità. Prima di aprire una connessione in modalità condivisa, il client può ottenere il formato di combinazione del motore audio chiamando il metodo IAudioClient::GetMixFormat .

Il buffer dell'endpoint condiviso tra il client e il motore audio devono essere sufficienti per evitare che si verifichino errori nel flusso audio tra l'elaborazione passata dal client e dal motore audio. Per un endpoint di rendering, il thread client scrive periodicamente i dati nel buffer e il thread del motore audio legge periodicamente i dati dal buffer. Per un endpoint di acquisizione, il thread del motore scrive periodicamente nel buffer e il thread client legge periodicamente dal buffer. In entrambi i casi, se i periodi del thread client e del thread del motore non sono uguali, il buffer deve essere sufficientemente grande per soddisfare i due periodi senza consentire l'esecuzione di errori.

Il client specifica una dimensione del buffer tramite il parametro hnsBufferDuration . Il client è responsabile della richiesta di un buffer sufficientemente grande per garantire che glitch non possano verificarsi tra l'elaborazione periodica passata che esegue nel buffer. Analogamente, il metodo Initialize garantisce che il buffer non sia mai minore della dimensione minima del buffer necessaria per garantire che glitch non si verifichino tra l'elaborazione periodica passa che il thread del motore esegue nel buffer. Se il client richiede dimensioni del buffer inferiori alle dimensioni minime necessarie del motore audio, il metodo imposta le dimensioni del buffer su questa dimensione minima del buffer anziché sulla dimensione del buffer richiesta dal client.

Se il client richiede una dimensione del buffer (tramite il parametro hnsBufferDuration ) che non è un numero integrale di fotogrammi audio, il metodo arrotonda le dimensioni del buffer richieste al numero integrale successivo di fotogrammi.

Dopo la chiamata Initialize , il client deve chiamare il metodo IAudioClient::GetBufferSize per ottenere le dimensioni precise del buffer dell'endpoint. Durante ogni passaggio di elaborazione, il client richiederà la dimensione effettiva del buffer per calcolare la quantità di dati da trasferire al buffer o dal buffer. Il client chiama il metodo IAudioClient::GetCurrentPadding per determinare la quantità di dati nel buffer attualmente disponibile per l'elaborazione.

Per ottenere la latenza di flusso minima tra l'applicazione client e il dispositivo endpoint audio, il thread client deve essere eseguito nello stesso periodo del thread del motore audio. Il periodo del thread del motore è fisso e non può essere controllato dal client. Rendendo il periodo del client più piccolo del periodo del motore inutilmente aumenta il carico del thread client sul processore senza migliorare la latenza o ridurre le dimensioni del buffer. Per determinare il periodo del thread del motore, il client può chiamare il metodo IAudioClient::GetDevicePeriod . Per impostare il buffer sulla dimensione minima richiesta dal thread del motore, il client deve chiamare Initialize con il parametro hnsBufferDuration impostato su 0. Dopo la chiamata Inizializza , il client può ottenere le dimensioni del buffer risultante chiamando IAudioClient::GetBufferSize.

Un client ha la possibilità di richiedere una dimensione del buffer maggiore di quella strettamente necessaria per rendere rari o inesistenti glitch di intervallo. L'aumento delle dimensioni del buffer non aumenta necessariamente la latenza del flusso. Per un flusso di rendering, la latenza tramite il buffer viene determinata esclusivamente dalla separazione tra il puntatore di scrittura del client e il puntatore di lettura del motore. Per un flusso di acquisizione, la latenza tramite il buffer viene determinata esclusivamente dalla separazione tra il puntatore di scrittura del motore e il puntatore di lettura del client.

Il flag di loopback (AUDCLNT_STREAMFLAGS_LOOPBACK) consente il loopback audio. Un client può abilitare il loopback audio solo in un endpoint di rendering con un flusso in modalità condivisa. Il loopback audio viene fornito principalmente per supportare l'annullamento dell'eco acustico (AEC).

Un client AEC richiede sia un endpoint di rendering che la possibilità di acquisire il flusso di output dal motore audio. Il flusso di output del motore è il mix globale riprodotto dal dispositivo audio attraverso gli altoparlanti. Se il loopback audio è abilitato, un client può aprire un buffer di acquisizione per la combinazione audio globale chiamando il metodo IAudioClient::GetService per ottenere un'interfaccia IAudioCaptureClient nell'oggetto flusso di rendering. Se il loopback audio non è abilitato, un tentativo di aprire un buffer di acquisizione in un flusso di rendering avrà esito negativo. I dati di loopback nel buffer di acquisizione sono nel formato del dispositivo, che il client può ottenere eseguendo una query sulla proprietà PKEY_AudioEngine_DeviceFormat del dispositivo.

Nelle versioni di Windows prima di Windows 10, un client di acquisizione in modalità pull non riceverà eventi quando un flusso viene inizializzato con buffer basato su eventi (AUDCLNT_STREAMFLAGS_EVENTCALLBACK) ed è abilitato per il loopback (AUDCLNT_STREAMFLAGS_LOOPBACK). Se il flusso viene aperto con questa configurazione, la chiamata Inizializza riesce, ma gli eventi pertinenti non vengono generati per notificare al client di acquisizione ogni volta che un buffer diventa pronto per l'elaborazione. Per risolvere questo problema, inizializzare un flusso di rendering in modalità basata su eventi. Ogni volta che il client riceve un evento per il flusso di rendering, deve segnalare al client di acquisizione di eseguire il thread di acquisizione che legge il set successivo di campioni dal buffer dell'endpoint di acquisizione. A partire da Windows 10 gli handle eventi pertinenti sono ora impostati per i flussi abilitati per il loopback che sono attivi.

Si noti che tutti i flussi devono essere aperti in modalità condivisione perché i flussi in modalità esclusiva non possono funzionare in modalità loopback. Per altre informazioni sul loopback audio, vedere Registrazione cicloback.

Il flag AUDCLNT_STREAMFLAGS_EVENTCALLBACK indica che l'elaborazione del buffer audio dal client verrà guidata dall'evento. WASAPI supporta il buffer basato su eventi per consentire l'elaborazione a bassa latenza di flussi in modalità condivisa ed esclusiva.

La versione iniziale di Windows Vista supporta il buffer basato su eventi, ovvero l'uso del flag di AUDCLNT_STREAMFLAGS_EVENTCALLBACK, solo per i flussi di rendering.

Nella versione iniziale di Windows Vista, per i flussi di acquisizione, il flag di AUDCLNT_STREAMFLAGS_EVENTCALLBACK è supportato solo in modalità condivisa. L'impostazione di questo flag non ha alcun effetto per i flussi di acquisizione in modalità esclusiva. Vale a dire, anche se l'applicazione specifica questo flag in modalità esclusiva tramite la chiamata Inizializza , l'applicazione non riceverà eventi che in genere sono necessari per acquisire il flusso audio. Nella versione di Windows Vista Service Pack 1 questo flag è funzionale in modalità condivisa ed esclusiva; un'applicazione può impostare questo flag per abilitare il buffer degli eventi per i flussi di acquisizione. Per altre informazioni sull'acquisizione di un flusso audio, vedere Acquisizione di un flusso.

Per abilitare il buffer basato su eventi, il client deve fornire un handle eventi al sistema. Dopo la chiamata Initialize e prima di chiamare il metodo IAudioClient::Start per avviare il flusso, il client deve chiamare il metodo IAudioClient::SetEventHandle per impostare l'handle eventi. Mentre il flusso è in esecuzione, il sistema segnala periodicamente l'evento per indicare al client che i dati audio sono disponibili per l'elaborazione. Tra l'elaborazione passa, il thread client attende l'handle dell'evento chiamando una funzione di sincronizzazione, ad esempio WaitForSingleObject. Per altre informazioni sulle funzioni di sincronizzazione, vedere la documentazione di Windows SDK.

Per un flusso in modalità condivisa che usa il buffer basato su eventi, il chiamante deve impostare sia hnsPeriodicity che hnsBufferDuration su 0. Il metodo Initialize determina la quantità di buffer da allocare in base al periodo di pianificazione del motore audio. Anche se il thread di elaborazione del buffer del client è basato su eventi, il processo di gestione del buffer di base, come descritto in precedenza, è invariato. Ogni volta che il thread si sveglia, deve chiamare IAudioClient::GetCurrentPadding per determinare la quantità di dati da scrivere in un buffer di rendering o leggere da un buffer di acquisizione. Al contrario dei due buffer allocati dal metodo Initialize per un flusso in modalità esclusiva che usa il buffer basato su eventi, un flusso in modalità condivisa richiede un singolo buffer.

Per un flusso in modalità esclusiva che usa il buffer basato su eventi, il chiamante deve specificare valori non zero per hnsPeriodicity e hnsBufferDuration e i valori di questi due parametri devono essere uguali. Il metodo Initialize alloca due buffer per il flusso. Ogni buffer è uguale alla durata del valore del parametro hnsBufferDuration . Dopo la chiamata Inizializza per un flusso di rendering, il chiamante deve riempire il primo dei due buffer prima di avviare il flusso. Per un flusso di acquisizione, i buffer sono inizialmente vuoti e il chiamante deve presupporre che ogni buffer rimanga vuoto finché l'evento per tale buffer non viene segnalato. Mentre il flusso è in esecuzione, il sistema invia in alternativa un buffer o l'altro al client, questa forma di buffer doppio viene definita "ping-ponging". Ogni volta che il client riceve un buffer dal sistema (che il sistema indica segnalando l'evento), il client deve elaborare l'intero buffer. Ad esempio, se il client richiede una dimensione del pacchetto dal metodo IAudioRenderClient::GetBuffer che non corrisponde alle dimensioni del buffer, il metodo ha esito negativo. Le chiamate al metodo IAudioClient::GetCurrentPadding non sono necessarie perché le dimensioni dei pacchetti devono sempre essere uguali alle dimensioni del buffer. Al contrario delle modalità di buffering descritte in precedenza, la latenza per un flusso basato su eventi e in modalità esclusiva dipende direttamente dalle dimensioni del buffer.

Come illustrato in Sessioni audio, il comportamento predefinito per una sessione che contiene flussi di rendering è che il volume e le impostazioni di disattivazione persistono tra i riavvii dell'applicazione. Il flag di AUDCLNT_STREAMFLAGS_NOPERSIST esegue l'override del comportamento predefinito e rende le impostazioni nonperistenti. Questo flag non ha alcun effetto sulle sessioni che contengono flussi di acquisizione, ovvero le impostazioni per tali sessioni non sono mai persistenti. Inoltre, le impostazioni per una sessione che contiene un flusso di loopback (un flusso inizializzato con il flag di AUDCLNT_STREAMFLAGS_LOOPBACK) non sono persistenti.

Solo una sessione che si connette a un dispositivo dell'endpoint di rendering può avere impostazioni di volume persistente e disattivazione. Il primo flusso da aggiungere alla sessione determina se le impostazioni della sessione sono persistenti. Pertanto, se il flag AUDCLNT_STREAMFLAGS_NOPERSIST o AUDCLNT_STREAMFLAGS_LOOPBACK viene impostato durante l'inizializzazione del primo flusso, le impostazioni della sessione non sono persistenti. In caso contrario, sono persistenti. La loro persistenza non è influenzata da flussi aggiuntivi che potrebbero essere aggiunti o rimossi successivamente durante la durata dell'oggetto sessione.

Dopo che una chiamata a Initialize ha inizializzato correttamente un'istanza dell'interfaccia IAudioClient , una chiamata inizializza successiva per inizializzare la stessa istanza dell'interfaccia avrà esito negativo e restituirà il codice di errore E_ALREADY_INITIALIZED.

Se la chiamata iniziale a Initialize ha esito negativo, le chiamate inizializzate successive potrebbero non riuscire e restituire il codice di errore E_ALREADY_INITIALIZED, anche se l'interfaccia non è stata inizializzata. In questo caso, rilasciare l'interfaccia IAudioClient e ottenere una nuova interfaccia IAudioClientdall'API MMDevice prima di chiamare di nuovo Initialize.

Per esempi di codice che chiamano il metodo Initialize , vedere gli argomenti seguenti:

A partire da Windows 7, Inizializza può restituire AUDCLNT_E_BUFFER_SIZE_NOT_ALIGNED per un rendering o un dispositivo di acquisizione. Ciò indica che la dimensione del buffer, specificata dal chiamante nel parametro hnsBufferDuration , non è allineata. Questo codice di errore viene restituito solo se il chiamante ha richiesto un flusso in modalità esclusiva (AUDCLNT_SHAREMODE_EXCLUSIVE) e il buffer basato su eventi (AUDCLNT_STREAMFLAGS_EVENTCALLBACK).

Se Inizializza restituisce AUDCLNT_E_BUFFER_SIZE_NOT_ALIGNED, il chiamante deve chiamare di nuovo Initialize e specificare la dimensione del buffer allineata. Eseguire la procedura descritta di seguito:

  1. Chiamare IAudioClient::GetBufferSize e ricevere le dimensioni del buffer allineate più alte (in fotogrammi).
  2. Chiamare IAudioClient::Release per rilasciare il client audio usato nella chiamata precedente che ha restituito AUDCLNT_E_BUFFER_SIZE_NOT_ALIGNED.
  3. Calcolare le dimensioni del buffer allineate in unità a 100 nanosecondi (hns). La dimensione del buffer è (REFERENCE_TIME)((10000.0 * 1000 / WAVEFORMATEX.nSamplesPerSecond * nFrames) + 0.5). In questa formula la nFrames dimensione del buffer recuperata da GetBufferSize.
  4. Chiamare il metodo IMMDevice::Activate con parametro iid impostato su REFIID IID_IAudioClient per creare un nuovo client audio.
  5. Chiamare di nuovo inizializzare il client audio creato e specificare la nuova dimensione del buffer e la periodicità.

A partire da Windows 10, i flussi audio caricati dall'hardware devono essere basati su eventi. Ciò significa che se si chiama IAudioClient2::SetClientProperties e si imposta il parametro bIsOffload di AudioClientProperties su TRUE, è necessario specificare il flag AUDCLNT_STREAMFLAGS_EVENTCALLBACK nel parametro StreamFlags su IAudioClient::Initialize.

Esempio

Il codice di esempio seguente illustra come rispondere al codice restituito 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;
}

Requisiti

   
Piattaforma di destinazione Windows
Intestazione audioclient.h

Vedi anche

Interfaccia IAudioCaptureClient

Interfaccia IAudioClient

IAudioClient::GetBufferSize

IAudioClient::GetCurrentPadding

IAudioClient::GetDevicePeriod

IAudioClient::GetMixFormat

IAudioClient::GetService

IAudioClient::SetEventHandle

IAudioClient::Start

IAudioRenderClient::GetBuffer