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 endpoint audio con altri client. Il client deve impostare questo parametro su uno dei valori di enumerazione AUDCLNT_SHAREMODE seguenti:

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 temporale. Questo parametro è di tipo REFERENCE_TIME ed è espresso in unità di 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 sulle 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 endpoint audio. Se il periodo del dispositivo richiesto non rientra nell'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 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, restituisce S_OK. Se ha esito negativo, i possibili codici restituiti includono, ma non sono limitati, i valori illustrati nella tabella seguente.

Codice restituito Description
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 dispositivo di rendering o di acquisizione se il chiamante ha specificato AUDCLNT_SHAREMODE_EXCLUSIVE e i flag AUDCLNT_STREAMFLAGS_EVENTCALLBACK. Il chiamante deve chiamare di nuovo Initialize con le dimensioni del buffer allineate. Per altre informazioni, vedere Osservazioni.
AUDCLNT_E_BUFFER_SIZE_ERROR
Nota Si applica a Windows 7 e versioni successive.
 
Indica che il valore della 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 della 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 (compreso nell'intervallo di 10% e 90%). Se questo valore non viene trovato, viene usato il valore predefinito 40% per calcolare l'utilizzo massimo della CPU.
AUDCLNT_E_DEVICE_INVALIDATED
Il dispositivo endpoint audio è stato scollegato oppure l'hardware audio o le risorse hardware associate sono state riconfigurate, disabilitate, rimosse o altrimenti rese non disponibili per l'uso.
AUDCLNT_E_RESOURCES_INVALIDATED
Le risorse del flusso sono state invalidate. Questo errore può essere generato per i motivi seguenti:
- Il flusso è sospeso.
- Un flusso esclusivo o offload viene disconnesso.
- Un'applicazione in pacchetto che ha una modalità esclusiva o un flusso di offload è inattiva.
- Un flusso di "output protetto" viene chiuso.
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 endpoint audio è stato scollegato o se l'hardware audio o le risorse hardware associate sono state riconfigurate, disabilitate, rimosse o altrimenti rese 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 in modalità esclusiva del dispositivo endpoint, ma l'utente ha disabilitato l'uso in modalità esclusiva 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 windows non è in esecuzione.
E_POINTER
Il parametro pFormat è NULL.
E_INVALIDARG
Il parametro pFormat punta a una descrizione di 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 esaurita.

Osservazioni:

Dopo aver attivato un'interfaccia IAudioClient in un dispositivo endpoint audio, il client deve chiamare correttamente Initialize una 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 dei 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 essere nel thread STA. Le chiamate da un thread MTA possono comportare 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 guidato dagli eventi e in modalità condivisa, ShareMode è impostato su AUDCLNT_SHAREMODE_SHARED e uno dei flag di flusso impostati include AUDCLNT_STREAMFLAGS_EVENTCALLBACK. Per un flusso di questo tipo, l'applicazione associata deve anche ottenere un handle effettuando una chiamata a IAudioClient::SetEventHandle. Quando è il momento di ritirare il flusso, il motore audio può quindi usare l'handle per rilasciare gli oggetti flusso. L'impossibilità di chiamare IAudioClient::SetEventHandle prima di rilasciare gli oggetti 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 flusso.

L'esito positivo di un tentativo di creazione di un flusso in modalità esclusiva dipende da diversi fattori, tra cui la disponibilità del dispositivo e le impostazioni controllate dall'utente che regolano il funzionamento in modalità esclusiva del dispositivo. Per altre informazioni, vedere Exclusive-Mode Streams.

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

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

I metodi seguenti non richiedono che Initialize venga chiamato per primo: 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 in modalità 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 deve essere sufficientemente grande per evitare che si verifichino errori nel flusso audio tra i passaggi di elaborazione 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 contenere il più lungo dei due periodi senza consentire l'esecuzione di glitch.

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 i passaggi di elaborazione periodici eseguiti nel buffer. Analogamente, il metodo Initialize garantisce che il buffer non sia mai inferiore alla dimensione minima del buffer necessaria per garantire che glitch non si verifichino tra i passaggi di elaborazione periodici eseguiti dal thread del motore nel buffer. Se il client richiede una dimensione del buffer inferiore alla dimensione minima richiesta del motore audio, il metodo imposta le dimensioni del buffer su questa dimensione minima del buffer anziché sulle dimensioni del buffer richieste 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 dovrà avere le dimensioni effettive del buffer per calcolare la quantità di dati da trasferire da o verso il 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 inferiore al periodo del motore aumenta inutilmente 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 sulle dimensioni minime richieste dal thread del motore, il client deve chiamare Initialize con il parametro hnsBufferDuration impostato su 0. Dopo la chiamata Initialize , 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) abilita 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 è la combinazione globale riprodotta 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, il 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 precedenti a Windows 10, un client di acquisizione in modalità pull non riceverà eventi quando un flusso viene inizializzato con buffering basato su eventi (AUDCLNT_STREAMFLAGS_EVENTCALLBACK) ed è abilitato per il loopback (AUDCLNT_STREAMFLAGS_LOOPBACK). Se il flusso viene aperto con questa configurazione, la chiamata Initialize ha esito positivo, ma gli eventi rilevanti non vengono generati per notificare al client di acquisizione ogni volta che un buffer diventa pronto per l'elaborazione. Per ovviare a questo problema, inizializzare un flusso di rendering in modalità guidata dagli 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 di eventi pertinenti sono ora impostati per i flussi abilitati per il loopback 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 loopback.

Il flag AUDCLNT_STREAMFLAGS_EVENTCALLBACK indica che l'elaborazione del buffer audio da parte del client verrà guidata dagli eventi. WASAPI supporta il buffering guidato dagli eventi per abilitare l'elaborazione a bassa latenza dei flussi in modalità condivisa e in modalità esclusiva.

La versione iniziale di Windows Vista supporta il buffering 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 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. Ovvero, anche se l'applicazione specifica questo flag in modalità esclusiva tramite la chiamata Initialize , 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 buffering guidato dagli 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 i passaggi di elaborazione, 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 hnsPeriodicity e hnsBufferDuration su 0. Il metodo Initialize determina la dimensione di un 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, non è modificato. Ogni volta che il thread viene risvegliato, deve chiamare IAudioClient::GetCurrentPadding per determinare la quantità di dati da scrivere in un buffer di rendering o leggere da un buffer di acquisizione. A differenza 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 buffering basato su eventi, il chiamante deve specificare valori diversi da 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 fino a quando non viene segnalato l'evento per tale buffer. Mentre il flusso è in esecuzione, il sistema invia in alternativa un buffer o l'altro al client. Questa forma di doppio buffering 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 del pacchetto devono essere sempre uguali alle dimensioni del buffer. A differenza delle modalità di buffering descritte in precedenza, la latenza per un flusso in modalità esclusiva basata su eventi dipende direttamente dalle dimensioni del buffer.

Come spiegato 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 AUDCLNT_STREAMFLAGS_NOPERSIST esegue l'override del comportamento predefinito e rende le impostazioni non permanenti. 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 AUDCLNT_STREAMFLAGS_LOOPBACK) non sono persistenti.

Solo una sessione che si connette a un dispositivo endpoint di rendering può avere impostazioni di volume permanente e disattivazione disattivata. 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 persistenza non è influenzata da flussi aggiuntivi che potrebbero essere successivamente aggiunti o rimossi durante la durata dell'oggetto sessione.

Dopo che una chiamata a Initialize ha inizializzato correttamente un'istanza dell'interfaccia IAudioClient, una chiamata Initialize successiva per inizializzare la stessa istanza di 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, Initialize può restituire AUDCLNT_E_BUFFER_SIZE_NOT_ALIGNED per un dispositivo di rendering o di acquisizione. Ciò indica che le dimensioni del buffer, specificate dal chiamante nel parametro hnsBufferDuration , non sono allineate. Questo codice di errore viene restituito solo se il chiamante ha richiesto un flusso in modalità esclusiva (AUDCLNT_SHAREMODE_EXCLUSIVE) e il buffering basato su eventi (AUDCLNT_STREAMFLAGS_EVENTCALLBACK).

Se Initialize restituisce AUDCLNT_E_BUFFER_SIZE_NOT_ALIGNED, il chiamante deve chiamare di nuovo Initialize e specificare le dimensioni del buffer allineate. Seguire questa procedura:

  1. Chiamare IAudioClient::GetBufferSize e ricevere la dimensione del buffer allineata più alta successiva (in fotogrammi).
  2. Chiama 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à di 100 nanosecondi (hns). La dimensione del buffer è (REFERENCE_TIME)((10000.0 * 1000 / WAVEFORMATEX.nSamplesPerSecond * nFrames) + 0.5). In questa formula è nFrames la dimensione del buffer recuperata da GetBufferSize.
  4. Chiamare il metodo IMMDevice::Activate con il parametro iid impostato su REFIID IID_IAudioClient per creare un nuovo client audio.
  5. Chiamare di nuovo Inizializza nel client audio creato e specificare la nuova dimensione del buffer e la periodicità.

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

Esempi

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

Requisito Value
Piattaforma di destinazione Windows
Header audioclient.h

Vedere anche

Interfaccia IAudioCaptureClient

Interfaccia IAudioClient

IAudioClient::GetBufferSize

IAudioClient::GetCurrentPadding

IAudioClient::GetDevicePeriod

IAudioClient::GetMixFormat

IAudioClient::GetService

IAudioClient::SetEventHandle

IAudioClient::Start

IAudioRenderClient::GetBuffer