Bagikan melalui


Audio Latensi Rendah

Artikel ini membahas perubahan latensi audio dalam Windows 10. Ini mencakup opsi API untuk pengembang aplikasi dan perubahan driver yang dapat dilakukan untuk mendukung audio latensi rendah. Latensi audio adalah penundaan antara waktu suara dibuat dan saat suara terdengar. Memiliki latensi audio rendah penting untuk beberapa skenario utama, seperti:

  • Audio pro
  • Pembuatan musik
  • Komunikasi
  • Realitas virtual
  • Permainan

Tujuan dokumen ini adalah untuk:

  1. Menjelaskan sumber latensi audio di Windows.
  2. Jelaskan perubahan yang mengurangi latensi audio di tumpukan audio Windows 10.
  3. Berikan referensi tentang bagaimana pengembang aplikasi dan produsen perangkat keras dapat memanfaatkan infrastruktur baru, untuk mengembangkan aplikasi dan driver dengan latensi audio rendah.

Artikel ini membahas:

  1. API AudioGraph baru untuk skenario pembuatan interaktif dan media.
  2. Perubahan wasapi untuk mendukung latensi rendah.
  3. Penyempurnaan dalam DDI driver.

Terminologi

Istilah Deskripsi
Latensi render Penundaan antara waktu aplikasi mengirimkan buffer data audio ke API render, hingga waktu yang terdengar dari speaker.
Menangkap latensi Penundaan antara waktu suara diambil dari mikrofon, hingga waktu dikirim ke API pengambilan yang digunakan oleh aplikasi.
Latensi pulang-pergi Penundaan antara waktu suara ditangkap dari mikrofon, diproses oleh aplikasi dan dikirimkan oleh aplikasi untuk dirender ke speaker. Kira-kira sama dengan latensi render + latensi tangkap.
Latensi sentuh ke aplikasi Penundaan antara waktu pengguna mengetuk layar hingga waktu sinyal dikirim ke aplikasi.
Latensi sentuh ke suara Penundaan antara waktu pengguna mengetuk layar, peristiwa masuk ke aplikasi dan suara terdengar melalui speaker. Ini sama dengan merender latensi + latensi sentuh ke aplikasi.

Tumpukan audio Windows

Diagram berikut menunjukkan versi tumpukan audio Windows yang disederhanakan.

Diagram memperlihatkan tumpukan audio latensi rendah dengan aplikasi, driver mesin audio, dan perangkat keras.

Berikut adalah ringkasan latensi di jalur render: objek pemrosesan audio

  1. Aplikasi menulis data ke dalam buffer

  2. Mesin audio membaca data dari buffer dan memprosesnya. Ini juga memuat efek audio dalam bentuk objek pemrosesan audio (API). Untuk informasi selengkapnya tentang API, lihat Objek pemrosesan audio Windows.

  3. Latensi API bervariasi berdasarkan pemrosesan sinyal dalam API.

  4. Sebelum Windows 10, latensi mesin audio sama dengan ~12 ms untuk aplikasi yang menggunakan data titik mengambang dan ~6 ms untuk aplikasi yang menggunakan data bilangan bulat

  5. Dalam Windows 10 dan yang lebih baru, latensi telah dikurangi menjadi 1,3 md untuk semua aplikasi

  6. Mesin audio menulis data yang diproses ke buffer.

  7. Sebelum Windows 10, buffer selalu diatur ke ~10 ms.

  8. Dimulai dengan Windows 10, ukuran buffer ditentukan oleh driver audio (detail selengkapnya tentang buffer dijelaskan nanti dalam artikel ini).

  9. Driver Audio membaca data dari buffer dan menulisnya ke perangkat keras.

  10. Perangkat keras juga dapat memproses data lagi dalam bentuk lebih banyak efek audio.

  11. Pengguna mendengar audio dari speaker.

Berikut adalah ringkasan latensi di jalur pengambilan:

  1. Audio diambil dari mikrofon.

  2. Perangkat keras dapat memproses data. Misalnya, untuk menambahkan efek audio.

  3. Driver membaca data dari perangkat keras dan menulis data ke dalam buffer.

  4. Sebelum Windows 10, buffer ini selalu diatur ke 10 ms.

  5. Dimulai dengan Windows 10, ukuran buffer ditentukan oleh driver audio (detail selengkapnya di bawah).

  6. Mesin audio membaca data dari buffer dan memprosesnya. Ini juga memuat efek audio dalam bentuk objek pemrosesan audio (API).

  7. Latensi API bervariasi berdasarkan pemrosesan sinyal dalam API.

  8. Sebelum Windows 10, latensi mesin audio sama dengan ~6 ms untuk aplikasi yang menggunakan data titik mengambang dan ~0ms untuk aplikasi yang menggunakan data bilangan bulat.

  9. Dalam Windows 10 dan yang lebih baru, latensi telah dikurangi menjadi ~0ms untuk semua aplikasi.

  10. Aplikasi ini menandakan bahwa data tersedia untuk dibaca, segera setelah mesin audio selesai dengan pemrosesannya. Tumpukan audio juga menyediakan opsi mode eksklusif. Dalam hal ini, data melewati mesin audio dan langsung dari aplikasi ke buffer tempat driver membacanya. Namun, jika aplikasi membuka titik akhir dalam mode eksklusif, maka tidak ada aplikasi lain yang dapat menggunakan titik akhir tersebut untuk merender atau menangkap audio.

Alternatif populer lainnya untuk aplikasi yang membutuhkan latensi rendah adalah menggunakan model ASIO (Audio Stream Input/Output), yang menggunakan mode eksklusif. Setelah pengguna menginstal driver ASIO pihak ketiga, aplikasi dapat mengirim data langsung dari aplikasi ke driver ASIO. Namun, aplikasi harus ditulis singgah sehingga berbicara langsung dengan driver ASIO.

Kedua alternatif (mode eksklusif dan ASIO) memiliki batasannya sendiri. Mereka memberikan latensi rendah, tetapi mereka memiliki batasan mereka sendiri (beberapa di antaranya dijelaskan di atas). Akibatnya, mesin audio telah dimodifikasi, untuk menurunkan latensi, sambil mempertahankan fleksibilitas.

Penyempurnaan tumpukan audio

Windows 10 dan kemudian telah ditingkatkan di tiga area untuk mengurangi latensi:

  1. Semua aplikasi yang menggunakan audio akan melihat pengurangan latensi pulang-pergi 4,5-16 md (seperti yang dijelaskan di bagian di atas) tanpa perubahan kode atau pembaruan driver, dibandingkan dengan Windows 8.1.
    1. Aplikasi yang menggunakan data floating point akan memiliki latensi 16 mdtk yang lebih rendah.
    2. Aplikasi yang menggunakan data bilangan bulat akan memiliki latensi 4,5 mdtk yang lebih rendah.
  2. Sistem dengan driver yang diperbarui akan memberikan latensi pulang-pergi yang lebih rendah:
    1. Driver dapat menggunakan DDI baru untuk melaporkan ukuran buffer yang didukung yang digunakan untuk mentransfer data antara Windows dan perangkat keras. Transfer data tidak harus selalu menggunakan buffer 10 ms, seperti yang mereka lakukan di versi Windows sebelumnya. Sebagai gantinya, driver dapat menentukan apakah dapat menggunakan buffer kecil, misalnya, 5 ms, 3 ms, 1 ms, dll.
    2. Aplikasi yang memerlukan latensi rendah dapat menggunakan API audio baru (AudioGraph atau WASAPI), untuk mengkueri ukuran buffer yang didukung oleh driver dan memilih yang akan digunakan untuk transfer data ke/dari perangkat keras.
  3. Ketika aplikasi menggunakan ukuran buffer di bawah ambang tertentu untuk merender dan menangkap audio, Windows memasuki mode khusus, di mana ia mengelola sumber dayanya dengan cara yang menghindari gangguan antara streaming audio dan subsistem lainnya. Ini akan mengurangi gangguan dalam eksekusi subsistem audio dan meminimalkan kemungkinan gangguan audio. Ketika aplikasi berhenti streaming, Windows kembali ke mode eksekusi normalnya. Subsistem audio terdiri dari sumber daya berikut:
    1. Utas mesin audio yang memproses audio latensi rendah.
    2. Semua utas dan gangguan yang telah didaftarkan oleh driver (menggunakan DDI baru yang dijelaskan di bagian tentang pendaftaran sumber daya driver).
    3. Beberapa atau semua utas audio dari aplikasi yang meminta buffer kecil, dan dari semua aplikasi yang memiliki grafik perangkat audio yang sama (misalnya, mode pemrosesan sinyal yang sama) dengan aplikasi apa pun yang meminta buffer kecil:
  4. Panggilan balik AudioGraph pada jalur streaming.
  5. Jika aplikasi menggunakan WASAPI, maka hanya item kerja yang dikirimkan ke API Antrean Kerja Real Time atau MFCreateMFByteStreamOnStreamEx dan ditandai sebagai "Audio" atau "ProAudio".

Peningkatan API

Dua API Windows 10 berikut memberikan kemampuan latensi rendah:

Untuk menentukan salah satu dari dua API yang akan digunakan:

  • Pilih AudioGraph, sedapat mungkin untuk pengembangan aplikasi baru.
  • Hanya gunakan WASAPI, jika:
    • Anda memerlukan lebih banyak kontrol daripada yang disediakan oleh AudioGraph.
    • Anda memerlukan latensi yang lebih rendah daripada yang disediakan oleh AudioGraph.

Bagian alat pengukuran dari artikel ini, menunjukkan pengukuran tertentu dari sistem Haswell menggunakan driver HDAudio kotak masuk.

Bagian berikut akan menjelaskan kemampuan latensi rendah di setiap API. Seperti yang dicatat di bagian sebelumnya, agar sistem mencapai latensi minimum, sistem perlu memperbarui driver yang mendukung ukuran buffer kecil.

AudioGraph

AudioGraph adalah API Platform Windows Universal baru di Windows 10 dan yang lebih baru yang ditujukan untuk mewujudkan skenario pembuatan musik dan interaktif dengan mudah. AudioGraph tersedia dalam beberapa bahasa pemrograman (C++, C#, JavaScript) dan memiliki model pemrograman yang sederhana dan kaya fitur.

Untuk menargetkan skenario latensi rendah, AudioGraph menyediakan properti AudioGraphSettings::QuantumSizeSelectionMode . Properti ini bisa menjadi salah satu nilai yang diperlihatkan dalam tabel di bawah ini:

Nilai Deskripsi
SystemDefault Mengatur buffer ke ukuran buffer default (~10 ms)
Latensi Terendah Mengatur buffer ke nilai minimum yang didukung oleh driver
ClosestToDesired Mengatur ukuran buffer agar sama dengan nilai yang ditentukan oleh properti DesiredSamplesPerQuantum atau ke nilai yang sedekat mungkin dengan DesiredSamplesPerQuantum seperti yang didukung oleh driver.

Sampel AudioCreation memperlihatkan cara menggunakan AudioGraph untuk latensi rendah. Cuplikan kode berikut menunjukkan cara mengatur ukuran buffer minimum:

AudioGraphSettings settings = new AudioGraphSettings(AudioRenderCategory.Media);
settings.QuantumSizeSelectionMode = QuantumSizeSelectionMode.LowestLatency;
CreateAudioGraphResult result = await AudioGraph.CreateAsync(settings);

API sesi audio Windows (WASAPI)

Mulai Windows 10, WASAPI telah ditingkatkan menjadi:

  • Izinkan aplikasi untuk menemukan rentang ukuran buffer (yaitu, nilai periodisitas) yang didukung oleh driver audio perangkat audio tertentu. Ini memungkinkan aplikasi untuk memilih antara ukuran buffer default (10 ms) atau buffer kecil (kurang dari 10 ms) saat membuka aliran dalam mode bersama. Jika aplikasi tidak menentukan ukuran buffer, maka aplikasi akan menggunakan ukuran buffer default.
  • Izinkan aplikasi untuk menemukan format dan periodisitas mesin audio saat ini. Hal ini memungkinkan aplikasi untuk menaikkan ke pengaturan mesin audio saat ini.
  • Izinkan aplikasi untuk menentukan bahwa aplikasi ingin merender/mengambil dalam format yang ditentukannya tanpa pengambilan sampel ulang oleh mesin audio

Fitur di atas akan tersedia di semua perangkat Windows. Namun, perangkat tertentu dengan sumber daya yang cukup dan driver yang diperbarui akan memberikan pengalaman pengguna yang lebih baik daripada yang lain.

Fungsionalitas di atas disediakan oleh antarmuka baru, yang disebut IAudioClient3, yang berasal dari IAudioClient2.

IAudioClient3 mendefinisikan 3 metode berikut:

Metode Deskripsi
GetCurrentSharedModeEnginePeriod Mengembalikan format dan periodisitas mesin audio saat ini
GetSharedModeEnginePeriod Mengembalikan rentang periodicities yang didukung oleh mesin untuk format stream yang ditentukan
InitializeSharedAudioStream Menginisialisasi aliran bersama dengan periodisitas yang ditentukan

Sampel WASAPIAudio menunjukkan cara menggunakan IAudioClient3 untuk latensi rendah.

Cuplikan kode berikut menunjukkan bagaimana aplikasi pembuatan musik dapat beroperasi dalam pengaturan latensi terendah yang didukung oleh sistem.

// 1. Activation

// Get a string representing the Default Audio (Render|Capture) Device
m_DeviceIdString = MediaDevice::GetDefaultAudio(Render|Capture)Id(
Windows::Media::Devices::AudioDeviceRole::Default );

// This call must be made on the main UI thread.  Async operation will call back to
// IActivateAudioInterfaceCompletionHandler::ActivateCompleted, which must be an agile // interface implementation
hr = ActivateAudioInterfaceAsync( m_DeviceIdString->Data(), __uuidof(IAudioClient3),
nullptr, this, &asyncOp );

// 2. Setting the audio client properties – note that low latency offload is not supported

AudioClientProperties audioProps = {0};
audioProps.cbSize = sizeof( AudioClientProperties );
audioProps.eCategory = AudioCategory_Media;

// if the device has System.Devices.AudioDevice.RawProcessingSupported set to true and you want to use raw mode
// audioProps.Options |= AUDCLNT_STREAMOPTIONS_RAW;
//
// if it is important to avoid resampling in the audio engine, set this flag
// audioProps.Options |= AUDCLNT_STREAMOPTIONS_MATCH_FORMAT;


hr = m_AudioClient->SetClientProperties( &audioProps ); if (FAILED(hr)) { ... }

// 3. Querying the legal periods

hr = m_AudioClient->GetMixFormat( &mixFormat ); if (FAILED(hr)) { ... }

hr = m_AudioClient->GetSharedModeEnginePeriod(wfx, &defaultPeriodInFrames, &fundamentalPeriodInFrames, &minPeriodInFrames, &maxPeriodInFrames); if (FAILED(hr)) { ... }

// legal periods are any multiple of fundamentalPeriodInFrames between
// minPeriodInFrames and maxPeriodInFrames, inclusive
// the Windows shared-mode engine uses defaultPeriodInFrames unless an audio client // has specifically requested otherwise

// 4. Initializing a low-latency client

hr = m_AudioClient->InitializeSharedAudioStream(
         AUDCLNT_STREAMFLAGS_EVENTCALLBACK,
         desiredPeriodInFrames,
         mixFormat,
         nullptr); // audio session GUID
         if (AUDCLNT_E_ENGINE_PERIODICITY_LOCKED == hr) {
         /* engine is already running at a different period; call m_AudioClient->GetSharedModeEnginePeriod to see what it is */
         } else if (FAILED(hr)) {
             ...
         }

// 5. Initializing a client with a specific format (if the format needs to be different than the default format)

AudioClientProperties audioProps = {0};
audioProps.cbSize = sizeof( AudioClientProperties );
audioProps.eCategory = AudioCategory_Media;
audioProps.Options |= AUDCLNT_STREAMOPTIONS_MATCH_FORMAT;

hr = m_AudioClient->SetClientProperties( &audioProps );
if (FAILED(hr)) { ... }

hr = m_AudioClient->IsFormatSupported(AUDCLNT_SHAREMODE_SHARED, appFormat, &closest);
if (S_OK == hr) {
       /* device supports the app format */
} else if (S_FALSE == hr) {
       /* device DOES NOT support the app format; closest supported format is in the "closest" output variable */
} else {
       /* device DOES NOT support the app format, and Windows could not find a close supported format */
}

hr = m_AudioClient->InitializeSharedAudioStream(
       AUDCLNT_STREAMFLAGS_EVENTCALLBACK,
       defaultPeriodInFrames,
       appFormat,
       nullptr); // audio session GUID
if (AUDCLNT_E_ENGINE_FORMAT_LOCKED == hr) {
       /* engine is already running at a different format */
} else if (FAILED(hr)) {
       ...
}

Selain itu, Microsoft merekomendasikan untuk aplikasi yang menggunakan WASAPI untuk juga menggunakan API Antrean Kerja Real Time atau MFCreateMFByteStreamOnStreamEx untuk membuat item kerja dan menandainya sebagai Audio atau Pro Audio, bukan utas mereka sendiri. Ini akan memungkinkan Windows untuk mengelolanya dengan cara yang akan menghindari subsistem non-audio gangguan. Sebaliknya, semua utas AudioGraph dikelola secara otomatis dengan benar oleh Windows. Cuplikan kode berikut dari sampel WASAPIAudio menunjukkan cara menggunakan API Antrean Kerja MF.

// Specify Source Reader Attributes
Attributes->SetUnknown( MF_SOURCE_READER_ASYNC_CALLBACK, static_cast<IMFSourceReaderCallback *>(this) );
    if (FAILED( hr ))
    {
        goto exit;
    }
    Attributes->SetString( MF_READWRITE_MMCSS_CLASS_AUDIO, L"Audio" );
    if (FAILED( hr ))
    {
        goto exit;
    }
    Attributes->SetUINT32( MF_READWRITE_MMCSS_PRIORITY_AUDIO, 0 );
    if (FAILED( hr ))
    {
        goto exit;
    }
    // Create a stream from IRandomAccessStream
    hr = MFCreateMFByteStreamOnStreamEx (reinterpret_cast<IUnknown*>(m_ContentStream), &ByteStream );
    if ( FAILED( hr ) )
    {
        goto exit;
    }
    // Create source reader
    hr = MFCreateSourceReaderFromByteStream( ByteStream, Attributes, &m_MFSourceReader );

Atau, cuplikan kode berikut menunjukkan cara menggunakan RT Work Queue API.

#define INVALID_WORK_QUEUE_ID 0xffffffff
DWORD g_WorkQueueId = INVALID_WORK_QUEUE_ID;
//#define MMCSS_AUDIO_CLASS    L"Audio"
//#define MMCSS_PROAUDIO_CLASS L"ProAudio"

STDMETHODIMP TestClass::GetParameters(DWORD* pdwFlags, DWORD* pdwQueue)
{
       HRESULT hr = S_OK;
       *pdwFlags = 0;
       *pdwQueue = g_WorkQueueId;
       return hr;
}

//-------------------------------------------------------
STDMETHODIMP TestClass::Invoke(IRtwqAsyncResult* pAsyncResult)
{
       HRESULT hr = S_OK;
       IUnknown *pState = NULL;
       WCHAR className[20];
       DWORD  bufferLength = 20;
       DWORD taskID = 0;
       LONG priority = 0;

       printf("Callback is invoked pAsyncResult(0x%0x)  Current process id :0x%0x Current thread id :0x%0x\n", (INT64)pAsyncResult, GetCurrentProcessId(), GetCurrentThreadId());

       hr = RtwqGetWorkQueueMMCSSClass(g_WorkQueueId, className, &bufferLength);
       IF_FAIL_EXIT(hr, Exit);

       if (className[0])
       {
              hr = RtwqGetWorkQueueMMCSSTaskId(g_WorkQueueId, &taskID);
              IF_FAIL_EXIT(hr, Exit);

              hr = RtwqGetWorkQueueMMCSSPriority(g_WorkQueueId, &priority);
              IF_FAIL_EXIT(hr, Exit);
              printf("MMCSS: [%ws] taskID (%d) priority(%d)\n", className, taskID, priority);
       }
       else
       {
              printf("non-MMCSS\n");
       }
       hr = pAsyncResult->GetState(&pState);
       IF_FAIL_EXIT(hr, Exit);

Exit:
       return S_OK;
}
//-------------------------------------------------------

int _tmain(int argc, _TCHAR* argv[])
{
       HRESULT hr = S_OK;
       HANDLE signalEvent;
       LONG Priority = 1;
       IRtwqAsyncResult *pAsyncResult = NULL;
       RTWQWORKITEM_KEY workItemKey = NULL;;
       IRtwqAsyncCallback *callback = NULL;
       IUnknown *appObject = NULL;
       IUnknown *appState = NULL;
       DWORD taskId = 0;
       TestClass cbClass;
       NTSTATUS status;

       hr = RtwqStartup();
       IF_FAIL_EXIT(hr, Exit);

       signalEvent = CreateEvent(NULL, true, FALSE, NULL);
       IF_TRUE_ACTION_EXIT(signalEvent == NULL, hr = E_OUTOFMEMORY, Exit);

       g_WorkQueueId = RTWQ_MULTITHREADED_WORKQUEUE;

       hr = RtwqLockSharedWorkQueue(L"Audio", 0, &taskId, &g_WorkQueueId);
       IF_FAIL_EXIT(hr, Exit);

       hr = RtwqCreateAsyncResult(NULL, reinterpret_cast<IRtwqAsyncCallback*>(&cbClass), NULL, &pAsyncResult);
       IF_FAIL_EXIT(hr, Exit);

       hr = RtwqPutWaitingWorkItem(signalEvent, Priority, pAsyncResult, &workItemKey);
       IF_FAIL_EXIT(hr, Exit);

       for (int i = 0; i < 5; i++)
       {
              SetEvent(signalEvent);
              Sleep(30);
              hr = RtwqPutWaitingWorkItem(signalEvent, Priority, pAsyncResult, &workItemKey);
              IF_FAIL_EXIT(hr, Exit);
    }

Exit:
       if (pAsyncResult)
       {
              pAsyncResult->Release();
       }

      if (INVALID_WORK_QUEUE_ID != g_WorkQueueId)
      {
        hr = RtwqUnlockWorkQueue(g_WorkQueueId);
        if (FAILED(hr))
        {
            printf("Failed with RtwqUnlockWorkQueue 0x%x\n", hr);
        }

        hr = RtwqShutdown();
        if (FAILED(hr))
        {
            printf("Failed with RtwqShutdown 0x%x\n", hr);
        }
      }

       if (FAILED(hr))
       {
          printf("Failed with error code 0x%x\n", hr);
       }
       return 0;
}

Akhirnya, pengembang aplikasi yang menggunakan WASAPI perlu menandai aliran mereka dengan kategori audio dan apakah akan menggunakan mode pemrosesan sinyal mentah, berdasarkan fungsionalitas setiap aliran. Microsoft menyarankan agar semua aliran audio tidak menggunakan mode pemrosesan sinyal mentah, kecuali implikasinya dipahami. Mode mentah melewati semua pemrosesan sinyal yang telah dipilih oleh OEM, jadi:

  • Sinyal render untuk titik akhir tertentu mungkin suboptimal.
  • Sinyal penangkapan mungkin datang dalam format yang tidak dapat dipahami aplikasi.
  • Latensi mungkin ditingkatkan.

Peningkatan driver

Agar driver audio mendukung latensi rendah, Windows 10 dan yang lebih baru menyediakan fitur-fitur berikut:

  1. [Wajib] Deklarasikan ukuran buffer minimum yang didukung di setiap mode.
  2. [Opsional, tetapi disarankan] Meningkatkan koordinasi untuk aliran data antara driver dan Windows.
  3. [Opsional, tetapi disarankan] Daftarkan sumber daya driver (interupsi, utas), sehingga dapat dilindungi oleh Windows dalam skenario latensi rendah. Driver fungsi miniport HDAudio yang dijumlahkan oleh driver bus HDAudio kotak masuk hdaudbus.sys tidak perlu mendaftarkan gangguan HDAudio, karena ini sudah dilakukan oleh hdaudbus.sys. Namun, jika driver miniport membuat utasnya sendiri, maka ia perlu mendaftarkannya.

Tiga bagian berikut akan menjelaskan setiap fitur baru secara lebih mendalam.

Mendeklarasikan ukuran buffer minimum

Driver beroperasi di bawah berbagai batasan saat memindahkan data audio antara Windows, driver, dan perangkat keras. Kendala ini mungkin disebabkan oleh transportasi perangkat keras fisik yang memindahkan data antara memori dan perangkat keras, atau karena modul pemrosesan sinyal dalam perangkat keras atau DSP terkait.

Mulai Windows 10, versi 1607, driver dapat mengekspresikan kemampuan ukuran buffernya menggunakan properti perangkat DEVPKEY_KsAudio_PacketSize_Constraints2. Properti ini memungkinkan pengguna untuk menentukan ukuran buffer minimum absolut yang didukung oleh driver, dan batasan ukuran buffer tertentu untuk setiap mode pemrosesan sinyal. Batasan khusus mode harus lebih tinggi dari ukuran buffer minimum driver, jika tidak, batasan tersebut diabaikan oleh tumpukan audio.

Misalnya, cuplikan kode berikut menunjukkan bagaimana driver dapat menyatakan bahwa ukuran buffer minimum yang didukung absolut adalah 2 ms, tetapi mode default mendukung 128 bingkai, yang sesuai dengan 3 ms jika kita mengasumsikan laju sampel 48 kHz.

 
//
// Describe buffer size constraints for WaveRT buffers
//
static struct
{
    KSAUDIO_PACKETSIZE_CONSTRAINTS2 TransportPacketConstraints;
    KSAUDIO_PACKETSIZE_PROCESSINGMODE_CONSTRAINT AdditionalProcessingConstraints[1];
} SysvadWaveRtPacketSizeConstraintsRender =
{
    {
        2 * HNSTIME_PER_MILLISECOND,                // 2 ms minimum processing interval
        FILE_BYTE_ALIGNMENT,                        // 1 byte packet size alignment
        0,                                          // no maximum packet size constraint
        2,                                          // 2 processing constraints follow
        {
            STATIC_AUDIO_SIGNALPROCESSINGMODE_DEFAULT,          // constraint for default processing mode
            128,                                                // 128 samples per processing frame
            0,                                                  // NA hns per processing frame
        },
    },
    {
        {
            STATIC_AUDIO_SIGNALPROCESSINGMODE_MOVIE,            // constraint for movie processing mode
            1024,                                               // 1024 samples per processing frame
            0,                                                  // NA hns per processing frame
        },
    }
};

Lihat artikel berikut untuk informasi lebih mendalam mengenai struktur ini:

Selain itu, sampel sysvad menunjukkan cara menggunakan properti ini, agar driver mendeklarasikan buffer minimum untuk setiap mode.

Meningkatkan koordinasi antara driver dan OS

DDI yang dijelaskan di bagian ini memungkinkan driver untuk:

  • Jelas menunjukkan setengah (paket) buffer mana yang tersedia untuk Windows, daripada tebakan OS berdasarkan posisi tautan codec. Ini membantu Windows pulih dari gangguan audio lebih cepat.
  • Secara opsional mengoptimalkan atau menyederhanakan transfer datanya masuk dan keluar dari buffer WaveRT. Jumlah manfaat di sini tergantung pada desain mesin DMA atau mekanisme transfer data lainnya antara buffer WaveRT dan perangkat keras (mungkin DSP).
  • "Burst" mengambil data lebih cepat daripada real-time jika driver telah mengumpulkan data yang ditangkap secara internal. Ini terutama ditujukan untuk skenario aktivasi suara tetapi juga dapat berlaku selama streaming normal.
  • Berikan informasi tanda waktu tentang posisi streaming saat ini daripada tebakan Windows, yang berpotensi memungkinkan informasi posisi yang akurat.

DDI ini berguna dalam kasus ini, di mana DSP digunakan. Namun, driver HD Audio standar atau desain buffer DMA melingkar sederhana lainnya mungkin tidak menemukan banyak manfaat dalam DDI baru ini yang tercantum di sini.

Beberapa rutinitas driver mengembalikan tanda waktu penghitung kinerja Windows yang mencerminkan waktu pengambilan sampel atau disajikan oleh perangkat.

Dalam perangkat yang memiliki alur DSP yang kompleks dan pemrosesan sinyal, menghitung tanda waktu yang akurat mungkin menantang dan harus dilakukan dengan bijaksana. Tanda waktu tidak boleh mencerminkan waktu di mana sampel ditransfer ke atau dari Windows ke DSP.

Untuk menghitung nilai penghitung kinerja, driver dan DSP mungkin menggunakan beberapa metode berikut.

  • Dalam DSP, lacak stempel waktu sampel menggunakan beberapa jam dinding DSP internal.
  • Antara driver dan DSP, hitung korelasi antara penghitung kinerja Windows dan jam dinding DSP. Prosedur untuk ini dapat berkisar dari sederhana (tetapi kurang tepat) hingga cukup kompleks atau baru (tetapi lebih tepat).
  • Faktor dalam setiap penundaan konstan karena algoritma pemrosesan sinyal atau alur atau transportasi perangkat keras, kecuali penundaan ini diperhitungkan sebaliknya.

Sampel sysvad menunjukkan cara menggunakan DDI di atas.

Mendaftarkan sumber daya driver

Untuk membantu memastikan operasi bebas glitch, driver audio harus mendaftarkan sumber daya streaming mereka dengan Portcls. Ini memungkinkan Windows mengelola sumber daya untuk menghindari gangguan antara streaming audio dan subsistem lainnya.

Sumber daya streaming adalah sumber daya apa pun yang digunakan oleh driver audio untuk memproses aliran audio atau memastikan aliran data audio. Hanya dua jenis sumber daya aliran yang didukung: interupsi dan utas milik driver. Driver audio harus mendaftarkan sumber daya setelah membuat sumber daya, dan membatalkan pendaftaran sumber daya sebelum menghapusnya.

Driver audio dapat mendaftarkan sumber daya pada waktu inisialisasi ketika driver dimuat, atau pada run-time, misalnya ketika ada penyeimbangan ulang sumber daya I/O. Portcls menggunakan status global untuk melacak semua sumber daya streaming audio.

Dalam beberapa kasus penggunaan, seperti yang membutuhkan audio latensi yang sangat rendah, Windows mencoba mengisolasi sumber daya terdaftar driver audio dari gangguan dari OS, aplikasi, dan aktivitas perangkat keras lainnya. Subsistem OS dan audio melakukan ini sesuai kebutuhan tanpa berinteraksi dengan driver audio, kecuali untuk pendaftaran driver audio sumber daya.

Persyaratan untuk mendaftarkan sumber daya aliran ini menyiratkan bahwa semua driver yang berada di jalur alur streaming harus mendaftarkan sumber daya mereka secara langsung atau tidak langsung dengan Portcls. Driver miniport audio memiliki opsi berikut:

  • Driver miniport audio adalah driver bawah dari tumpukannya (menginterogasi jam / w secara langsung), dalam hal ini, driver tahu sumber daya alirannya dan dapat mendaftarkannya dengan Portcls.
  • Driver miniport audio mengalirkan audio dengan bantuan driver lain (misalnya driver bus audio). Driver lain ini juga menggunakan sumber daya yang harus didaftarkan ke Portcls. Tumpukan driver paralel/bus ini dapat mengekspos antarmuka publik (atau pribadi, jika satu vendor memiliki semua driver) yang digunakan driver miniport audio untuk mengumpulkan info ini.
  • Driver miniport audio mengalirkan audio dengan bantuan driver lain (misalnya hdaudbus). Driver lain ini juga menggunakan sumber daya yang harus didaftarkan ke Portcls. Driver paralel/bus ini dapat terhubung dengan Portcls dan langsung mendaftarkan sumber daya mereka. Driver miniport audio harus memberi tahu Portcls bahwa mereka bergantung pada sumber daya perangkat paralel/bus (PDO) lainnya. Infrastruktur audio HD menggunakan opsi ini, yaitu, driver bus audio HD ditautkan dengan Portcls dan secara otomatis melakukan langkah-langkah berikut:
    • mendaftarkan sumber daya pengemudi busnya, dan
    • memberi tahu Portcls bahwa sumber daya anak bergantung pada sumber daya induk. Dalam arsitektur audio HD, driver miniport audio hanya perlu mendaftarkan sumber daya utas milik driver sendiri.

Catatan:

  • Driver fungsi miniport HDAudio yang dihitung oleh driver bus HDAudio kotak masuk hdaudbus.sys tidak perlu mendaftarkan interupsi HDAudio, karena ini sudah dilakukan oleh hdaudbus.sys. Namun, jika driver miniport membuat utasnya sendiri, maka ia perlu mendaftarkannya.
  • Driver yang menautkan dengan Portcls hanya untuk mendaftarkan sumber daya streaming harus memperbarui INF mereka untuk menyertakan wdmaudio.inf dan menyalin portcls.sys (dan file dependen). Bagian salinan INF baru didefinisikan dalam wdmaudio.inf untuk hanya menyalin file-file tersebut.
  • Driver audio yang hanya berjalan di Windows 10 dan nantinya dapat melakukan hard-link ke:
  • Driver audio yang harus berjalan pada OS tingkat bawah dapat menggunakan antarmuka berikut (miniport dapat memanggil QueryInterface untuk antarmuka IID_IPortClsStreamResourceManager dan mendaftarkan sumber dayanya hanya ketika PortCls mendukung antarmuka).
  • DDI ini, gunakan enumerasi dan struktur ini:

Terakhir, driver yang menautkan PortCls untuk tujuan tunggal mendaftarkan sumber daya harus menambahkan dua baris berikut di bagian DDInstall inf mereka. Driver miniport audio tidak memerlukan ini karena mereka sudah memiliki include/need dalam wdmaudio.inf.

[<install-section-name>]
Include=wdmaudio.inf
Needs=WDMPORTCLS.CopyFilesOnly

Baris di atas memastikan bahwa PortCls dan file dependennya diinstal.

Alat pengukuran

Untuk mengukur latensi pulang pergi, pengguna dapat menggunakan alat yang memutar pulsa melalui speaker dan menangkapnya melalui mikrofon. Mereka mengukur penundaan jalur berikut:

  1. Aplikasi memanggil API render (AudioGraph atau WASAPI) untuk memutar pulsa
  2. Audio diputar melalui speaker
  3. Audio diambil dari mikrofon
  4. Pulsa terdeteksi oleh API tangkapan (AudioGraph atau WASAPI) Untuk mengukur latensi pulang pergi untuk ukuran buffer yang berbeda, pengguna perlu menginstal driver yang mendukung buffer kecil. Driver HDAudio kotak masuk telah diperbarui untuk mendukung ukuran buffer antara 128 sampel (2.66ms@48kHz) dan 480 sampel (10ms@48kHz). Langkah-langkah berikut menunjukkan cara menginstal driver HDAudio kotak masuk (yang merupakan bagian dari semua Windows 10 dan SKU yang lebih baru):
  • Mulai Manajer Perangkat.
  • Di bawah Pengontrol video dan game suara, klik dua kali pada perangkat yang sesuai dengan speaker internal Anda.
  • Di jendela berikutnya, buka tab Driver .
  • Pilih Perbarui driver ->Telusuri komputer saya untuk perangkat lunak pengandar ->Biarkan saya memilih dari daftar driver perangkat di komputer ini ->Pilih Perangkat Audio Definisi Tinggi dan pilih Berikutnya.
  • Jika jendela berjudul "Perbarui peringatan driver" muncul, pilih Ya.
  • Pilih tutup.
  • Jika Anda diminta untuk me-reboot sistem, pilih Ya untuk reboot.
  • Setelah reboot, sistem akan menggunakan driver microsoft HDAudio kotak masuk dan bukan driver codec pihak ketiga. Ingat driver mana yang Anda gunakan sebelumnya sehingga Anda dapat kembali ke driver tersebut jika Anda ingin menggunakan pengaturan optimal untuk codec audio Anda.

Grafik yang mengilustrasikan perbedaan latensi pulang-pergi antara WASAPI dan AudioGraph untuk berbagai ukuran buffer.

Perbedaan latensi antara WASAPI dan AudioGraph disebabkan oleh alasan berikut:

  • AudioGraph menambahkan satu buffer latensi di sisi pengambilan, untuk menyinkronkan render dan pengambilan, yang tidak disediakan oleh WASAPI. Penambahan ini menyederhanakan kode untuk aplikasi yang ditulis menggunakan AudioGraph.
  • Ada buffer latensi lain di sisi render AudioGraph ketika sistem menggunakan buffer yang lebih besar dari 6 ms.
  • AudioGraph tidak memiliki opsi untuk menonaktifkan pengambilan efek audio.

Sampel

FAQ

Bukankah lebih baik, jika semua aplikasi menggunakan API baru untuk latensi rendah? Apakah latensi rendah tidak selalu menjamin pengalaman pengguna yang lebih baik?

Belum tentu. Latensi rendah memiliki tradeoff:

  • Latensi rendah berarti konsumsi daya yang lebih tinggi. Jika sistem menggunakan buffer 10 ms, itu berarti bahwa CPU akan bangun setiap 10 md, mengisi buffer data dan tidur. Namun, jika sistem menggunakan buffer 1-ms, itu berarti bahwa CPU akan bangun setiap 1 ms. Dalam skenario kedua, ini berarti bahwa CPU akan lebih sering bangun dan konsumsi daya akan meningkat. Ini akan mengurangi masa pakai baterai.
  • Sebagian besar aplikasi mengandalkan efek audio untuk memberikan pengalaman pengguna terbaik. Misalnya, pemutar media ingin menyediakan audio dengan keakuratan tinggi. Aplikasi komunikasi ingin gema dan kebisingan minimum. Menambahkan jenis efek audio ini ke aliran akan meningkatkan latensinya. Aplikasi ini lebih tertarik pada kualitas audio daripada dalam latensi audio.

Singkatnya, setiap jenis aplikasi memiliki kebutuhan yang berbeda mengenai latensi audio. Jika aplikasi tidak memerlukan latensi rendah, aplikasi tidak boleh menggunakan API baru untuk latensi rendah.

Apakah semua sistem yang diperbarui ke Windows 10 dan nantinya akan diperbarui secara otomatis untuk mendukung buffer kecil? Apakah semua sistem akan mendukung ukuran buffer minimum yang sama?

Tidak, agar sistem mendukung buffer kecil, sistem perlu memperbarui driver. Terserah OEM untuk memutuskan sistem mana yang akan diperbarui untuk mendukung buffer kecil. Selain itu, sistem yang lebih baru lebih mungkin mendukung buffer yang lebih kecil daripada sistem yang lebih lama. Latensi dalam sistem baru kemungkinan besar akan lebih rendah dari sistem yang lebih lama.

Jika driver mendukung ukuran buffer kecil, apakah semua aplikasi di Windows 10 dan nantinya secara otomatis menggunakan buffer kecil untuk merender dan mengambil audio?

Tidak, secara default semua aplikasi di Windows 10 dan yang lebih baru akan menggunakan buffer 10 ms untuk merender dan mengambil audio. Jika aplikasi perlu menggunakan buffer kecil, maka aplikasi perlu menggunakan pengaturan AudioGraph baru atau antarmuka WASAPI IAudioClient3, untuk melakukannya. Namun, jika satu aplikasi meminta penggunaan buffer kecil, maka mesin audio akan mulai mentransfer audio menggunakan ukuran buffer tertentu. Dalam hal ini, semua aplikasi yang menggunakan titik akhir dan mode yang sama akan secara otomatis beralih ke ukuran buffer kecil tersebut. Ketika aplikasi latensi rendah keluar, mesin audio akan beralih ke buffer 10 ms lagi.