Bagikan melalui


Properti Posisi Audio

Klien driver audio menggunakan properti KSPROPERTY_AUDIO_POSITION untuk mendapatkan dan mengatur posisi saat ini dalam aliran audio. Properti menggunakan struktur KSAUDIO_POSITION untuk menjelaskan posisi saat ini. Struktur berisi dua anggota: PlayOffset dan WriteOffset.

Anggota PlayOffset dan WriteOffset menentukan batas wilayah buffer klien yang saat ini dicadangkan untuk penggunaan eksklusif perangkat audio. Klien harus mengasumsikan bahwa perangkat saat ini mungkin mengakses salah satu data yang terkandung di wilayah ini. Oleh karena itu, klien hanya boleh mengakses bagian buffer yang terletak di luar wilayah ini. Batas wilayah bergerak saat aliran maju.

Jika buffer klien diulang (yaitu, jenis aliran KSINTERFACE_STANDARD_LOOPED_STREAMING), PlayOffset dan WriteOffset adalah offset relatif buffer. Artinya, mereka ditentukan sebagai offset byte dari awal buffer klien yang diulang. Ketika salah satu kenaikan offset ke akhir buffer, itu membungkus sekitar ke awal buffer. (Offset pada awal buffer adalah nol.) Dengan demikian, offset tidak pernah melebihi ukuran buffer.

Jika buffer klien nonlooped (yaitu, jenis stream KSINTERFACE_STANDARD_STREAMING), PlayOffset dan WriteOffset adalah offset stream-relative. Artinya, mereka ditentukan sebagai offset byte dari awal aliran. Offset ini dapat dianggap sebagai offset menjadi buffer ideal yang berisi seluruh aliran dan berdampingan dari awal hingga akhir.

Dalam kasus aliran render, anggota PlayOffset menentukan posisi pemutaran aliran, dan anggota WriteOffset menentukan posisi tulis aliran. Gambar berikut menunjukkan posisi putar dan tulis di buffer klien.

Diagram yang mengilustrasikan posisi putar dan tulis dalam aliran render.

Posisi bermain adalah offset byte dari sampel yang saat ini sedang dimainkan (yaitu, sampel yang dikaitkan pada input konverter digital-ke-analog, atau DAC). Posisi tulis adalah posisi di luar mana klien dapat menulis dengan aman ke buffer. Saat streaming diputar, posisi putar dan tulis bergerak dari kiri ke kanan pada gambar sebelumnya. Penulisan klien harus tetap berada di depan posisi tulis. Selain itu, jika buffer diulang, penulisan klien tidak boleh menyalip posisi bermain.

Meskipun driver port WaveCyclic atau WavePci mengandalkan driver miniport untuk melacak posisi bermain, driver port melacak posisi tulis. Driver port WaveCyclic dan WavePci memperbarui posisi tulis sebagai berikut:

  • WaveCyclic

    Setiap kali driver port WaveCyclic memanggil IDmaChannel::CopyTo untuk menyalin blok data baru ke buffer siklik (dari buffer klien), posisi tulis maju ke lokasi (di buffer klien) dari byte terakhir di blok data.

  • WavePci

    Secara default, setiap kali driver miniport WavePci memanggil IPortWavePciStream::GetMapping untuk memperoleh pemetaan baru (dari sebagian buffer klien) dan panggilan berhasil, posisi tulis maju ke lokasi (di buffer klien) dari byte terakhir dalam pemetaan baru.

    Jika driver miniport WavePci mengambil alih perilaku default dengan menentukan offset prefetch ke driver port, posisi tulis saat ini selalu sama dengan jumlah posisi putar saat ini dan offset prefetch. Untuk informasi selengkapnya, lihat Offset Prefetch.

Dalam kasus aliran pengambilan, anggota PlayOffset menentukan posisi rekaman aliran, dan anggota WriteOffset menentukan posisi baca aliran. Gambar berikut menunjukkan posisi rekaman dan baca di buffer klien.

Diagram yang mengilustrasikan posisi rekaman dan baca dalam aliran pengambilan.

Posisi rekaman adalah offset byte dari sampel terbaru yang akan di-latch pada output konverter analog-ke-digital, atau ADC. (Posisi ini menentukan lokasi buffer tempat mesin DMA perangkat audio pada akhirnya akan menulis sampel.) Posisi baca adalah posisi di luar mana klien tidak dapat membaca dengan aman dari buffer. Saat rekaman aliran berlangsung, posisi baca dan rekam maju dari kiri ke kanan pada gambar sebelumnya. Bacaan klien harus mengikuti posisi baca. Selain itu, jika buffer diulang, bacaan klien harus tetap berada di depan posisi rekaman.

Meskipun driver port WaveCyclic atau WavePci mengandalkan driver miniport untuk melacak posisi rekor, driver port melacak posisi baca. Driver port WaveCyclic dan WavePci memperbarui posisi baca sebagai berikut:

  • WaveCyclic

    Setiap kali driver port WaveCyclic memanggil IDmaChannel::CopyFrom untuk menyalin blok data baru dari buffer siklik (ke buffer klien), posisi baca maju ke lokasi (di buffer klien) byte terakhir di blok data.

  • WavePci

    Setiap kali driver miniport WavePci memanggil IPortWavePciStream::ReleaseMapping untuk merilis pemetaan yang diperoleh sebelumnya (dari sebagian buffer klien), posisi baca maju ke lokasi (di buffer klien) dari byte terakhir dalam pemetaan yang dirilis.

Driver Miniport tidak perlu menerapkan rutinitas handler untuk permintaan properti KSPROPERTY_AUDIO_POSITION. Sebaliknya, driver port WaveCyclic dan WavePci menangani permintaan ini atas nama driver miniport. Saat menangani permintaan get-property, driver port WaveCyclic atau WavePci sudah memiliki semua informasi yang diperlukan untuk menghitung nilai WriteOffset , tetapi masih memerlukan informasi dari driver miniport untuk menghitung nilai PlayOffset . Untuk mendapatkan informasi ini, driver port memanggil metode IMiniportWaveCyclicStream::GetPosition driver miniport atau IMiniportWavePciStream::GetPosition .

Untuk aliran render, metode GetPosition mengambil posisi putar - offset byte dari sampel yang saat ini sedang dimainkan melalui DAC. Untuk aliran pengambilan, metode GetPosition mengambil posisi rekaman - offset byte dari sampel terbaru yang akan ditangkap oleh ADC.

Perhatikan bahwa nilai offset yang diambil oleh panggilan GetPosition adalah posisi putar yang sesuai dengan sinyal yang saat ini ditransmisikan melalui jack speaker atau posisi rekaman yang sesuai dengan sinyal yang saat ini diterima melalui jack mikrofon. Ini bukan posisi DMA. (Posisi DMA adalah offset byte dari sampel yang saat ini ditransfer mesin DMA di perangkat audio ke atau dari buffer DMA.)

Beberapa perangkat keras audio berisi register posisi untuk melacak offset byte sampel yang saat ini ada di setiap DAC atau ADC, dalam hal ini metode GetPosition hanya mengambil konten register posisi untuk aliran yang sesuai. Perangkat keras audio lainnya hanya dapat menyediakan driver dengan posisi DMA, dalam hal ini metode GetPosition harus memberikan perkiraan terbaik dari offset byte sampel di DAC atau ADC dengan mempertimbangkan posisi DMA saat ini dan penundaan buffering internal ke perangkat.

Meskipun handler properti di driver port WaveCyclic atau WavePci harus membedakan antara buffer loop dan nonlooped untuk menentukan apakah akan memberikan offset byte relatif stream atau buffer-relative, detail ini (yaitu, apakah buffer diulang atau tidak) transparan untuk driver miniport.

Metode IMiniportWaveCyclicStream::GetPosition selalu melaporkan buffer-relative play atau posisi rekaman terlepas dari apakah buffer klien diulang atau tidak. Jika buffer klien diulang, handler properti mengonversi posisi relatif buffer yang dilaporkan oleh driver miniport, yang dinyatakan sebagai offset ke dalam buffer siklik, ke offset ke buffer klien, yang kemudian ditulis oleh handler ke anggota PlayOffset . Jika buffer klien tidak di-loopsi, handler properti mengonversi posisi putar relatif buffer ke posisi putar relatif aliran sebelum menulisnya ke anggota PlayOffset .

Metode IMiniportWavePciStream::GetPosition selalu melaporkan pemutaran atau posisi rekaman stream-relative terlepas dari apakah buffer klien diulang atau tidak. Jika buffer klien diulang, handler properti mengonversi posisi pemutaran relatif aliran ke posisi putar relatif buffer (dinyatakan sebagai offset ke dalam buffer klien) sebelum menulisnya ke anggota PlayOffset dalam struktur KSAUDIO_POSITION dalam permintaan properti. Jika buffer klien tidak di-loopsi, handler properti menulis posisi stream-relative ke anggota PlayOffset .

Posisi putar atau rekam adalah nol segera setelah inisialisasi aliran. Transisi ke status KSSTATE_STOP (lihat KSSTATE) mengatur ulang posisi ke nol. Saat aliran dihentikan oleh transisi dari KSSTATE_RUN ke KSSTATE_PAUSE atau KSSTATE_ACQUIRE, posisi membeku. Ini tidak akan terjadi ketika aliran beralih dari KSSTATE_PAUSE atau KSSTATE_ACQUIRE kembali ke KSSTATE_RUN.

Misalnya implementasi metode GetPosition untuk driver miniport WaveCyclic dan WavePci, lihat contoh driver audio di Windows Driver Kit (WDK).