Skip to content

Commit c4761e0

Browse files
WASAPI : Detect IAudioClient3 at runtime
1 parent 0d34adf commit c4761e0

File tree

1 file changed

+44
-90
lines changed

1 file changed

+44
-90
lines changed

RtAudio.cpp

Lines changed: 44 additions & 90 deletions
Original file line numberDiff line numberDiff line change
@@ -4203,13 +4203,8 @@ class WasapiResampler
42034203
// A structure to hold various information related to the WASAPI implementation.
42044204
struct WasapiHandle
42054205
{
4206-
#ifdef __IAudioClient3_INTERFACE_DEFINED__
4207-
IAudioClient3* captureAudioClient;
4208-
IAudioClient3* renderAudioClient;
4209-
#else
42104206
IAudioClient* captureAudioClient;
42114207
IAudioClient* renderAudioClient;
4212-
#endif
42134208
IAudioCaptureClient* captureClient;
42144209
IAudioRenderClient* renderClient;
42154210
HANDLE captureEvent;
@@ -4327,11 +4322,7 @@ RtAudio::DeviceInfo RtApiWasapi::getDeviceInfo( unsigned int device )
43274322
IMMDeviceCollection* renderDevices = NULL;
43284323
IMMDevice* devicePtr = NULL;
43294324
IMMDevice* defaultDevicePtr = NULL;
4330-
#ifdef __IAudioClient3_INTERFACE_DEFINED__
4331-
IAudioClient3* audioClient = NULL;
4332-
#else
43334325
IAudioClient* audioClient = NULL;
4334-
#endif
43354326
IPropertyStore* devicePropStore = NULL;
43364327
IPropertyStore* defaultDevicePropStore = NULL;
43374328

@@ -4453,11 +4444,7 @@ RtAudio::DeviceInfo RtApiWasapi::getDeviceInfo( unsigned int device )
44534444
}
44544445

44554446
// channel count
4456-
#ifdef __IAudioClient3_INTERFACE_DEFINED__
4457-
hr = devicePtr->Activate( __uuidof( IAudioClient3 ), CLSCTX_ALL, NULL, ( void** ) &audioClient );
4458-
#else
44594447
hr = devicePtr->Activate( __uuidof( IAudioClient ), CLSCTX_ALL, NULL, ( void** ) &audioClient );
4460-
#endif
44614448
if ( FAILED( hr ) ) {
44624449
errorText_ = "RtApiWasapi::getDeviceInfo: Unable to retrieve device audio client.";
44634450
goto Exit;
@@ -4750,23 +4737,15 @@ bool RtApiWasapi::probeDeviceOpen( unsigned int device, StreamMode mode, unsigne
47504737
}
47514738

47524739
// retrieve captureAudioClient from devicePtr
4753-
#ifdef __IAudioClient3_INTERFACE_DEFINED__
4754-
IAudioClient3*& captureAudioClient = ( ( WasapiHandle* ) stream_.apiHandle )->captureAudioClient;
4755-
#else
47564740
IAudioClient*& captureAudioClient = ( ( WasapiHandle* ) stream_.apiHandle )->captureAudioClient;
4757-
#endif
47584741

47594742
hr = captureDevices->Item( device - renderDeviceCount, &devicePtr );
47604743
if ( FAILED( hr ) ) {
47614744
errorText_ = "RtApiWasapi::probeDeviceOpen: Unable to retrieve capture device handle.";
47624745
goto Exit;
47634746
}
47644747

4765-
#ifdef __IAudioClient3_INTERFACE_DEFINED__
4766-
hr = devicePtr->Activate( __uuidof( IAudioClient3 ), CLSCTX_ALL,
4767-
#else
47684748
hr = devicePtr->Activate( __uuidof( IAudioClient ), CLSCTX_ALL,
4769-
#endif
47704749
NULL, ( void** ) &captureAudioClient );
47714750
if ( FAILED( hr ) ) {
47724751
errorText_ = "RtApiWasapi::probeDeviceOpen: Unable to retrieve capture device audio client.";
@@ -4787,34 +4766,22 @@ bool RtApiWasapi::probeDeviceOpen( unsigned int device, StreamMode mode, unsigne
47874766
if ( device < renderDeviceCount && mode == INPUT )
47884767
{
47894768
// if renderAudioClient is not initialised, initialise it now
4790-
#ifdef __IAudioClient3_INTERFACE_DEFINED__
4791-
IAudioClient3*& renderAudioClient = ( ( WasapiHandle* ) stream_.apiHandle )->renderAudioClient;
4792-
#else
47934769
IAudioClient*& renderAudioClient = ( ( WasapiHandle* ) stream_.apiHandle )->renderAudioClient;
4794-
#endif
47954770
if ( !renderAudioClient )
47964771
{
47974772
probeDeviceOpen( device, OUTPUT, channels, firstChannel, sampleRate, format, bufferSize, options );
47984773
}
47994774

48004775
// retrieve captureAudioClient from devicePtr
4801-
#ifdef __IAudioClient3_INTERFACE_DEFINED__
4802-
IAudioClient3*& captureAudioClient = ( ( WasapiHandle* ) stream_.apiHandle )->captureAudioClient;
4803-
#else
48044776
IAudioClient*& captureAudioClient = ( ( WasapiHandle* ) stream_.apiHandle )->captureAudioClient;
4805-
#endif
48064777

48074778
hr = renderDevices->Item( device, &devicePtr );
48084779
if ( FAILED( hr ) ) {
48094780
errorText_ = "RtApiWasapi::probeDeviceOpen: Unable to retrieve render device handle.";
48104781
goto Exit;
48114782
}
48124783

4813-
#ifdef __IAudioClient3_INTERFACE_DEFINED__
4814-
hr = devicePtr->Activate( __uuidof( IAudioClient3 ), CLSCTX_ALL,
4815-
#else
48164784
hr = devicePtr->Activate( __uuidof( IAudioClient ), CLSCTX_ALL,
4817-
#endif
48184785
NULL, ( void** ) &captureAudioClient );
48194786
if ( FAILED( hr ) ) {
48204787
errorText_ = "RtApiWasapi::probeDeviceOpen: Unable to retrieve render device audio client.";
@@ -4835,11 +4802,7 @@ bool RtApiWasapi::probeDeviceOpen( unsigned int device, StreamMode mode, unsigne
48354802
if ( device < renderDeviceCount && mode == OUTPUT )
48364803
{
48374804
// if renderAudioClient is already initialised, don't initialise it again
4838-
#ifdef __IAudioClient3_INTERFACE_DEFINED__
4839-
IAudioClient3*& renderAudioClient = ( ( WasapiHandle* ) stream_.apiHandle )->renderAudioClient;
4840-
#else
48414805
IAudioClient*& renderAudioClient = ( ( WasapiHandle* ) stream_.apiHandle )->renderAudioClient;
4842-
#endif
48434806
if ( renderAudioClient )
48444807
{
48454808
methodResult = SUCCESS;
@@ -4852,11 +4815,7 @@ bool RtApiWasapi::probeDeviceOpen( unsigned int device, StreamMode mode, unsigne
48524815
goto Exit;
48534816
}
48544817

4855-
#ifdef __IAudioClient3_INTERFACE_DEFINED__
4856-
hr = devicePtr->Activate( __uuidof( IAudioClient3 ), CLSCTX_ALL,
4857-
#else
48584818
hr = devicePtr->Activate( __uuidof( IAudioClient ), CLSCTX_ALL,
4859-
#endif
48604819
NULL, ( void** ) &renderAudioClient );
48614820
if ( FAILED( hr ) ) {
48624821
errorText_ = "RtApiWasapi::probeDeviceOpen: Unable to retrieve render device audio client.";
@@ -4982,13 +4941,8 @@ void RtApiWasapi::wasapiThread()
49824941

49834942
HRESULT hr;
49844943

4985-
#ifdef __IAudioClient3_INTERFACE_DEFINED__
4986-
IAudioClient3* captureAudioClient = ( ( WasapiHandle* ) stream_.apiHandle )->captureAudioClient;
4987-
IAudioClient3* renderAudioClient = ( ( WasapiHandle* ) stream_.apiHandle )->renderAudioClient;
4988-
#else
49894944
IAudioClient* captureAudioClient = ( ( WasapiHandle* ) stream_.apiHandle )->captureAudioClient;
49904945
IAudioClient* renderAudioClient = ( ( WasapiHandle* ) stream_.apiHandle )->renderAudioClient;
4991-
#endif
49924946
IAudioCaptureClient* captureClient = ( ( WasapiHandle* ) stream_.apiHandle )->captureClient;
49934947
IAudioRenderClient* renderClient = ( ( WasapiHandle* ) stream_.apiHandle )->renderClient;
49944948
HANDLE captureEvent = ( ( WasapiHandle* ) stream_.apiHandle )->captureEvent;
@@ -5050,43 +5004,37 @@ void RtApiWasapi::wasapiThread()
50505004
captureSrRatio = ( ( float ) captureFormat->nSamplesPerSec / stream_.sampleRate );
50515005

50525006
if ( !captureClient ) {
5053-
#ifdef __IAudioClient3_INTERFACE_DEFINED__
5054-
if ( !loopbackEnabled )
5007+
IAudioClient3* captureAudioClient3 = nullptr;
5008+
captureAudioClient->QueryInterface( __uuidof( IAudioClient3 ), ( void** ) &captureAudioClient3 );
5009+
if ( captureAudioClient3 && !loopbackEnabled )
50555010
{
50565011
UINT32 Ignore;
50575012
UINT32 MinPeriodInFrames;
5058-
hr = captureAudioClient->GetSharedModeEnginePeriod( captureFormat,
5059-
&Ignore,
5060-
&Ignore,
5061-
&MinPeriodInFrames,
5062-
&Ignore );
5013+
hr = captureAudioClient3->GetSharedModeEnginePeriod( captureFormat,
5014+
&Ignore,
5015+
&Ignore,
5016+
&MinPeriodInFrames,
5017+
&Ignore );
50635018
if ( FAILED( hr ) ) {
50645019
errorText = "RtApiWasapi::wasapiThread: Unable to initialize capture audio client.";
50655020
goto Exit;
50665021
}
50675022

5068-
hr = captureAudioClient->InitializeSharedAudioStream( AUDCLNT_STREAMFLAGS_EVENTCALLBACK,
5069-
MinPeriodInFrames,
5070-
captureFormat,
5071-
NULL );
5023+
hr = captureAudioClient3->InitializeSharedAudioStream( AUDCLNT_STREAMFLAGS_EVENTCALLBACK,
5024+
MinPeriodInFrames,
5025+
captureFormat,
5026+
NULL );
50725027
}
50735028
else
50745029
{
50755030
hr = captureAudioClient->Initialize( AUDCLNT_SHAREMODE_SHARED,
5076-
AUDCLNT_STREAMFLAGS_LOOPBACK,
5031+
loopbackEnabled ? AUDCLNT_STREAMFLAGS_LOOPBACK : AUDCLNT_STREAMFLAGS_EVENTCALLBACK,
50775032
0,
50785033
0,
50795034
captureFormat,
50805035
NULL );
50815036
}
5082-
#else
5083-
hr = captureAudioClient->Initialize( AUDCLNT_SHAREMODE_SHARED,
5084-
loopbackEnabled ? AUDCLNT_STREAMFLAGS_LOOPBACK : AUDCLNT_STREAMFLAGS_EVENTCALLBACK,
5085-
0,
5086-
0,
5087-
captureFormat,
5088-
NULL );
5089-
#endif
5037+
50905038
if ( FAILED( hr ) ) {
50915039
errorText = "RtApiWasapi::wasapiThread: Unable to initialize capture audio client.";
50925040
goto Exit;
@@ -5167,31 +5115,37 @@ void RtApiWasapi::wasapiThread()
51675115
renderSrRatio = ( ( float ) renderFormat->nSamplesPerSec / stream_.sampleRate );
51685116

51695117
if ( !renderClient ) {
5170-
#ifdef __IAudioClient3_INTERFACE_DEFINED__
5171-
UINT32 Ignore;
5172-
UINT32 MinPeriodInFrames;
5173-
hr = renderAudioClient->GetSharedModeEnginePeriod( renderFormat,
5174-
&Ignore,
5175-
&Ignore,
5176-
&MinPeriodInFrames,
5177-
&Ignore );
5178-
if ( FAILED( hr ) ) {
5179-
errorText = "RtApiWasapi::wasapiThread: Unable to initialize render audio client.";
5180-
goto Exit;
5118+
IAudioClient3* renderAudioClient3 = nullptr;
5119+
renderAudioClient->QueryInterface( __uuidof( IAudioClient3 ), ( void** ) &renderAudioClient3 );
5120+
if ( renderAudioClient3 )
5121+
{
5122+
UINT32 Ignore;
5123+
UINT32 MinPeriodInFrames;
5124+
hr = renderAudioClient3->GetSharedModeEnginePeriod( renderFormat,
5125+
&Ignore,
5126+
&Ignore,
5127+
&MinPeriodInFrames,
5128+
&Ignore );
5129+
if ( FAILED( hr ) ) {
5130+
errorText = "RtApiWasapi::wasapiThread: Unable to initialize render audio client.";
5131+
goto Exit;
5132+
}
5133+
5134+
hr = renderAudioClient3->InitializeSharedAudioStream( AUDCLNT_STREAMFLAGS_EVENTCALLBACK,
5135+
MinPeriodInFrames,
5136+
renderFormat,
5137+
NULL );
51815138
}
5182-
5183-
hr = renderAudioClient->InitializeSharedAudioStream( AUDCLNT_STREAMFLAGS_EVENTCALLBACK,
5184-
MinPeriodInFrames,
5185-
renderFormat,
5186-
NULL );
5187-
#else
5188-
hr = renderAudioClient->Initialize( AUDCLNT_SHAREMODE_SHARED,
5189-
AUDCLNT_STREAMFLAGS_EVENTCALLBACK,
5190-
0,
5191-
0,
5192-
renderFormat,
5193-
NULL );
5194-
#endif
5139+
else
5140+
{
5141+
hr = renderAudioClient->Initialize( AUDCLNT_SHAREMODE_SHARED,
5142+
AUDCLNT_STREAMFLAGS_EVENTCALLBACK,
5143+
0,
5144+
0,
5145+
renderFormat,
5146+
NULL );
5147+
}
5148+
51955149
if ( FAILED( hr ) ) {
51965150
errorText = "RtApiWasapi::wasapiThread: Unable to initialize render audio client.";
51975151
goto Exit;

0 commit comments

Comments
 (0)