Skip to content

Instantly share code, notes, and snippets.

@d7samurai
Last active August 29, 2025 12:13
Show Gist options
  • Save d7samurai/6d24d0ba93f8c8fe6b4f02b92d4c8ce0 to your computer and use it in GitHub Desktop.
Save d7samurai/6d24d0ba93f8c8fe6b4f02b92d4c8ce0 to your computer and use it in GitHub Desktop.

Revisions

  1. d7samurai revised this gist Mar 2, 2024. 1 changed file with 1 addition and 7 deletions.
    8 changes: 1 addition & 7 deletions code.cpp
    Original file line number Diff line number Diff line change
    @@ -43,13 +43,7 @@ int main()

    audioClient->GetMixFormat(&mixFormat);

    WAVEFORMATEXTENSIBLE mixFormatEx;

    memcpy(&mixFormatEx, mixFormat, sizeof(mixFormatEx));

    CoTaskMemFree(mixFormat);

    audioClient->Initialize(AUDCLNT_SHAREMODE_SHARED, AUDCLNT_STREAMFLAGS_EVENTCALLBACK, minimumPeriod, 0, reinterpret_cast<WAVEFORMATEX*>(&mixFormatEx), nullptr);
    audioClient->Initialize(AUDCLNT_SHAREMODE_SHARED, AUDCLNT_STREAMFLAGS_EVENTCALLBACK, minimumPeriod, 0, mixFormat, nullptr);

    IAudioRenderClient* audioRenderClient;

  2. d7samurai revised this gist Jun 23, 2023. 1 changed file with 1 addition and 1 deletion.
    2 changes: 1 addition & 1 deletion .readme.md
    Original file line number Diff line number Diff line change
    @@ -1,4 +1,4 @@
    # Minimal WASAPI
    Minimal WASAPI reference implementation. Runnable console application contained in a single function and laid out in a linear, step-by-step fashion. No modern C++ / OOP / obscuring cruft. Produces a steady sine wave sound.

    (This is a re-post of the same gist I posted a few years earlier, since it's not possible to hide or rearrange gists).
    (This is a re-post of the same gist I posted a few years earlier, simply due to me wanting the Minimal D3D11 series to be listed contiguously and it's not possible to hide or rearrange gists).
  3. d7samurai revised this gist Apr 26, 2023. 1 changed file with 1 addition and 1 deletion.
    2 changes: 1 addition & 1 deletion .readme.md
    Original file line number Diff line number Diff line change
    @@ -1,4 +1,4 @@
    # Minimal WASAPI
    Minimal WASAPI reference implementation. Runnable console application contained in a single function and laid out in a linear, step-by-step fashion. No modern C++ / OOP / obscuring cruft. Produces a steady sine wave sound.

    (This is a re-post of the same gist I posted a few years earlier, since it's not possible to hide or re-arrange gists).
    (This is a re-post of the same gist I posted a few years earlier, since it's not possible to hide or rearrange gists).
  4. d7samurai revised this gist Apr 26, 2023. 1 changed file with 1 addition and 1 deletion.
    2 changes: 1 addition & 1 deletion .readme.md
    Original file line number Diff line number Diff line change
    @@ -1,4 +1,4 @@
    # Minimal WASAPI
    Minimal WASAPI reference implementation. Runnable console application contained in a single function and laid out in a linear, step-by-step fashion. No modern C++ / OOP / obscuring cruft. Produces a steady sine wave sound.

    (This is a re-post of the same gist I posted a few years earlier, since it's not possible to hide or re-arrange the order of gists).
    (This is a re-post of the same gist I posted a few years earlier, since it's not possible to hide or re-arrange gists).
  5. d7samurai revised this gist Apr 26, 2023. 1 changed file with 3 additions and 1 deletion.
    4 changes: 3 additions & 1 deletion .readme.md
    Original file line number Diff line number Diff line change
    @@ -1,2 +1,4 @@
    # Minimal WASAPI
    Minimal WASAPI reference implementation. Runnable console application contained in a single function and laid out in a linear, step-by-step fashion. No modern C++ / OOP / obscuring cruft. Produces a steady sine wave sound.
    Minimal WASAPI reference implementation. Runnable console application contained in a single function and laid out in a linear, step-by-step fashion. No modern C++ / OOP / obscuring cruft. Produces a steady sine wave sound.

    (This is a re-post of the same gist I posted a few years earlier, since it's not possible to hide or re-arrange the order of gists).
  6. d7samurai created this gist Dec 28, 2022.
    2 changes: 2 additions & 0 deletions .readme.md
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,2 @@
    # Minimal WASAPI
    Minimal WASAPI reference implementation. Runnable console application contained in a single function and laid out in a linear, step-by-step fashion. No modern C++ / OOP / obscuring cruft. Produces a steady sine wave sound.
    101 changes: 101 additions & 0 deletions code.cpp
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,101 @@

    #pragma comment(lib, "ole32")

    ///////////////////////////////////////////////////////////////////////////////////////////////////

    #include <windows.h>
    #include <mmdeviceapi.h>
    #include <audioclient.h>
    #include <math.h> // for sine

    ///////////////////////////////////////////////////////////////////////////////////////////////////

    int main()
    {
    CoInitializeEx(nullptr, COINIT_MULTITHREADED | COINIT_DISABLE_OLE1DDE);

    ///////////////////////////////////////////////////////////////////////////////////////////////

    IMMDeviceEnumerator* deviceEnumerator;

    CoCreateInstance(__uuidof(MMDeviceEnumerator), nullptr, CLSCTX_INPROC_SERVER, __uuidof(IMMDeviceEnumerator), reinterpret_cast<void**>(&deviceEnumerator));

    ///////////////////////////////////////////////////////////////////////////////////////////////

    IMMDevice* audioDevice;

    deviceEnumerator->GetDefaultAudioEndpoint(eRender, eConsole, &audioDevice);

    ///////////////////////////////////////////////////////////////////////////////////////////////

    IAudioClient3* audioClient;

    audioDevice->Activate(__uuidof(IAudioClient3), CLSCTX_INPROC_SERVER, nullptr, reinterpret_cast<void**>(&audioClient));

    ///////////////////////////////////////////////////////////////////////////////////////////////

    REFERENCE_TIME defaultPeriod;
    REFERENCE_TIME minimumPeriod;

    audioClient->GetDevicePeriod(&defaultPeriod, &minimumPeriod);

    WAVEFORMATEX* mixFormat;

    audioClient->GetMixFormat(&mixFormat);

    WAVEFORMATEXTENSIBLE mixFormatEx;

    memcpy(&mixFormatEx, mixFormat, sizeof(mixFormatEx));

    CoTaskMemFree(mixFormat);

    audioClient->Initialize(AUDCLNT_SHAREMODE_SHARED, AUDCLNT_STREAMFLAGS_EVENTCALLBACK, minimumPeriod, 0, reinterpret_cast<WAVEFORMATEX*>(&mixFormatEx), nullptr);

    IAudioRenderClient* audioRenderClient;

    audioClient->GetService(__uuidof(IAudioRenderClient), reinterpret_cast<void**>(&audioRenderClient));

    UINT32 bufferSize;

    audioClient->GetBufferSize(&bufferSize);

    HANDLE bufferReady = CreateEventA(nullptr, FALSE, FALSE, nullptr);

    audioClient->SetEventHandle(bufferReady);

    ///////////////////////////////////////////////////////////////////////////////////////////////

    double time = 0.0;

    audioClient->Start();

    while (WaitForSingleObject(bufferReady, INFINITE) == WAIT_OBJECT_0)
    {
    UINT32 bufferPadding;

    audioClient->GetCurrentPadding(&bufferPadding);

    UINT32 frameCount = bufferSize - bufferPadding;
    float* buffer;

    audioRenderClient->GetBuffer(frameCount, reinterpret_cast<BYTE**>(&buffer));

    for (UINT32 frameIndex = 0; frameIndex < frameCount; frameIndex++)
    {
    float amplitude = static_cast<float>(sin(time));

    *buffer++ = amplitude; // left
    *buffer++ = amplitude; // right

    time += 0.05;
    }

    audioRenderClient->ReleaseBuffer(frameCount, 0);
    }

    audioClient->Stop();

    ///////////////////////////////////////////////////////////////////////////////////////////////

    return 0;
    }