|   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;
}
 |