1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121 | // To get the c interface even in .cpp
// #define CINTERFACE
#define COBJMACROS
#include <audioclient.h>
#include <Mmdeviceapi.h>
b32 sound_create( PlatformSpecific* platform, sound_Format* format, u32* bufferSizeInSamples ) {
b32 result = false;
IMMDeviceEnumerator* enumerator;
/* TODO simon: make sure that Ole32.dll is present by default on windows. */
HMODULE oleDLL = LoadLibrary( "Ole32.dll" );
typedef HRESULT ( *CoCreateInstance_type )( REFCLSID rclsid, LPUNKNOWN pUnkOuter, DWORD dwClsContext, REFIID riid, LPVOID *ppv );
CoCreateInstance_type CoCreateInstance = ( CoCreateInstance_type ) GetProcAddress( oleDLL, "CoCreateInstance" );
#define C_INTERFACE
#ifndef C_INTERFACE
HRESULT error = CoCreateInstance( __uuidof( MMDeviceEnumerator ), NULL, CLSCTX_ALL, __uuidof( IMMDeviceEnumerator ), ( void** ) &enumerator );
#else
HRESULT error = CoCreateInstance( &CLSID_MMDeviceEnumerator, NULL, CLSCTX_ALL, &IID_IMMDeviceEnumerator, ( void** ) &enumerator );
#endif
FreeLibrary( oleDLL );
if ( error == S_OK ) {
IMMDevice* device;
#ifndef C_INTERFACE
error = enumerator->GetDefaultAudioEndpoint( eRender, eConsole, &device );
#else
error = IMMDeviceEnumerator_GetDefaultAudioEndpoint( enumerator, eRender, eConsole, &device );
#endif
if ( error == S_OK ) {
#ifndef C_INTERFACE
error = device->Activate( __uuidof( IAudioClient ), CLSCTX_ALL, NULL, ( void** ) &platform->audioClient );
#else
error = IMMDevice_Activate( device, &IID_IAudioClient, CLSCTX_ALL, NULL, ( void** ) &platform->audioClient );
#endif
if ( error == S_OK ) {
WAVEFORMATEXTENSIBLE bufferFormat;
bufferFormat.Format.wFormatTag = WAVE_FORMAT_EXTENSIBLE;
bufferFormat.Format.nChannels = format->channelCount;
bufferFormat.Format.nSamplesPerSec = format->samplesPerSecond;
bufferFormat.Format.wBitsPerSample = format->containerSize * 8;
bufferFormat.Format.nBlockAlign = bufferFormat.Format.nChannels * format->containerSize;
bufferFormat.Format.nAvgBytesPerSec = bufferFormat.Format.nSamplesPerSec * bufferFormat.Format.nBlockAlign;
bufferFormat.Format.cbSize = sizeof( bufferFormat );
bufferFormat.Samples.wValidBitsPerSample = format->bitsPerSample;
bufferFormat.dwChannelMask = format->channelMask;
WAVE_EXTENSIBLE_GUID( WAVE_FORMAT_PCM, ( u8* ) &bufferFormat.SubFormat );
/* NOTE simon: 1 reference_time = 100 nanoseconds = 1 sec / 10 000 000. */
REFERENCE_TIME bufferDuration = 10000000;
#ifndef C_INTERFACE
error = platform->audioClient->Initialize( AUDCLNT_SHAREMODE_SHARED, 0, bufferDuration, 0, &bufferFormat.Format, 0 );
#else
error = IAudioClient_Initialize( platform->audioClient, AUDCLNT_SHAREMODE_SHARED, 0, bufferDuration, 0, &bufferFormat.Format, 0 );
#endif
if ( error == S_OK ) {
#ifndef C_INTERFACE
error = platform->audioClient->GetBufferSize( bufferSizeInSamples );
#else
error = IAudioClient_GetBufferSize( platform->audioClient, bufferSizeInSamples );
#endif
_assert( *bufferSizeInSamples == format->samplesPerSecond );
#ifndef C_INTERFACE
error = platform->audioClient->GetService( __uuidof( IAudioRenderClient ), ( void** ) &platform->audioRenderClient );
#else
error = IAudioClient_GetService( platform->audioClient, &IID_IAudioRenderClient, ( void** ) &platform->audioRenderClient );
#endif
if ( error == S_OK ) {
result = true;
} else {
#ifndef C_INTERFACE
platform->audioClient->Release( );
#else
IAudioClient_Release( platform->audioClient );
#endif
platform->audioClient = 0;
}
} else {
#ifndef C_INTERFACE
platform->audioClient->Release( );
#else
IAudioClient_Release( platform->audioClient );
#endif
platform->audioClient = 0;
}
}
#ifndef C_INTERFACE
device->Release( );
#else
IMMDevice_Release( device );
#endif
}
#ifndef C_INTERFACE
enumerator->Release( );
#else
IMMDeviceEnumerator_Release( enumerator );
#endif
}
return result;
}
|