diff --git a/miniaudio.h b/miniaudio.h index 3879cd3..58a16a6 100644 --- a/miniaudio.h +++ b/miniaudio.h @@ -7312,6 +7312,7 @@ typedef struct ma_device_type deviceType; void* pAudioClient; void** ppAudioClientService; + void** ppAudioClock; ma_result* pResult; /* The result from creating the audio client service. */ } createAudioClient; struct @@ -7821,6 +7822,7 @@ struct ma_device /*IAudioClient**/ ma_ptr pAudioClientCapture; /*IAudioRenderClient**/ ma_ptr pRenderClient; /*IAudioCaptureClient**/ ma_ptr pCaptureClient; + /*IAudioClock**/ ma_ptr pAudioClock; /*IMMDeviceEnumerator**/ ma_ptr pDeviceEnumerator; /* Used for IMMNotificationClient notifications. Required for detecting default device changes. */ ma_IMMNotificationClient notificationClient; /*HANDLE*/ ma_handle hEventPlayback; /* Auto reset. Initialized to signaled. */ @@ -20305,6 +20307,8 @@ static const IID MA_IID_IAudioClient2 = {0x726778CD, static const IID MA_IID_IAudioClient3 = {0x7ED4EE07, 0x8E67, 0x4CD4, {0x8C, 0x1A, 0x2B, 0x7A, 0x59, 0x87, 0xAD, 0x42}}; /* 7ED4EE07-8E67-4CD4-8C1A-2B7A5987AD42 = __uuidof(IAudioClient3) */ static const IID MA_IID_IAudioRenderClient = {0xF294ACFC, 0x3146, 0x4483, {0xA7, 0xBF, 0xAD, 0xDC, 0xA7, 0xC2, 0x60, 0xE2}}; /* F294ACFC-3146-4483-A7BF-ADDCA7C260E2 = __uuidof(IAudioRenderClient) */ static const IID MA_IID_IAudioCaptureClient = {0xC8ADBD64, 0xE71E, 0x48A0, {0xA4, 0xDE, 0x18, 0x5C, 0x39, 0x5C, 0xD3, 0x17}}; /* C8ADBD64-E71E-48A0-A4DE-185C395CD317 = __uuidof(IAudioCaptureClient) */ +static const IID MA_IID_IAudioClock = {0xCD63314F, 0x3FBA, 0x4a1b, {0x81, 0x2C, 0xEF, 0x96, 0x35, 0x87, 0x28, 0xE7}}; /* CD63314F-3FBA-4a1b-812C-EF96358728E7 = _uuidof(IAudioClock) */ +static const IID MA_IID_IAudioClock2 = {0x6f49ff73, 0x6727, 0x49ac, {0xa0, 0x08, 0xd9, 0x8c, 0xf5, 0xe7, 0x00, 0x48}}; /* 6f49ff73-6727-49ac-a008-d98cf5e70048 = __uuidof(IAudioClock2) */ static const IID MA_IID_IMMNotificationClient = {0x7991EEC9, 0x7E89, 0x4D85, {0x83, 0x90, 0x6C, 0x70, 0x3C, 0xEC, 0x60, 0xC0}}; /* 7991EEC9-7E89-4D85-8390-6C703CEC60C0 = __uuidof(IMMNotificationClient) */ #if !defined(MA_WIN32_DESKTOP) && !defined(MA_WIN32_GDK) static const IID MA_IID_DEVINTERFACE_AUDIO_RENDER = {0xE6327CAD, 0xDCEC, 0x4949, {0xAE, 0x8A, 0x99, 0x1E, 0x97, 0x6A, 0x79, 0xD2}}; /* E6327CAD-DCEC-4949-AE8A-991E976A79D2 */ @@ -20334,6 +20338,7 @@ typedef struct ma_IAudioClient2 ma_IAudioClient2; typedef struct ma_IAudioClient3 ma_IAudioClient3; typedef struct ma_IAudioRenderClient ma_IAudioRenderClient; typedef struct ma_IAudioCaptureClient ma_IAudioCaptureClient; +typedef struct ma_IAudioClock ma_IAudioClock; typedef ma_int64 MA_REFERENCE_TIME; @@ -20745,6 +20750,28 @@ static MA_INLINE HRESULT ma_IAudioCaptureClient_GetBuffer(ma_IAudioCaptureClient static MA_INLINE HRESULT ma_IAudioCaptureClient_ReleaseBuffer(ma_IAudioCaptureClient* pThis, ma_uint32 numFramesRead) { return pThis->lpVtbl->ReleaseBuffer(pThis, numFramesRead); } static MA_INLINE HRESULT ma_IAudioCaptureClient_GetNextPacketSize(ma_IAudioCaptureClient* pThis, ma_uint32* pNumFramesInNextPacket) { return pThis->lpVtbl->GetNextPacketSize(pThis, pNumFramesInNextPacket); } + +/* IAudioClock */ +typedef struct +{ + /* IUnknown */ + HRESULT (STDMETHODCALLTYPE * QueryInterface)(ma_IAudioCaptureClient* pThis, const IID* const riid, void** ppObject); + ULONG (STDMETHODCALLTYPE * AddRef) (ma_IAudioCaptureClient* pThis); + ULONG (STDMETHODCALLTYPE * Release) (ma_IAudioCaptureClient* pThis); + + /* IAudioClock */ + HRESULT (STDMETHODCALLTYPE * GetFrequency)(ma_IAudioClock* pThis, ma_uint64* pu64Frequency); + HRESULT (STDMETHODCALLTYPE * GetPosition)(ma_IAudioClock* pThis, ma_uint64* pu64Position, ma_uint64* pu64QPCPosition); + HRESULT (STDMETHODCALLTYPE * GetCharacteristics)(ma_IAudioClock* pThis, DWORD* pdwCharacteristics); +} ma_IAudioClockVtbl; +struct ma_IAudioClock +{ + ma_IAudioClockVtbl* lpVtbl; +}; +static MA_INLINE HRESULT ma_IAudioClock_GetFrequency(ma_IAudioClock* pThis, ma_uint64* pu64Frequency) { return pThis->lpVtbl->GetFrequency(pThis, pu64Frequency); } +static MA_INLINE HRESULT ma_IAudioClock_GetPosition(ma_IAudioClock* pThis, ma_uint64* pu64Position, ma_uint64* pu64QPCPosition) { return pThis->lpVtbl->GetPosition(pThis, pu64Position, pu64QPCPosition); } +static MA_INLINE HRESULT ma_IAudioClock_GetCharacteristics(ma_IAudioClock* pThis, DWORD* pdwCharacteristics) { return pThis->lpVtbl->GetCharacteristics(pThis, pdwCharacteristics); } + #if defined(MA_WIN32_UWP) /* mmdevapi Functions */ typedef HRESULT (WINAPI * MA_PFN_ActivateAudioInterfaceAsync)(const wchar_t* deviceInterfacePath, const IID* riid, MA_PROPVARIANT* activationParams, ma_IActivateAudioInterfaceCompletionHandler* completionHandler, ma_IActivateAudioInterfaceAsyncOperation** activationOperation); @@ -21248,6 +21275,7 @@ static ma_thread_result MA_THREADCALL ma_context_command_thread__wasapi(void* pU } else { *cmd.data.createAudioClient.pResult = ma_result_from_HRESULT(ma_IAudioClient_GetService((ma_IAudioClient*)cmd.data.createAudioClient.pAudioClient, &MA_IID_IAudioCaptureClient, cmd.data.createAudioClient.ppAudioClientService)); } + ma_IAudioClient_GetService((ma_IAudioClient*)cmd.data.createAudioClient.pAudioClient, &MA_IID_IAudioClock, cmd.data.createAudioClient.ppAudioClock); } break; case MA_CONTEXT_COMMAND_RELEASE_IAUDIOCLIENT__WASAPI: @@ -21286,7 +21314,7 @@ static ma_thread_result MA_THREADCALL ma_context_command_thread__wasapi(void* pU return (ma_thread_result)0; } -static ma_result ma_device_create_IAudioClient_service__wasapi(ma_context* pContext, ma_device_type deviceType, ma_IAudioClient* pAudioClient, void** ppAudioClientService) +static ma_result ma_device_create_IAudioClient_service__wasapi(ma_context* pContext, ma_device_type deviceType, ma_IAudioClient* pAudioClient, void** ppAudioClientService, void **ppAudioClock) { ma_result result; ma_result cmdResult; @@ -21294,6 +21322,7 @@ static ma_result ma_device_create_IAudioClient_service__wasapi(ma_context* pCont cmd.data.createAudioClient.deviceType = deviceType; cmd.data.createAudioClient.pAudioClient = (void*)pAudioClient; cmd.data.createAudioClient.ppAudioClientService = ppAudioClientService; + cmd.data.createAudioClient.ppAudioClock = ppAudioClock; cmd.data.createAudioClient.pResult = &cmdResult; /* Declared locally, but won't be dereferenced after this function returns since execution of the command will wait here. */ result = ma_context_post_command__wasapi(pContext, &cmd); /* This will not return until the command has actually been run. */ @@ -22121,6 +22150,7 @@ typedef struct ma_IAudioClient* pAudioClient; ma_IAudioRenderClient* pRenderClient; ma_IAudioCaptureClient* pCaptureClient; + ma_IAudioClock* pAudioClock; ma_format formatOut; ma_uint32 channelsOut; ma_uint32 sampleRateOut; @@ -22160,6 +22190,7 @@ static ma_result ma_device_init_internal__wasapi(ma_context* pContext, ma_device pData->pAudioClient = NULL; pData->pRenderClient = NULL; pData->pCaptureClient = NULL; + pData->pAudioClock = NULL; streamFlags = MA_AUDCLNT_STREAMFLAGS_EVENTCALLBACK; if (!pData->noAutoConvertSRC && pData->sampleRateIn != 0 && pData->shareMode != ma_share_mode_exclusive) { /* <-- Exclusive streams must use the native sample rate. */ @@ -22530,9 +22561,9 @@ static ma_result ma_device_init_internal__wasapi(ma_context* pContext, ma_device if (deviceType == ma_device_type_playback) { - result = ma_device_create_IAudioClient_service__wasapi(pContext, deviceType, (ma_IAudioClient*)pData->pAudioClient, (void**)&pData->pRenderClient); + result = ma_device_create_IAudioClient_service__wasapi(pContext, deviceType, (ma_IAudioClient*)pData->pAudioClient, (void**)&pData->pRenderClient, (void**)&pData->pAudioClock); } else { - result = ma_device_create_IAudioClient_service__wasapi(pContext, deviceType, (ma_IAudioClient*)pData->pAudioClient, (void**)&pData->pCaptureClient); + result = ma_device_create_IAudioClient_service__wasapi(pContext, deviceType, (ma_IAudioClient*)pData->pAudioClient, (void**)&pData->pCaptureClient, (void**)&pData->pAudioClock); } /*if (FAILED(hr)) {*/ @@ -22693,6 +22724,7 @@ static ma_result ma_device_reinit__wasapi(ma_device* pDevice, ma_device_type dev if (deviceType == ma_device_type_capture || deviceType == ma_device_type_loopback) { pDevice->wasapi.pAudioClientCapture = data.pAudioClient; pDevice->wasapi.pCaptureClient = data.pCaptureClient; + pDevice->wasapi.pAudioClock = data.pAudioClock; pDevice->capture.internalFormat = data.formatOut; pDevice->capture.internalChannels = data.channelsOut; @@ -22714,6 +22746,7 @@ static ma_result ma_device_reinit__wasapi(ma_device* pDevice, ma_device_type dev if (deviceType == ma_device_type_playback) { pDevice->wasapi.pAudioClientPlayback = data.pAudioClient; pDevice->wasapi.pRenderClient = data.pRenderClient; + pDevice->wasapi.pAudioClock = data.pAudioClock; pDevice->playback.internalFormat = data.formatOut; pDevice->playback.internalChannels = data.channelsOut; @@ -22783,6 +22816,7 @@ static ma_result ma_device_init__wasapi(ma_device* pDevice, const ma_device_conf pDevice->wasapi.pAudioClientCapture = data.pAudioClient; pDevice->wasapi.pCaptureClient = data.pCaptureClient; + pDevice->wasapi.pAudioClock = data.pAudioClock; pDevice->wasapi.originalPeriodSizeInMilliseconds = pDescriptorCapture->periodSizeInMilliseconds; pDevice->wasapi.originalPeriodSizeInFrames = pDescriptorCapture->periodSizeInFrames; pDevice->wasapi.originalPeriods = pDescriptorCapture->periodCount; @@ -22862,6 +22896,7 @@ static ma_result ma_device_init__wasapi(ma_device* pDevice, const ma_device_conf pDevice->wasapi.pAudioClientPlayback = data.pAudioClient; pDevice->wasapi.pRenderClient = data.pRenderClient; + pDevice->wasapi.pAudioClock = data.pAudioClock; pDevice->wasapi.originalPeriodSizeInMilliseconds = pDescriptorPlayback->periodSizeInMilliseconds; pDevice->wasapi.originalPeriodSizeInFrames = pDescriptorPlayback->periodSizeInFrames; pDevice->wasapi.originalPeriods = pDescriptorPlayback->periodCount;