Created
July 3, 2026 21:02
-
-
Save Gargaj/1782443176389843a369d2bd4867c6b0 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| #include <stdio.h> | |
| #include <conio.h> | |
| #include <audioclient.h> | |
| #include <Mmdeviceapi.h> | |
| #include <Functiondiscoverykeys_devpkey.h> | |
| #define DR_MP3_IMPLEMENTATION | |
| #include "dr_mp3.h" | |
| const int sampleRate = 44100; | |
| const int channelCount = 2; | |
| const int sampleSize = sizeof( short ); | |
| WAVEFORMATEX waveFormat = | |
| { | |
| /* wFormatTag */ WAVE_FORMAT_PCM, | |
| /* nChannels */ channelCount, | |
| /* nSamplesPerSec */ sampleRate, | |
| /* nAvgBytesPerSec */ sampleRate * sampleSize * channelCount, | |
| /* nBlockAlign */ sampleSize * channelCount, | |
| /* wBitsPerSample */ 8 * sampleSize, | |
| /* cbSize */ 0, | |
| }; | |
| IMMDeviceEnumerator * enumerator = nullptr; | |
| IMMDevice * device = nullptr; | |
| IAudioClient * audioClient = nullptr; | |
| IAudioRenderClient * audioRenderClient = nullptr; | |
| IAudioClock * audioClock = nullptr; | |
| unsigned int bufferFrameCount = 0; | |
| bool shouldExit = false; | |
| drmp3 mp3; | |
| DWORD __stdcall ThreadProc( LPVOID _param ) | |
| { | |
| if ( audioClient->Start() != S_OK ) | |
| { | |
| return 0; | |
| } | |
| shouldExit = false; | |
| while ( !shouldExit ) | |
| { | |
| unsigned int numFramesPadding = 0; | |
| audioClient->GetCurrentPadding( &numFramesPadding ); | |
| const unsigned int framesRemaining = bufferFrameCount - numFramesPadding; | |
| if ( framesRemaining ) | |
| { | |
| unsigned char * buffer = nullptr; | |
| audioRenderClient->GetBuffer( framesRemaining, &buffer ); | |
| drmp3_read_pcm_frames_s16( &mp3, framesRemaining, (drmp3_int16 *)buffer ); | |
| audioRenderClient->ReleaseBuffer( framesRemaining, 0 ); | |
| } | |
| Sleep( 3 ); | |
| } | |
| audioClient->Stop(); | |
| return 0; | |
| } | |
| int main() | |
| { | |
| if ( CoInitialize( nullptr ) != S_OK ) | |
| { | |
| return 1; | |
| } | |
| if ( CoCreateInstance( __uuidof(MMDeviceEnumerator), NULL, CLSCTX_ALL, __uuidof(IMMDeviceEnumerator), (void **)&enumerator ) != S_OK ) | |
| { | |
| return 1; | |
| } | |
| if ( enumerator->GetDefaultAudioEndpoint( eRender, eConsole, &device ) != S_OK ) | |
| { | |
| return 1; | |
| } | |
| if ( device->Activate( __uuidof(IAudioClient), CLSCTX_ALL, NULL, (void **)&audioClient ) != S_OK ) | |
| { | |
| return 1; | |
| } | |
| const REFERENCE_TIME bufferDuration = 10000000; // 100 nanosecond units | |
| if ( audioClient->Initialize( AUDCLNT_SHAREMODE_SHARED, 0, bufferDuration, 0, &waveFormat, 0 ) != S_OK ) | |
| { | |
| return 1; | |
| } | |
| if ( audioClient->GetService( __uuidof(IAudioRenderClient), (void **)&audioRenderClient ) != S_OK ) | |
| { | |
| return 1; | |
| } | |
| if ( audioClient->GetBufferSize( &bufferFrameCount ) != S_OK ) | |
| { | |
| return 1; | |
| } | |
| if ( audioClient->GetService( __uuidof(IAudioClock), (void **)&audioClock ) != S_OK ) | |
| { | |
| return 1; | |
| } | |
| unsigned long long clockFrequency = 0; | |
| if ( audioClock->GetFrequency( &clockFrequency ) != S_OK ) | |
| { | |
| return 1; | |
| } | |
| if ( !drmp3_init_file( &mp3, "audio.mp3", nullptr ) ) | |
| { | |
| return 1; | |
| } | |
| DWORD threadID; | |
| HANDLE threadHandle = CreateThread( nullptr, 0, ThreadProc, nullptr, 0, (LPDWORD)&threadID ); | |
| if ( threadHandle == NULL ) | |
| { | |
| return 1; | |
| } | |
| SetThreadPriority( threadHandle, THREAD_PRIORITY_TIME_CRITICAL ); | |
| while ( !_kbhit() ) | |
| { | |
| unsigned long long position = 0; | |
| if ( audioClock->GetPosition( &position, nullptr ) != S_OK ) | |
| { | |
| return 1; | |
| } | |
| double timeInSeconds = position / (double)clockFrequency; | |
| printf( "%.2f\r", timeInSeconds ); | |
| Sleep( 1 ); | |
| } | |
| shouldExit = true; | |
| if ( audioClock ) | |
| { | |
| audioClock->Release(); | |
| audioClock = nullptr; | |
| } | |
| if ( audioRenderClient ) | |
| { | |
| audioRenderClient->Release(); | |
| audioRenderClient = nullptr; | |
| } | |
| if ( audioClient ) | |
| { | |
| audioClient->Release(); | |
| audioClient = nullptr; | |
| } | |
| if ( device ) | |
| { | |
| device->Release(); | |
| device = nullptr; | |
| } | |
| if ( enumerator ) | |
| { | |
| enumerator->Release(); | |
| enumerator = nullptr; | |
| } | |
| return 0; | |
| } |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment