Bagikan melalui


Audio Latensi Rendah

Artikel ini membahas perubahan latensi audio di 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 saat suara dibuat dan saat suara tersebut didengar. 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. AudioGraph API untuk skenario interaktif dan pembuatan media.
  2. Perubahan WASAPI untuk mendukung latensi rendah.
  3. Peningkatan pada antarmuka perangkat lunak driver (DDI).

Terminologi

Istilah Deskripsi
Render latensi Penundaan antara waktu aplikasi mengirimkan buffer data audio ke API render, sampai waktu suara tersebut didengar dari speaker.
Menangkap latensi Penundaan antara waktu suara diambil dari mikrofon hingga saat suara dikirim ke API penangkapan yang sedang digunakan oleh aplikasi.
Latensi pulang pergi Penundaan antara waktu suara diambil dari mikrofon, diproses oleh aplikasi, dan disampaikan oleh aplikasi untuk diputar 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 antara Sentuhan dan Suara Penundaan antara waktu ketika pengguna mengetuk layar, peristiwa tersebut dikirim ke aplikasi, dan suara terdengar melalui speaker. Ini sama dengan latensi render + latensi dari sentuhan ke aplikasi.

Lapisan 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 objek pemrosesan audio (APOs), 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 floating point dan ~6 ms untuk aplikasi yang menggunakan data bilangan bulat

  5. Di Windows 10 dan yang lebih baru, latensi telah dikurangi menjadi 1,3 ms 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 di 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 floating point dan ~0ms untuk aplikasi yang menggunakan data bilangan bulat.

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

  10. Aplikasi ini memberi sinyal bahwa data tersedia untuk dibaca, segera setelah mesin audio selesai dengan pemrosesannya. Stack audio juga menghadirkan opsi mode eksklusif. Dalam hal ini, data melewati mesin audio dan ditransfer langsung dari aplikasi ke buffer yang dibaca oleh driver. Namun, jika aplikasi membuka titik akhir dalam mode eksklusif, maka tidak ada aplikasi lain yang dapat menggunakan titik akhir tersebut untuk merender atau mengambil 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 sedemikian rupa sehingga berinteraksi langsung dengan driver ASIO.

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

Peningkatan sistem audio

Windows 10 dan yang lebih baru telah ditingkatkan di tiga area untuk mengurangi latensi:

  1. Semua aplikasi yang menggunakan audio akan melihat pengurangan 4,5-16 mdtk dalam latensi pulang pergi (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 latensi rendah 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 latensi rendah (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 benang dan interupsi yang telah didaftarkan oleh driver (menggunakan DDI latensi rendah sebagaimana 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 di jalur streaming.
  5. Jika aplikasi menggunakan WASAPI, maka hanya item kerja yang dikirimkan ke Real-Time Work Queue API 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:

  • Mendukung 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 di artikel ini menampilkan pengukuran spesifik dari sistem Haswell menggunakan driver HDAudio bawaan.

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

AudioGraph

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

Untuk menargetkan skenario latensi rendah, AudioGraph menyediakan properti AudioGraphSettings::QuantumSizeSelectionMode. Properti ini dapat berupa salah satu nilai yang ditampilkan dalam tabel di bawah ini:

Nilai Deskripsi
Bawaan Sistem Mengatur buffer ke ukuran buffer default (~10 ms)
Latensi Terendah Mengatur buffer ke nilai minimum yang didukung oleh driver
Terdekat dengan Yang Diinginkan Mengatur ukuran buffer agar sama dengan nilai yang ditentukan oleh properti DesiredSamplesPerQuantum atau ke nilai yang sedekat mungkin dengan DesiredSamplesPerQuantum yang didukung oleh driver.

Sampel AudioCreation menunjukkan 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 menemukan rentang ukuran buffer (yaitu, nilai berkala) 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. Ini memungkinkan aplikasi untuk menyesuaikan dengan pengaturan audio saat ini.
  • Izinkan aplikasi 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, yang disebut IAudioClient3, yang berasal dari IAudioClient2.

IAudioClient3 menentukan 3 metode berikut:

Metode Deskripsi
GetCurrentSharedModeEnginePeriod Mengembalikan format dan periodisitas mesin audio saat ini
GetSharedModeEnginePeriod Mengembalikan rentang periode yang didukung oleh mesin untuk format aliran yang ditentukan
InitializeSharedAudioStream Menginisialisasi aliran yang dibagikan dengan periodicitas 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 aplikasi yang menggunakan WASAPI untuk juga menggunakan Real-Time Work Queue API atau MFCreateMFByteStreamOnStreamEx untuk membuat item kerja dan menandainya sebagai Audio atau Pro Audio, alih-alih utas mereka sendiri. Ini akan memungkinkan Windows mengelolanya dengan cara yang akan menghindari gangguan pada subsistem non-audio. 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 berikut:

  1. [Wajib] Deklarasikan ukuran buffer minimum yang didukung di setiap mode.
  2. [Opsional, tetapi disarankan] Tingkatkan 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 didaftarkan oleh driver bus HDAudio bawaan hdaudbus.sys tidak perlu mendaftarkan interupsi HDAudio, karena ini sudah dilakukan oleh hdaudbus.sys. Namun, jika driver miniport membuat utasnya sendiri, maka driver tersebut perlu mendaftarkannya.

Tiga bagian berikut akan menjelaskan setiap fitur 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 absolut yang didukung 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:

  • Dengan jelas menunjukkan bagian setengah (paket) mana dari buffer yang tersedia untuk Windows, daripada membiarkan OS menebak berdasarkan posisi tautan pada 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).
  • "Mode 'burst' menangkap data lebih cepat daripada waktu nyata jika driver telah secara internal mengumpulkan data yang ditangkap." Ini terutama ditujukan untuk skenario aktivasi suara tetapi juga dapat berlaku selama streaming normal.
  • Berikan informasi tanda waktu tentang posisi alirannya 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 yang disebutkan 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 cermat. 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 suatu 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).
  • Memperhitungkan penundaan tetap apa pun karena algoritma pemrosesan sinyal atau jalur pemrosesan atau perangkat keras, kecuali jika penundaan ini sudah diperhitungkan.

Sampel sysvad menunjukkan cara menggunakan DDI di atas.

Mendaftarkan sumber daya pengandar

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 sistem operasi dan audio melakukan hal ini sesuai kebutuhan tanpa berinteraksi dengan driver audio, kecuali untuk pendaftaran sumber daya oleh driver audio.

Persyaratan ini untuk mendaftarkan sumber daya aliran 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 tumpukannya (menghubungkan h/w secara langsung), dalam hal ini, driver mengetahui sumber daya alirannya dan dapat mendaftarkannya dengan Portcls.
  • Driver miniport audio menjalankan streaming audio dengan bantuan driver lain (misalnya, driver bus audio). Driver lain ini juga menggunakan sumber daya yang harus didaftarkan dengan Portcls. Tumpukan driver paralel/bus ini dapat mengekspos antarmuka publik (atau privat, jika satu vendor memiliki semua driver) yang digunakan driver miniport audio untuk mengumpulkan info ini.
  • Driver miniport audio memutar audio dengan dukungan driver lain (misalnya hdaudbus). Driver lain ini juga menggunakan sumber daya yang harus didaftarkan dengan Portcls. Driver paralel/bus ini dapat menautkan 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 ini. Infrastruktur audio HD menggunakan opsi ini, yaitu, driver hd audio-bus ditautkan dengan Portcls dan secara otomatis melakukan langkah-langkah berikut:
    • mendaftarkan sumber daya pengemudi busnya, dan
    • memberi tahu Portcls bahwa sumber daya-milik anak bergantung pada sumber daya-milik induk. Dalam arsitektur audio HD, driver audio miniport hanya perlu mendaftarkan sumber daya utas yang dimiliki oleh driver sendiri.

Catatan:

  • Driver fungsi miniport HDAudio yang didaftarkan oleh driver bus HDAudio bawaan hdaudbus.sys tidak perlu mendaftarkan interupsi HDAudio, karena ini sudah dilakukan oleh hdaudbus.sys. Namun, jika driver miniport membuat utasnya sendiri, maka driver tersebut 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 yang lebih baru 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 berikut:

Terakhir, driver yang menautkan PortCls untuk tujuan tunggal mendaftarkan sumber daya harus menambahkan dua baris berikut pada bagian DDInstall dari inf mereka. Driver miniport audio tidak memerlukan ini karena mereka sudah memiliki include/need di 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 memancarkan pulsa melalui speaker dan menangkapnya melalui mikrofon. Mereka mengukur penundaan jalur berikut:

  1. Aplikasi memanggil API render (AudioGraph atau WASAPI) untuk memutar suara
  2. Audio diputar melalui speaker
  3. Audio diambil dari mikrofon
  4. Denyut nadi 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 SKU Windows 10 dan yang lebih baru):
  • Mulai Manajer Perangkat.
  • Di bawah Pengontrol suara video dan game, klik ganda pada perangkat yang sesuai dengan speaker internal Anda.
  • Di jendela berikutnya, buka tab Driver.
  • Pilih Perbarui driver ->Telusuri komputer saya untuk perangkat lunak driver ->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 memulai ulang.
  • Setelah reboot, sistem akan menggunakan driver bawaan Microsoft HDAudio 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 pada sisi penangkapan untuk menyinkronkan render dan penangkapan, yang tidak disediakan oleh WASAPI. Penambahan ini menyederhanakan kode untuk aplikasi yang ditulis menggunakan AudioGraph.
  • Ada buffer latensi lain di sisi render AudioGraph saat 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? Tidakkah latensi rendah selalu menjamin pengalaman pengguna yang lebih baik?

Belum tentu. Latensi rendah memiliki kompromi.

  • Latensi rendah berarti konsumsi daya yang lebih tinggi. Jika sistem menggunakan buffer 10 ms, itu berarti bahwa CPU akan bangun setiap 10 ms, isi 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 bertujuan untuk meminimalkan gema dan kebisingan. 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 yang lebih baru 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 yang lebih baru akan 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.