Sdílet prostřednictvím


Zvuk s nízkou latencí

Tento článek popisuje změny latence zvuku ve Windows 10. Popisuje možnosti rozhraní API pro vývojáře aplikací a změny ovladačů, které je možné provést pro podporu zvuku s nízkou latencí. Latence zvuku je prodleva mezi tímto časem, kdy se zvuk vytvoří a kdy je slyšet. Nízká latence zvuku je důležitá pro několik klíčových scénářů, například:

  • Zvuk Pro
  • Tvorba hudby
  • Komunikace
  • Virtuální realita
  • Hry

Cílem tohoto dokumentu je:

  1. Popište zdroje latence zvuku ve Windows.
  2. Vysvětlete změny, které snižují latenci zvuku ve zvukovém zásobníku Windows 10.
  3. Uveďte referenční informace o tom, jak můžou vývojáři aplikací a výrobci hardwaru využívat novou infrastrukturu, aby mohli vyvíjet aplikace a ovladače s nízkou latencí zvuku.

Tento článek popisuje:

  1. Rozhraní API AudioGraph pro interaktivní a mediální tvorbu.
  2. Změny v WASAPI pro podporu nízké latence
  3. Vylepšení v DDI ovladačů.

Terminologie

Období Popis
Latence vykreslení Zpoždění mezi dobou, kdy aplikace odešle vyrovnávací paměť zvukových dat do API pro přehrávání, než je zvuk slyšet z reproduktorů.
Zachytávání latence Zpoždění mezi časem, kdy je zvuk zachycen z mikrofonu, a časem, kdy je odeslán do rozhraní API pro zachytávání, která používá aplikace.
Latence zpáteční cesty Zpoždění mezi časem, kdy je zvuk zachycen z mikrofonu, zpracován aplikací a odeslán aplikací k promítnutí do reproduktorů. Přibližně se rovná součtu latence vykreslování a latence zachycení.
Latence mezi dotykem a aplikací Zpoždění mezi časem, kdy uživatel klepne na obrazovku, a časem, kdy se signál odešle do aplikace.
Zpoždění mezi dotykem a zvukem Zpoždění mezi časem, kdy uživatel klepne na obrazovku, událost přejde do aplikace a přes reproduktory se ozývá zvuk. Je rovno latenci vykreslování + latenci od dotyku k aplikaci.

Zvukový zásobník Windows

Následující diagram znázorňuje zjednodušenou verzi zvukového zásobníku Windows.

diagram znázorňující zvukový zásobník s nízkou latencí, obsahující aplikace, ovladač zvukového enginu a hardware

Tady je souhrn latencí v cestě vykreslení: objekty zpracování zvuku

  1. Aplikace zapíše data do vyrovnávací paměti.

  2. Zvukový modul načte data z vyrovnávací paměti a zpracuje je. Načítá také zvukové efekty ve formě objektů pro zpracování zvuku (APO). Další informace o objektech zpracování zvuku (APO) naleznete v tématu objekty zpracování zvuku systému Windows.

  3. Latence apO se liší v závislosti na zpracování signálu v rámci apO.

  4. Před Windows 10 byla latence zvukového modulu rovna ~12 ms pro aplikace, které používají desetinná čísla s pohyblivou řádovou čárkou, a ~6 ms pro aplikace, které používají celočíselná data.

  5. Ve Windows 10 a novějších se latence snížila na 1,3 ms pro všechny aplikace.

  6. Zvukový stroj zapíše zpracovávaná data do vyrovnávací paměti.

  7. Před Windows 10 byla vyrovnávací paměť vždy nastavena na ~10 ms.

  8. Počínaje Windows 10 je velikost vyrovnávací paměti definovaná ovladačem zvuku (další podrobnosti o vyrovnávací paměti jsou popsány dále v tomto článku).

  9. Ovladač zvuku čte data z vyrovnávací paměti a zapisuje je do hardwaru.

  10. Hardware může také znovu zpracovávat data ve formě dalších zvukových efektů.

  11. Uživatel uslyší zvuk z reproduktoru.

Tady je souhrn latence v cestě zachycení:

  1. Zvuk se zaznamenává z mikrofonu.

  2. Hardware může zpracovávat data. Pokud například chcete přidat zvukové efekty.

  3. Ovladač načte data z hardwaru a zapíše data do vyrovnávací paměti.

  4. Před Windows 10 byla tato vyrovnávací paměť vždy nastavena na 10 ms.

  5. Počínaje Windows 10 je velikost vyrovnávací paměti definovaná ovladačem zvuku (další podrobnosti najdete níže).

  6. Zvukový modul načte data z vyrovnávací paměti a zpracuje je. Načítá také zvukové efekty ve formě objektů pro zpracování zvuku (APO).

  7. Latence apO se liší v závislosti na zpracování signálu v rámci apO.

  8. Před Windows 10 byla latence zvukového modulu přibližně 6 ms pro aplikace, které používají data s plovoucí desetinnou čárkou, a 0 ms pro aplikace, které používají celočíselná data.

  9. Ve Windows 10 a novějších se latence snížila na přibližně 0 min. pro všechny aplikace.

  10. Aplikaci je signalizováno, že data jsou k dispozici ke čtení, jakmile zvukový modul dokončí své zpracování. Zvukový zásobník také nabízí možnost výhradního režimu. V takovém případě data obcházejí zvukový modul a jdou přímo z aplikace do vyrovnávací paměti, ze které ovladač čte. Pokud ale aplikace otevře koncový bod ve výhradním režimu, neexistuje žádná jiná aplikace, která by tento koncový bod mohl použít k vykreslení nebo zachycení zvuku.

Další oblíbenou alternativou pro aplikace, které potřebují nízkou latenci, je použití modelu ASIO (Audio Stream Input/Output), který využívá exkluzivní režim. Po instalaci ovladače ASIO jiného výrobce můžou aplikace odesílat data přímo z aplikace do ovladače ASIO. Aplikace však musí být napsána takovým způsobem, že komunikuje přímo s řidičem ASIO.

Obě alternativy (exkluzivní režim i ASIO) mají svá vlastní omezení. Poskytují nízkou latenci, ale mají vlastní omezení (některé z nich byly popsány výše). V důsledku toho byl zvukový modul upraven, aby se snížila latence a zachovala flexibilitu.

Vylepšení zvukového systému

Windows 10 a novější byly vylepšeny ve třech oblastech, aby se snížila latence:

  1. Všechny aplikace, které používají zvuk, uvidí snížení latence odezvy 4,5–16 ms (jak bylo vysvětleno v předchozí části) bez jakýchkoli změn kódu nebo aktualizací ovladačů v porovnání s Windows 8.1.
    1. Aplikace, které používají čísla s pohyblivou řádovou čárkou, budou mít latenci sníženou o 16 ms.
    2. Aplikace, které používají celočíselná data, budou mít nižší latenci 4,5 ms.
  2. Systémy s aktualizovanými ovladači zajistí ještě nižší latenci:
    1. Ovladače můžou pomocí DDI s nízkou latencí hlásit podporované velikosti vyrovnávací paměti, která se používá k přenosu dat mezi Windows a hardwarem. Přenosy dat nemusí vždy používat 10ms vyrovnávací paměti, jako tomu bylo v předchozích verzích Windows. Místo toho může ovladač určit, jestli může používat malé vyrovnávací paměti, například 5 ms, 3 ms, 1 ms atd.
    2. Aplikace, které vyžadují nízkou latenci, můžou použít rozhraní API zvuku s nízkou latencí (AudioGraph nebo WASAPI) k dotazování velikostí vyrovnávací paměti, které ovladač podporuje, a vybrat rozhraní API pro přenos dat do a z hardwaru.
  3. Když aplikace používá velikost vyrovnávací paměti nižší než určitou prahovou hodnotu pro vykreslení a zachycení zvuku, windows přejde do speciálního režimu, kde spravuje své prostředky způsobem, který zabraňuje rušení mezi streamováním zvuku a jinými subsystémy. Tím se sníží přerušení provádění zvukového subsystému a minimalizuje se pravděpodobnost chyb zvuku. Když aplikace zastaví streamování, Windows se vrátí do normálního režimu spuštění. Zvukový subsystém se skládá z následujících zdrojů:
    1. Vlákno zvukového procesoru, které zpracovává zvuk s nízkou latencí.
    2. Všechna vlákna a přerušení zaregistrovaná ovladačem (pomocí DDI s nízkou latencí, které jsou popsány v části o registraci prostředků ovladače).
    3. Některá nebo všechna zvuková vlákna z aplikací, které požadují malé vyrovnávací paměti, a ze všech aplikací, které sdílejí stejný graf zvukového zařízení (například stejný režim zpracování signálu) se všemi aplikacemi, které požadovaly malé vyrovnávací paměti:
  4. Zpětná volání AudioGraph v cestě streamování.
  5. Pokud aplikace používá WASAPI, pak se to týká pouze pracovních položek odeslaných do API pracovní fronty Real-Time nebo do MFCreateMFByteStreamOnStreamEx, které byly označeny jako "Audio" nebo "ProAudio".

Vylepšení rozhraní API

Následující dvě rozhraní API pro Windows 10 poskytují možnosti nízké latence:

Určení, která z těchto dvou rozhraní API se má použít:

  • Upřednostnění AudioGraphu, kdykoli je to možné pro vývoj nových aplikací.
  • Použijte pouze WASAPI, pokud:
    • Potřebujete větší kontrolu nad tím, co poskytuje AudioGraph.
    • Potřebujete nižší latenci, než která poskytuje AudioGraph.

V části článku věnované nástrojům pro měření, konkrétně ukazuje měření ze systému Haswell pomocí integrovaného ovladače HDAudio.

Následující části popisují možnosti nízké latence v jednotlivých rozhraních API. Jak bylo uvedeno v předchozí části, aby systém dosáhl minimální latence, musí mít aktualizované ovladače, které podporují malé velikosti vyrovnávací paměti.

AudioGraph

AudioGraph je rozhraní API pro univerzální platformu Windows ve Windows 10 a novější, které je zaměřené na snadnou realizaci interaktivních scénářů a scénářů vytváření hudby. AudioGraph je k dispozici v několika programovacích jazycích (C++, C#, JavaScript) a má jednoduchý programovací model s bohatými funkcemi.

Aby bylo možné cílit na scénáře s nízkou latencí, poskytuje AudioGraph vlastnost AudioGraphSettings::QuantumSizeSelectionMode. Tato vlastnost může být libovolná z hodnot zobrazených v následující tabulce:

Hodnota Popis
Výchozí systém Nastaví vyrovnávací paměť na výchozí velikost vyrovnávací paměti (~10 ms).
Nejnižšílatence Nastaví vyrovnávací paměť na minimální hodnotu podporovanou ovladačem.
Nejblíže k požadovanému Nastaví velikost vyrovnávací paměti tak, aby byla buď rovna hodnotě definované vlastností DesiredSamplesPerQuantum, nebo na hodnotu co nejbližší DesiredSamplesPerQuantum, kterou podporuje ovladač.

Ukázka AudioCreation ukazuje, jak používat AudioGraph pro nízkou latenci. Následující fragment kódu ukazuje, jak nastavit minimální velikost vyrovnávací paměti:

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

Rozhraní API zvukové relace Windows (WASAPI)

Počínaje Windows 10 byla funkce WASAPI vylepšena na:

  • Povolit aplikaci zjistit rozsah velikostí vyrovnávací paměti (tj. hodnoty periodicity), které jsou podporovány zvukovým ovladačem daného zvukového zařízení. Aplikace tak může při otevírání datového proudu ve sdíleném režimu zvolit mezi výchozí velikostí vyrovnávací paměti (10 ms) nebo malou vyrovnávací pamětí (menší než 10 ms). Pokud aplikace nezadá velikost vyrovnávací paměti, použije výchozí velikost vyrovnávací paměti.
  • Umožnit aplikaci zjistit aktuální formát a periodicitu zvukového systému. To umožňuje aplikacím přizpůsobit se aktuálním nastavením zvukového systému.
  • Povolit aplikaci určit, že chce vykreslit nebo zachytit ve formátu, který určuje bez jakéhokoliv převzorkování zvukovým strojem

Výše uvedené funkce budou dostupné na všech zařízeních s Windows. Některá zařízení s dostatečnými prostředky a aktualizovanými ovladači ale poskytují lepší uživatelské prostředí než ostatní.

Výše uvedené funkce je poskytována rozhraním, které se nazývá IAudioClient3, který je odvozen od IAudioClient2.

IAudioClient3 definuje následující 3 metody:

Metoda Popis
GetCurrentSharedModeEnginePeriod (Získat aktuální období sdíleného režimu motoru) Vrátí aktuální formát a periodičnost zvukového stroje.
GetSharedModeEnginePeriod Vrátí rozsah periodiek podporovaných modulem pro zadaný formát datového proudu.
Inicializace Sdíleného Audio Streamu Inicializuje sdílený datový proud se zadanou periodikou.

Ukázka WASAPIAudio ukazuje, jak používat IAudioClient3 pro nízkou latenci.

Následující fragment kódu ukazuje, jak může aplikace pro vytváření hudby fungovat v nastavení s nejnižší latencí, které systém podporuje.

// 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)) {
       ...
}

Microsoft také doporučuje pro aplikace, které používají WASAPI, používat také Real-Time rozhraní API pracovní fronty nebo MFCreateMFByteStreamOnStreamEx vytvářet pracovní položky a označit je jako Audio nebo Pro Audio místo vlastních vláken. To umožní systému Windows spravovat je způsobem, který zabrání rušení subsystémů bez zvuku. Naproti tomu všechna vlákna AudioGraph jsou automaticky spravována systémem Windows. Následující fragment kódu z příkladu WASAPIAudio ukazuje, jak používat rozhraní API pracovní fronty 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 );

Případně následující fragment kódu ukazuje, jak používat rozhraní API pracovní fronty RT.

#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;
}

A konečně, vývojáři aplikací, kteří používají WASAPI, musí označit své streamy pomocí kategorie zvuku a to, jestli mají používat nezpracovaný režim zpracování signálu na základě funkcí každého datového proudu. Microsoft doporučuje, aby všechny zvukové streamy nepoužívaly režim zpracování surového signálu, pokud nejsou důsledky plně pochopeny. Nezpracovaný režim obchází veškeré zpracování signálu zvolené výrobcem OEM, takže:

  • Signál vykreslení pro konkrétní koncový bod může být neoptimální.
  • Signál zachycení může být ve formátu, kterému aplikace nerozumí.
  • Latence se může zlepšit.

Vylepšení ovladačů

Aby ovladače zvuku podporovaly nízkou latenci, windows 10 a novější poskytují následující funkce:

  1. [Povinné] Deklarujte minimální velikost vyrovnávací paměti podporovanou v každém režimu.
  2. [Volitelné, ale doporučené] Zlepšete koordinaci toku dat mezi ovladačem a Windows.
  3. [Volitelné, ale doporučené] Zaregistrujte prostředky ovladačů (přerušení, vlákna), aby je systém Windows mohl chránit ve scénářích s nízkou latencí. Ovladače funkcí miniportu HDAudio, které jsou vyjmenovány integrovaným ovladačem sběrnice HDAudio hdaudbus.sys, nemusí registrovat přerušení HDAudio, protože to již provádí hdaudbus.sys. Pokud ale ovladač miniportu vytvoří vlastní vlákna, musí je zaregistrovat.

Následující tři části popisují jednotlivé funkce podrobněji.

Deklarujte minimální velikost vyrovnávací paměti.

Ovladač pracuje s různými omezeními při přesouvání zvukových dat mezi Windows, ovladačem a hardwarem. Tato omezení můžou být způsobená fyzickým hardwarovým přenosem, který přesouvá data mezi pamětí a hardwarem, nebo kvůli modulům zpracování signálu v rámci hardwaru nebo přidruženého DSP.

Počínaje verzí Windows 10, 1607, může ovladač pomocí vlastnosti DEVPKEY_KsAudio_PacketSize_Constraints2 zařízení vyjádřit své schopnosti týkající se velikosti vyrovnávací paměti. Tato vlastnost umožňuje uživateli definovat absolutní minimální velikost vyrovnávací paměti podporovanou ovladačem a konkrétní omezení velikosti vyrovnávací paměti pro každý režim zpracování signálu. Omezení specifická pro režim musí být vyšší než minimální velikost vyrovnávací paměti ovladačů, jinak je zvukový stack ignoruje.

Například následující fragment kódu ukazuje, jak ovladač může deklarovat, že absolutní minimální podporovaná velikost vyrovnávací paměti je 2 ms, ale výchozí režim podporuje 128 snímků, což odpovídá 3 ms, pokud předpokládáme vzorkovací frekvenci 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
        },
    }
};

Podrobnější informace o těchto strukturách najdete v následujících článcích:

Také ukázka sysvad ukazuje, jak použít tyto vlastnosti, aby ovladač deklaroval minimální vyrovnávací paměť pro každý režim.

Zlepšení koordinace mezi řidičem a operačním systémem

Rozhraní DDI popsaná v této části umožňují ovladači:

  • Jasně určete, která polovina (nebo část) vyrovnávací paměti je k dispozici systému Windows, místo aby operační systém musel odhadovat na základě pozice propojení kodeku. To pomáhá systému Windows rychleji zotavit se z chyb zvuku.
  • Volitelně můžete optimalizovat nebo zjednodušit přenosy dat do vyrovnávací paměti WaveRT a z ní. Množství výhod zde závisí na návrhu modulu DMA nebo jiném mechanismu přenosu dat mezi vyrovnávací pamětí WaveRT a hardwarem (případně DSP).
  • "Burst" dokáže zachytit data rychleji než v reálném čase, pokud ovladač interně nahromadil zachycená data. To je primárně určené pro scénáře aktivace hlasem, ale může se použít i během normálního streamování.
  • Poskytněte informace o časovém razítku aktuální pozice streamu místo toho, aby systém Windows hádal, což by mohlo potenciálně umožnit přesné informace o pozici.

Tato DDI je užitečná v případě, kdy se používá DSP. Standardní ovladač HD Audio nebo jiný jednoduchý návrh kruhové vyrovnávací paměti DMA však nemusí najít mnoho přínosu v těchto zde uvedených DDI.

Několik rutin ovladačů vrací časové razítko čítače výkonu Windows, které odráží čas, kdy jsou vzorky zachyceny nebo prezentovány zařízením.

V zařízeních, která mají komplexní kanály DSP a zpracování signálu, může být výpočet přesného časového razítka náročný a měl by být proveden promyšleně. Časová razítka by neměla odrážet čas, kdy byly vzorky přeneseny do nebo z Windows do DSP.

K výpočtu hodnot čítače výkonu může ovladač a DSP použít některé z následujících metod.

  • V rámci DSP sledujte vzorková časová razítka pomocí interních DSP hodin.
  • Mezi ovladačem a DSP vypočítejte korelaci mezi čítačem výkonu Windows a hodinou DSP. Postupy mohou být v rozsahu od jednoduchých (ale méně přesných) až po poměrně složité nebo nové (ale přesnější).
  • Započítání jakýchkoli konstantních zpoždění kvůli algoritmům zpracování signálu nebo přenosům kanálu nebo hardwaru, pokud se tato zpoždění jinak nezapočítávají.

Ukázka sysvad ukazuje, jak používat výše uvedené DDI.

Registrace prostředků ovladačů

Aby se zajistilo bezproblémové fungování zvukových ovladačů, musí své streamovací prostředky zaregistrovat v Portcls. To umožňuje systému Windows spravovat prostředky, aby nedocházelo k rušení mezi streamováním zvuku a jinými subsystémy.

Prostředky streamu jsou všechny prostředky, které ovladač zvuku používá ke zpracování zvukových streamů nebo k zajištění toku zvukových dat. Podporují se pouze dva typy prostředků datového proudu: přerušení a vlákna vlastněná ovladačem. Ovladače zvuku by měly po vytvoření prostředku zaregistrovat prostředek a před odstraněním zrušit jeho registraci.

Zvukové ovladače můžou registrovat prostředky v době inicializace při načtení ovladače nebo za běhu, například když dojde k obnovení rovnováhy vstupně-výstupních prostředků. Portcls používá globální stav ke sledování všech prostředků pro streamování zvuku.

V některých případech použití, například těch, které vyžadují velmi nízkou latenci zvuku, se Systém Windows pokusí izolovat registrované prostředky zvukového ovladače od rušení od jiných operačních systémů, aplikací a hardwarových aktivit. Operační systém a zvukový subsystém to dělají podle potřeby bez interakce se zvukovým ovladačem, s výjimkou toho, že zvukový ovladač registruje prostředky.

Tento požadavek na registraci prostředků streamu znamená, že všechny ovladače, které jsou v cestě streamovacího kanálu, musí své prostředky zaregistrovat přímo nebo nepřímo u Portcls. Ovladač miniportu zvuku má tyto možnosti:

  • Ovladač miniportu zvuku je nejspodnější ovladač ve svém zásobníku (komunikuje přímo s h/w), v tomto případě ovladač zná své streamové prostředky a může je zaregistrovat u Portcls.
  • Ovladač audio miniportu streamuje zvuk pomocí jiných ovladačů (například ovladače zvukové sběrnice). Tyto další ovladače také používají prostředky, které musí být registrovány v portcls. Tyto zásobníky paralelních/sběrnicových ovladačů mohou vystavit veřejné rozhraní (nebo soukromé, pokud jeden dodavatel vlastní všechny ovladače), které ovladače audio miniportu využívají ke shromažďování těchto informací.
  • Ovladač miniportu zvuku přenáší zvuk pomocí jiných ovladačů (například hdaudbus). Tyto další ovladače také používají prostředky, které musí být registrovány v portcls. Tyto paralelní/sběrnicové ovladače se mohou propojit s Portcls a přímo zaregistrovat své prostředky. Ovladače miniportu zvuku musí dát Portcls vědět, že jsou závislé na prostředcích těchto dalších paralelních/sběrných zařízení (PDO). Infrastruktura zvuku HD používá tuto možnost, tj. ovladač audio-sběrnice HD se propojuje s Portcls a automaticky provede následující kroky:
    • zaregistruje prostředky řidiče autobusu a
    • upozorní Portcls, že prostředky dětí závisí na rodičovských prostředcích. V architektuře zvuku HD stačí, když ovladač miniportu zvuku zaregistruje vlastní prostředky vlákna vlastněného ovladačem.

Poznámky:

  • Ovladače funkce HDAudio miniportu, které jsou vyčíslovány integrovaným ovladačem HDAudio sběrnice hdaudbus.sys, nemusí registrovat přerušení HDAudio, protože to již zajišťuje hdaudbus.sys. Pokud ale ovladač miniportu vytvoří vlastní vlákna, musí je zaregistrovat.
  • Ovladače, které odkazují na Portcls pouze za účelem registrace streamingových prostředků, musí aktualizovat své soubory INFs, aby zahrnovaly wdmaudio.inf a zkopírovat portcls.sys (a závislé soubory). V souboru wdmaudio.inf je definován nový oddíl kopírování INF, který bude kopírovat pouze tyto soubory.
  • Ovladače zvuku, které běží jenom ve Windows 10 a novějších, můžou pevně propojit s:
  • Zvukové ovladače, které musí běžet na operačním systému nižší úrovně, mohou použít následující rozhraní (miniport může volat QueryInterface pro rozhraní IID_IPortClsStreamResourceManager a zaregistrovat jeho prostředky pouze v případě, že PortCls podporuje rozhraní).
  • Tyto DDI používají následující výčet a strukturu:

A konečně ovladače, které začleňují PortCls výhradně pro účel registrace prostředků, musí do sekce DDInstall v INF souboru přidat následující dva řádky. Ovladače miniportu zvuku to nepotřebují, protože již mají sekce include/needs v souboru wdmaudio.inf.

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

Výše uvedené řádky zajišťují, že jsou nainstalovány PortCls a jeho závislé soubory.

Nástroje pro měření

Aby mohl uživatel měřit latenci, může využívat nástroje, které přehrávají impulsy přes reproduktory a zachycují je mikrofonem. Měří zpoždění následující cesty:

  1. Aplikace volá rozhraní API pro vykreslování (AudioGraph nebo WASAPI) k přehrání impulsu.
  2. Zvuk se přehrával prostřednictvím reproduktorů.
  3. Zvuk se zaznamenává z mikrofonu.
  4. Rozhraní API pro zachytávání (AudioGraph nebo WASAPI) detekuje puls. Aby bylo možné měřit obousměrnou latenci pro různé velikosti vyrovnávacích pamětí, musejí uživatelé nainstalovat ovladač podporující malé vyrovnávací paměti. Ovladač HDAudio doručené pošty byl aktualizován tak, aby podporoval velikosti vyrovnávací paměti mezi 128 vzorky (2.66ms@48kHz) a 480 vzorků (10ms@48kHz). Následující kroky ukazují, jak nainstalovat integrovaný ovladač HDAudio (který je součástí všech SKU Windows 10 a novějších):
  • Spusťte Správce zařízení.
  • V části Ovladače zvuku a herpoklikejte na zařízení, které odpovídá vašim interním reproduktorům.
  • V dalším okně přejděte na kartu Ovladač.
  • Vyberte Aktualizovat ovladač –>Procházet můj počítač pro software ovladačů –>Nechat mě vybrat ze seznamu ovladačů zařízení v tomto počítači –>Vybrat zařízení pro vysoké rozlišení zvuku a vybrat Další.
  • Pokud se zobrazí okno s názvem Aktualizovat upozornění ovladače, vyberte Ano.
  • Vyberte zavřít.
  • Pokud se zobrazí výzva k restartování systému, vyberte Ano k restartování.
  • Po restartování bude systém používat ovladač Doručená pošta Microsoft HDAudio, nikoli ovladač kodeku třetí strany. Mějte na paměti, který ovladač jste používali dříve, abyste se mohli vrátit k danému ovladači, pokud chcete použít optimální nastavení zvukového kodeku.

Graf znázorňující rozdíly v latenci mezi WASAPI a AudioGraphem pro různé velikosti vyrovnávací paměti.

Rozdíly v latenci mezi WASAPI a AudioGraphem jsou způsobené následujícími důvody:

  • AudioGraph přidá v části zachytávání jednu vyrovnávací paměť pro latenci, k synchronizaci renderování a zachytávání, které WASAPI neposkytuje. Tento doplněk zjednodušuje kód pro aplikace napsané pomocí AudioGraphu.
  • Na straně zpracování AudioGraphu existuje další záložní paměť pro latenci, když systém používá více než 6ms vyrovnávací paměť.
  • AudioGraph nemá možnost zakázat zachytávání zvukových efektů.

Vzorky

FAQ

Nebylo by lepší, kdyby všechny aplikace používaly nová rozhraní API pro nízkou latenci? Nezaručuje nízká latence vždy lepší uživatelské prostředí?

Nemusí to být nutně. Nízká latence má své kompromisy:

  • Nízká latence znamená vyšší spotřebu energie. Pokud systém používá vyrovnávací paměti 10 ms, znamená to, že procesor se probudí každých 10 ms, naplní vyrovnávací paměť dat a přejde do režimu spánku. Pokud však systém používá vyrovnávací paměti 1 ms, znamená to, že procesor se probudí každých 1 ms. Ve druhém scénáři to znamená, že se procesor probudí častěji a spotřeba energie se zvýší. Tím se sníží životnost baterie.
  • Většina aplikací spoléhá na zvukové efekty, aby poskytovala co nejlepší uživatelské prostředí. Multimediální přehrávače například chtějí poskytovat zvuk s vysokou věrností. Komunikační aplikace chtějí minimální odezvu a šum. Přidáním těchto typů zvukových efektů do datového proudu se zvýší jeho latence. Tyto aplikace mají větší zájem o kvalitu zvuku než latenci zvuku.

V souhrnu má každý typ aplikace různé potřeby týkající se latence zvuku. Pokud aplikace nepotřebuje nízkou latenci, neměla by pro nízkou latenci používat nová rozhraní API.

Budou všechny systémy, které se aktualizují na Windows 10 a novější, automaticky aktualizovat tak, aby podporovaly malé vyrovnávací paměti? Budou všechny systémy podporovat stejnou minimální velikost vyrovnávací paměti?

Ne, aby systém podporoval malé vyrovnávací paměti, musí mít aktualizované ovladače. Je na původních výrobcích zařízení rozhodnout, které systémy se budou aktualizovat, aby podporovaly malé vyrovnávací paměti. Novější systémy také pravděpodobně podporují menší vyrovnávací paměti než starší systémy. Latence v nových systémech bude pravděpodobně nižší než starší systémy.

Pokud ovladač podporuje malé velikosti vyrovnávací paměti, budou všechny aplikace ve Windows 10 a novějších automaticky používat malé vyrovnávací paměti k vykreslení a zachycení zvuku?

Ne, ve výchozím nastavení budou všechny aplikace ve Windows 10 a novějších používat vyrovnávací paměti 10 ms k vykreslení a zachycení zvuku. Pokud aplikace potřebuje používat malé vyrovnávací paměti, musí k tomu použít nová nastavení AudioGraph nebo rozhraní WASAPI IAudioClient3. Pokud ale jedna aplikace požádá o použití malých vyrovnávacích pamětí, zvukový modul začne přenášet zvuk pomocí této konkrétní velikosti vyrovnávací paměti. V takovém případě se všechny aplikace, které používají stejný koncový bod a režim, automaticky přepnou na malou velikost vyrovnávací paměti. Po ukončení aplikace s nízkou latencí se zvukový modul znovu přepne do vyrovnávací paměti 10 ms.