Metode IAudioClient::Initialize (audioclient.h)

Metode Inisialisasi menginisialisasi aliran audio.

Sintaks

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

Parameter

[in] ShareMode

Mode berbagi untuk koneksi. Melalui parameter ini, klien memberi tahu mesin audio apakah ingin berbagi perangkat titik akhir audio dengan klien lain. Klien harus mengatur parameter ini ke salah satu nilai enumerasi AUDCLNT_SHAREMODE berikut:

AUDCLNT_SHAREMODE_EXCLUSIVE

AUDCLNT_SHAREMODE_SHARED

[in] StreamFlags

Bendera untuk mengontrol pembuatan aliran. Klien harus mengatur parameter ini ke 0 atau ke bitwise ATAU dari satu atau beberapa konstanta AUDCLNT_STREAMFLAGS_XXX atau konstanta AUDCLNT_SESSIONFLAGS_XXX.

[in] hnsBufferDuration

Kapasitas buffer sebagai nilai waktu. Parameter ini berjenis REFERENCE_TIME dan dinyatakan dalam unit 100 nanodetik. Parameter ini berisi ukuran buffer yang diminta pemanggil untuk buffer yang akan dibagikan aplikasi audio dengan mesin audio (dalam mode bersama) atau dengan perangkat titik akhir (dalam mode eksklusif). Jika panggilan berhasil, metode mengalokasikan buffer yang setidaknya sebesar ini. Untuk informasi selengkapnya tentang REFERENCE_TIME, lihat dokumentasi Windows SDK. Untuk informasi selengkapnya tentang persyaratan buffering, lihat Keterangan.

[in] hnsPeriodicity

Periode perangkat. Parameter ini hanya dapat berupa bukan nol dalam mode eksklusif. Dalam mode bersama, selalu atur parameter ini ke 0. Dalam mode eksklusif, parameter ini menentukan periode penjadwalan yang diminta untuk akses buffer berturut-turut oleh perangkat titik akhir audio. Jika periode perangkat yang diminta berada di luar rentang yang ditetapkan oleh periode minimum perangkat dan periode maksimum sistem, maka metode akan menjepit periode ke rentang tersebut. Jika parameter ini adalah 0, metode mengatur periode perangkat ke nilai defaultnya. Untuk mendapatkan periode perangkat default, panggil metode IAudioClient::GetDevicePeriod . Jika bendera aliran AUDCLNT_STREAMFLAGS_EVENTCALLBACK diatur dan AUDCLNT_SHAREMODE_EXCLUSIVE ditetapkan sebagai ShareMode, maka hnsPeriodicity harus nonzero dan sama dengan hnsBufferDuration.

[in] pFormat

Penunjuk ke deskriptor format. Parameter ini harus menunjuk ke deskriptor format yang valid dari jenis WAVEFORMATEX (atau WAVEFORMATEXTENSIBLE). Untuk informasi selengkapnya, lihat Keterangan.

[in] AudioSessionGuid

Penunjuk ke GUID sesi. Parameter ini menunjuk ke nilai GUID yang mengidentifikasi sesi audio tempat aliran berada. Jika GUID mengidentifikasi sesi yang telah dibuka sebelumnya, metode menambahkan aliran ke sesi tersebut. Jika GUID tidak mengidentifikasi sesi yang ada, metode membuka sesi baru dan menambahkan aliran ke sesi tersebut. Aliran tetap menjadi anggota sesi yang sama selama masa pakainya. Mengatur parameter ini ke NULL setara dengan meneruskan pointer ke nilai GUID_NULL.

Mengembalikan nilai

Jika metode berhasil, metode akan mengembalikan S_OK. Jika gagal, kemungkinan kode pengembalian menyertakan, tetapi tidak terbatas pada, nilai yang diperlihatkan dalam tabel berikut.

Menampilkan kode Deskripsi
AUDCLNT_E_ALREADY_INITIALIZED
Objek IAudioClient sudah diinisialisasi.
AUDCLNT_E_WRONG_ENDPOINT_TYPE
Bendera AUDCLNT_STREAMFLAGS_LOOPBACK diatur tetapi perangkat titik akhir adalah perangkat tangkapan, bukan perangkat penyajian.
AUDCLNT_E_BUFFER_SIZE_NOT_ALIGNED
Catatan Berlaku untuk Windows 7 dan yang lebih baru.
 
Ukuran buffer yang diminta tidak diratakan. Kode ini dapat dikembalikan untuk render atau perangkat pengambilan jika pemanggil menentukan AUDCLNT_SHAREMODE_EXCLUSIVE dan bendera AUDCLNT_STREAMFLAGS_EVENTCALLBACK. Penelepon harus memanggil Inisialisasi lagi dengan ukuran buffer yang diratakan. Untuk informasi selengkapnya, lihat Keterangan.
AUDCLNT_E_BUFFER_SIZE_ERROR
Catatan Berlaku untuk Windows 7 dan yang lebih baru.
 
Menunjukkan bahwa nilai durasi buffer yang diminta oleh klien mode eksklusif berada di luar rentang. Nilai durasi yang diminta untuk mode penarikan tidak boleh lebih besar dari 5000 milidetik; untuk mode pendorongan, nilai durasi tidak boleh lebih besar dari 2 detik.
AUDCLNT_E_CPUUSAGE_EXCEEDED
Menunjukkan bahwa durasi proses-pass melebihi penggunaan CPU maksimum. Mesin audio melacak penggunaan CPU dengan mempertahankan berapa kali durasi proses-lulus melebihi penggunaan CPU maksimum. Penggunaan CPU maksimum dihitung sebagai persen dari periodisitas mesin. Nilai persentase adalah nilai pembatasan CPU sistem (dalam kisaran 10% dan 90%). Jika nilai ini tidak ditemukan, maka nilai default 40% digunakan untuk menghitung penggunaan CPU maksimum.
AUDCLNT_E_DEVICE_INVALIDATED
Perangkat titik akhir audio telah dicabut, atau perangkat keras audio atau sumber daya perangkat keras terkait telah dikonfigurasi ulang, dinonaktifkan, dihapus, atau dibuat tidak tersedia untuk digunakan.
AUDCLNT_E_DEVICE_IN_USE
Perangkat titik akhir sudah digunakan. Perangkat sedang digunakan dalam mode eksklusif, atau perangkat sedang digunakan dalam mode bersama dan pemanggil diminta untuk menggunakan perangkat dalam mode eksklusif.
AUDCLNT_E_ENDPOINT_CREATE_FAILED
Metode gagal membuat titik akhir audio untuk render atau perangkat pengambilan. Ini dapat terjadi jika perangkat titik akhir audio telah dicabut, atau perangkat keras audio atau sumber daya perangkat keras terkait telah dikonfigurasi ulang, dinonaktifkan, dihapus, atau dibuat tidak tersedia untuk digunakan.
AUDCLNT_E_INVALID_DEVICE_PERIOD
Catatan Berlaku untuk Windows 7 dan yang lebih baru.
 
Menunjukkan bahwa periode perangkat yang diminta oleh klien mode eksklusif lebih besar dari 5000 milidetik.
AUDCLNT_E_UNSUPPORTED_FORMAT
Mesin audio (mode bersama) atau perangkat titik akhir audio (mode eksklusif) tidak mendukung format yang ditentukan.
AUDCLNT_E_EXCLUSIVE_MODE_NOT_ALLOWED
Pemanggil meminta penggunaan mode eksklusif perangkat titik akhir, tetapi pengguna telah menonaktifkan penggunaan mode eksklusif perangkat.
AUDCLNT_E_BUFDURATION_PERIOD_NOT_EQUAL
Bendera AUDCLNT_STREAMFLAGS_EVENTCALLBACK diatur tetapi parameter hnsBufferDuration dan hnsPeriodicity tidak sama.
AUDCLNT_E_SERVICE_NOT_RUNNING
Layanan audio Windows tidak berjalan.
E_POINTER
Parameter pFormat adalah NULL.
E_INVALIDARG
Parameter pFormat menunjuk ke deskripsi format yang tidak valid; atau bendera AUDCLNT_STREAMFLAGS_LOOPBACK diatur tetapi ShareMode tidak sama dengan AUDCLNT_SHAREMODE_SHARED; atau bendera AUDCLNT_STREAMFLAGS_CROSSPROCESS diatur tetapi ShareMode sama dengan AUDCLNT_SHAREMODE_EXCLUSIVE.

Panggilan sebelumnya ke SetClientProperties dilakukan dengan kategori yang tidak valid untuk aliran audio/render.

E_OUTOFMEMORY
Kehabisan memori.

Keterangan

Setelah mengaktifkan antarmuka IAudioClient pada perangkat titik akhir audio, klien harus berhasil memanggil Inisialisasi sekali dan hanya sekali untuk menginisialisasi aliran audio antara klien dan perangkat. Klien dapat terhubung langsung ke perangkat keras audio (mode eksklusif) atau secara tidak langsung melalui mesin audio (mode bersama). Dalam panggilan Inisialisasi , klien menentukan format data audio, ukuran buffer, dan sesi audio untuk aliran.

Catatan Di Windows 8, penggunaan pertama IAudioClient untuk mengakses perangkat audio harus berada di utas STA. Panggilan dari utas MTA dapat mengakibatkan perilaku yang tidak terdefinisi.
 
Upaya untuk membuat aliran mode bersama hanya dapat berhasil jika perangkat audio sudah beroperasi dalam mode bersama atau perangkat saat ini tidak digunakan. Upaya untuk membuat aliran mode bersama gagal jika perangkat sudah beroperasi dalam mode eksklusif.

Jika aliran diinisialisasi menjadi berbasis peristiwa dan dalam mode bersama, ShareMode diatur ke AUDCLNT_SHAREMODE_SHARED dan salah satu bendera aliran yang diatur menyertakan AUDCLNT_STREAMFLAGS_EVENTCALLBACK. Untuk aliran seperti itu, aplikasi terkait juga harus mendapatkan handel dengan melakukan panggilan ke IAudioClient::SetEventHandle. Ketika sudah waktunya untuk menghentikan aliran, mesin audio kemudian dapat menggunakan handel untuk merilis objek aliran. Kegagalan memanggil IAudioClient::SetEventHandle sebelum merilis objek stream dapat menyebabkan penundaan beberapa detik (periode waktu habis) saat mesin audio menunggu handel yang tersedia. Setelah periode waktu habis berakhir, mesin audio kemudian merilis objek aliran.

Apakah upaya untuk membuat aliran mode eksklusif berhasil tergantung pada beberapa faktor, termasuk ketersediaan perangkat dan pengaturan yang dikontrol pengguna yang mengatur operasi mode eksklusif perangkat. Untuk informasi selengkapnya, lihat Stream Mode Eksklusif.

Objek IAudioClient mendukung tepat satu koneksi ke mesin audio atau perangkat keras audio. Koneksi ini berlangsung selama masa pakai objek IAudioClient .

Klien harus memanggil metode berikut hanya setelah memanggil Inisialisasi:

Metode berikut tidak mengharuskan Inisialisasi dipanggil terlebih dahulu: Metode ini dapat dipanggil kapan saja setelah mengaktifkan antarmuka IAudioClient .

Sebelum memanggil Inisialisasi untuk menyiapkan koneksi mode bersama atau mode eksklusif, klien dapat memanggil metode IAudioClient::IsFormatSupported untuk menemukan apakah mesin audio atau perangkat titik akhir audio mendukung format tertentu dalam mode tersebut. Sebelum membuka koneksi mode bersama, klien dapat memperoleh format campuran mesin audio dengan memanggil metode IAudioClient::GetMixFormat .

Buffer titik akhir yang dibagikan antara klien dan mesin audio harus cukup besar untuk mencegah gangguan terjadi dalam aliran audio antara pemrosesan yang dilewati oleh klien dan mesin audio. Untuk titik akhir penyajian, utas klien secara berkala menulis data ke buffer, dan utas mesin audio secara berkala membaca data dari buffer. Untuk titik akhir penangkapan, utas mesin secara berkala menulis ke buffer, dan utas klien secara berkala membaca dari buffer. Dalam kedua kasus, jika periode utas klien dan utas mesin tidak sama, buffer harus cukup besar untuk mengakomodasi lebih lama dari dua periode tanpa memungkinkan gangguan terjadi.

Klien menentukan ukuran buffer melalui parameter hnsBufferDuration . Klien bertanggung jawab untuk meminta buffer yang cukup besar untuk memastikan bahwa gangguan tidak dapat terjadi antara proses berkala yang dilakukannya pada buffer. Demikian pula, metode Inisialisasi memastikan bahwa buffer tidak pernah lebih kecil dari ukuran buffer minimum yang diperlukan untuk memastikan bahwa gangguan tidak terjadi antara pemrosesan berkala melewati yang dilakukan utas mesin pada buffer. Jika klien meminta ukuran buffer yang lebih kecil dari ukuran buffer minimum mesin audio yang diperlukan, metode mengatur ukuran buffer ke ukuran buffer minimum ini daripada ke ukuran buffer yang diminta oleh klien.

Jika klien meminta ukuran buffer (melalui parameter hnsBufferDuration ) yang bukan jumlah bingkai audio integral, metode membulatkan ukuran buffer yang diminta ke jumlah bingkai integral berikutnya.

Setelah panggilan Inisialisasi , klien harus memanggil metode IAudioClient::GetBufferSize untuk mendapatkan ukuran buffer titik akhir yang tepat. Selama setiap lulus pemrosesan, klien akan membutuhkan ukuran buffer aktual untuk menghitung berapa banyak data yang akan ditransfer ke atau dari buffer. Klien memanggil metode IAudioClient::GetCurrentPadding untuk menentukan berapa banyak data dalam buffer yang saat ini tersedia untuk diproses.

Untuk mencapai latensi streaming minimum antara aplikasi klien dan perangkat titik akhir audio, utas klien harus berjalan pada periode yang sama dengan utas mesin audio. Periode utas mesin diperbaiki dan tidak dapat dikontrol oleh klien. Membuat periode klien lebih kecil dari periode mesin yang tidak perlu meningkatkan beban utas klien pada prosesor tanpa meningkatkan latensi atau mengurangi ukuran buffer. Untuk menentukan periode utas mesin, klien dapat memanggil metode IAudioClient::GetDevicePeriod . Untuk mengatur buffer ke ukuran minimum yang diperlukan oleh utas mesin, klien harus memanggil Inisialisasi dengan parameter hnsBufferDuration diatur ke 0. Setelah panggilan Inisialisasi , klien bisa mendapatkan ukuran buffer yang dihasilkan dengan memanggil IAudioClient::GetBufferSize.

Klien memiliki opsi untuk meminta ukuran buffer yang lebih besar dari apa yang benar-benar diperlukan untuk membuat gangguan waktu jarang atau tidak ada. Meningkatkan ukuran buffer tidak selalu meningkatkan latensi aliran. Untuk aliran penyajian, latensi melalui buffer hanya ditentukan oleh pemisahan antara pointer tulis klien dan penunjuk baca mesin. Untuk aliran penangkapan, latensi melalui buffer hanya ditentukan oleh pemisahan antara penunjuk tulis mesin dan penunjuk baca klien.

Bendera loopback (AUDCLNT_STREAMFLAGS_LOOPBACK) memungkinkan loopback audio. Klien hanya dapat mengaktifkan loopback audio pada titik akhir penyajian dengan aliran mode bersama. Loopback audio disediakan terutama untuk mendukung pembatalan gema akustik (AEC).

Klien AEC memerlukan titik akhir penyajian dan kemampuan untuk mengambil aliran output dari mesin audio. Aliran output mesin adalah campuran global yang diputar perangkat audio melalui speaker. Jika loopback audio diaktifkan, klien dapat membuka buffer pengambilan untuk campuran audio global dengan memanggil metode IAudioClient::GetService untuk mendapatkan antarmuka IAudioCaptureClient pada objek stream penyajian. Jika loopback audio tidak diaktifkan, upaya untuk membuka buffer pengambilan pada aliran penyajian akan gagal. Data loopback dalam buffer pengambilan berada dalam format perangkat, yang dapat diperoleh klien dengan mengkueri properti PKEY_AudioEngine_DeviceFormat perangkat.

Pada versi Windows sebelum Windows 10, klien pengambilan mode tarik tidak akan menerima peristiwa apa pun ketika aliran diinisialisasi dengan buffering berbasis peristiwa (AUDCLNT_STREAMFLAGS_EVENTCALLBACK) dan diaktifkan loopback (AUDCLNT_STREAMFLAGS_LOOPBACK). Jika aliran dibuka dengan konfigurasi ini, panggilan Inisialisasi berhasil, tetapi peristiwa yang relevan tidak dinaikkan untuk memberi tahu klien pengambilan setiap kali buffer siap diproses. Untuk mengatasinya, inisialisasi aliran render dalam mode berbasis peristiwa. Setiap kali klien menerima peristiwa untuk aliran render, klien penangkapan harus memberi sinyal untuk menjalankan utas pengambilan yang membaca serangkaian sampel berikutnya dari buffer titik akhir pengambilan. Pada Windows 10 handel peristiwa yang relevan sekarang diatur untuk aliran berkemampuan loopback yang aktif.

Perhatikan bahwa semua aliran harus dibuka dalam mode berbagi karena aliran mode eksklusif tidak dapat beroperasi dalam mode loopback. Untuk informasi selengkapnya tentang loopback audio, lihat Perekaman Loopback.

Bendera AUDCLNT_STREAMFLAGS_EVENTCALLBACK menunjukkan bahwa pemrosesan buffer audio oleh klien akan didorong oleh peristiwa. WASAPI mendukung buffering berbasis peristiwa untuk memungkinkan pemrosesan latensi rendah dari aliran mode bersama dan mode eksklusif.

Rilis awal Windows Vista mendukung buffering berbasis peristiwa (yaitu, penggunaan bendera AUDCLNT_STREAMFLAGS_EVENTCALLBACK) hanya untuk penyajian aliran.

Dalam rilis awal Windows Vista, untuk aliran pengambilan, bendera AUDCLNT_STREAMFLAGS_EVENTCALLBACK hanya didukung dalam mode bersama. Mengatur bendera ini tidak berpengaruh untuk aliran pengambilan mode eksklusif. Artinya, meskipun aplikasi menentukan bendera ini dalam mode eksklusif melalui panggilan Inisialisasi , aplikasi tidak akan menerima peristiwa apa pun yang biasanya diperlukan untuk menangkap aliran audio. Dalam rilis Windows Vista Service Pack 1, bendera ini berfungsi dalam mode bersama dan mode eksklusif; aplikasi dapat mengatur bendera ini untuk mengaktifkan buffering peristiwa untuk aliran pengambilan. Untuk informasi selengkapnya tentang menangkap aliran audio, lihat Menangkap Stream.

Untuk mengaktifkan buffering berbasis peristiwa, klien harus menyediakan handel peristiwa ke sistem. Mengikuti panggilan Inisialisasi dan sebelum memanggil metode IAudioClient::Start untuk memulai aliran, klien harus memanggil metode IAudioClient::SetEventHandle untuk mengatur penanganan aktivitas. Saat aliran berjalan, sistem secara berkala memberi sinyal peristiwa untuk menunjukkan kepada klien bahwa data audio tersedia untuk diproses. Di antara proses berlalu, utas klien menunggu pada handel peristiwa dengan memanggil fungsi sinkronisasi seperti WaitForSingleObject. Untuk informasi selengkapnya tentang fungsi sinkronisasi, lihat dokumentasi Windows SDK.

Untuk aliran mode bersama yang menggunakan buffering berbasis peristiwa, pemanggil harus mengatur hnsPeriodicity dan hnsBufferDuration ke 0. Metode Inisialisasi menentukan seberapa besar buffer untuk dialokasikan berdasarkan periode penjadwalan mesin audio. Meskipun utas pemrosesan buffer klien didorong oleh peristiwa, proses manajemen buffer dasar, seperti yang dijelaskan sebelumnya, tidak diubah. Setiap kali utas terbangun, utas harus memanggil IAudioClient::GetCurrentPadding untuk menentukan berapa banyak data yang akan ditulis ke buffer penyajian atau membaca dari buffer tangkapan. Berbeda dengan dua buffer yang dialokasikan metode Inisialisasi untuk aliran mode eksklusif yang menggunakan buffering berbasis peristiwa, aliran mode bersama memerlukan satu buffer.

Untuk aliran mode eksklusif yang menggunakan buffering berbasis peristiwa, pemanggil harus menentukan nilai bukan nol untuk hnsPeriodicity dan hnsBufferDuration, dan nilai kedua parameter ini harus sama. Metode Inisialisasi mengalokasikan dua buffer untuk aliran. Setiap buffer sama dalam durasi dengan nilai parameter hnsBufferDuration . Mengikuti panggilan Inisialisasi untuk aliran penyajian, pemanggil harus mengisi yang pertama dari dua buffer sebelum memulai aliran. Untuk aliran pengambilan, buffer awalnya kosong, dan pemanggil harus mengasumsikan bahwa setiap buffer tetap kosong sampai peristiwa untuk buffer tersebut diberi sinyal. Saat aliran berjalan, sistem secara bergantian mengirim satu buffer atau yang lain ke klien—bentuk buffering ganda ini disebut sebagai "ping-ponging". Setiap kali klien menerima buffer dari sistem (yang ditunjukkan sistem dengan memberi sinyal peristiwa), klien harus memproses seluruh buffer. Misalnya, jika klien meminta ukuran paket dari metode IAudioRenderClient::GetBuffer yang tidak cocok dengan ukuran buffer, metode gagal. Panggilan ke metode IAudioClient::GetCurrentPadding tidak perlu karena ukuran paket harus selalu sama dengan ukuran buffer. Berbeda dengan mode buffering yang dibahas sebelumnya, latensi untuk aliran mode eksklusif berbasis peristiwa bergantung langsung pada ukuran buffer.

Seperti yang dijelaskan dalam Sesi Audio, perilaku default untuk sesi yang berisi aliran penyajian adalah bahwa pengaturan volume dan bisukannya tetap ada di seluruh mulai ulang aplikasi. Bendera AUDCLNT_STREAMFLAGS_NOPERSIST mengambil alih perilaku default dan membuat pengaturan tidak konsisten. Bendera ini tidak berpengaruh pada sesi yang berisi aliran pengambilan—pengaturan untuk sesi tersebut tidak pernah persisten. Selain itu, pengaturan untuk sesi yang berisi aliran loopback (aliran yang diinisialisasi dengan bendera AUDCLNT_STREAMFLAGS_LOOPBACK) tidak persisten.

Hanya sesi yang tersambung ke perangkat titik akhir penyajian yang dapat memiliki volume persisten dan pengaturan bisukan. Aliran pertama yang ditambahkan ke sesi menentukan apakah pengaturan sesi tetap ada. Dengan demikian, jika bendera AUDCLNT_STREAMFLAGS_NOPERSIST atau AUDCLNT_STREAMFLAGS_LOOPBACK diatur selama inisialisasi aliran pertama, pengaturan sesi tidak persisten. Jika tidak, mereka persisten. Persistensinya tidak terpengaruh oleh aliran tambahan yang kemudian ditambahkan atau dihapus selama masa pakai objek sesi.

Setelah panggilan ke Inisialisasi berhasil menginisialisasi instans antarmuka IAudioClient , panggilan Inisialisasi berikutnya untuk menginisialisasi instans antarmuka yang sama akan gagal dan mengembalikan kode kesalahan E_ALREADY_INITIALIZED.

Jika panggilan awal ke Inisialisasi gagal, panggilan Inisialisasi berikutnya mungkin gagal dan mengembalikan kode kesalahan E_ALREADY_INITIALIZED, meskipun antarmuka belum diinisialisasi. Jika ini terjadi, lepaskan antarmuka IAudioClient dan dapatkan antarmuka IAudioClient baru dari MMDevice API sebelum memanggil Inisialisasi lagi.

Untuk contoh kode yang memanggil metode Inisialisasi , lihat topik berikut:

Dimulai dengan Windows 7, Inisialisasi dapat mengembalikan AUDCLNT_E_BUFFER_SIZE_NOT_ALIGNED untuk render atau perangkat pengambilan. Ini menunjukkan bahwa ukuran buffer, yang ditentukan oleh pemanggil dalam parameter hnsBufferDuration , tidak diratakan. Kode kesalahan ini dikembalikan hanya jika pemanggil meminta aliran mode eksklusif (AUDCLNT_SHAREMODE_EXCLUSIVE) dan buffering berbasis peristiwa (AUDCLNT_STREAMFLAGS_EVENTCALLBACK).

Jika Inisialisasi mengembalikan AUDCLNT_E_BUFFER_SIZE_NOT_ALIGNED, penelepon harus memanggil Inisialisasi lagi dan menentukan ukuran buffer yang diratakan. Gunakan langkah-langkah berikut:

  1. Panggil IAudioClient::GetBufferSize dan terima ukuran buffer selaras tertinggi berikutnya (dalam bingkai).
  2. Panggil IAudioClient::Release untuk merilis klien audio yang digunakan dalam panggilan sebelumnya yang mengembalikan AUDCLNT_E_BUFFER_SIZE_NOT_ALIGNED.
  3. Hitung ukuran buffer yang diratakan dalam unit 100 nanodetik (hns). Ukuran buffer adalah (REFERENCE_TIME)((10000.0 * 1000 / WAVEFORMATEX.nSamplesPerSecond * nFrames) + 0.5). Dalam rumus ini, nFrames adalah ukuran buffer yang diambil oleh GetBufferSize.
  4. Panggil metode IMMDevice::Activate dengan parameter iid diatur ke REFIID IID_IAudioClient untuk membuat klien audio baru.
  5. Panggil Inisialisasi lagi pada klien audio yang dibuat dan tentukan ukuran dan periodisitas buffer baru.

Dimulai dengan Windows 10, aliran audio yang dilepas perangkat keras harus digerakkan oleh peristiwa. Ini berarti bahwa jika Anda memanggil IAudioClient2::SetClientProperties dan mengatur parameter bIsOffloadaudioClientProperties ke TRUE, Anda harus menentukan bendera AUDCLNT_STREAMFLAGS_EVENTCALLBACK dalam parameter StreamFlags ke IAudioClient::Initialize.

Contoh

Contoh kode berikut menunjukkan cara merespons kode pengembalian 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;
}

Persyaratan

   
Target Platform Windows
Header audioclient.h

Lihat juga

Antarmuka IAudioCaptureClient

Antarmuka IAudioClient

IAudioClient::GetBufferSize

IAudioClient::GetCurrentPadding

IAudioClient::GetDevicePeriod

IAudioClient::GetMixFormat

IAudioClient::GetService

IAudioClient::SetEventHandle

IAudioClient::Start

IAudioRenderClient::GetBuffer