medfall

Unnamed repository; edit this file 'description' to name the repository.
Log | Files | Refs

commit e95be30d56f79f2c9eda79b28549225d2ef9e36f
parent 48fd654a1d0e5e600c47898b7da9097a77c41fb8
Author: Michael Savage <mikejsavage@gmail.com>
Date:   Thu Jan 26 23:24:26 +0200

XAudio2 works!

Diffstat:
win32_audio_output.cc | 51++++++++++++++++++++++++++++++++++++++-------------
win32_audio_output.h | 18++----------------
2 files changed, 40 insertions(+), 29 deletions(-)
diff --git a/win32_audio_output.cc b/win32_audio_output.cc @@ -11,11 +11,27 @@ #include "platform_library.h" #include "platform_thread.h" +struct XAudioCallbacks : public IXAudio2VoiceCallback { + void __stdcall OnBufferEnd( void * data ) { + HANDLE event = ( HANDLE ) data; + SetEvent( event ); + } + + void __stdcall OnBufferStart( void * ) { } + void __stdcall OnLoopEnd( void * ) { } + void __stdcall OnStreamEnd() { } + void __stdcall OnVoiceError( void *, HRESULT ) { } + void __stdcall OnVoiceProcessingPassStart( u32 ) { } + void __stdcall OnVoiceProcessingPassEnd() { } +}; + static Library xaudio2_lib = NULL; static IXAudio2 * xaudio2 = NULL; static IXAudio2MasteringVoice * mastering_voice = NULL; +static XAudioCallbacks callbacks; + void audio_output_init() { if( FAILED( CoInitializeEx( nullptr, COINIT_MULTITHREADED ) ) ) { FATAL( "CoInitializeEx" ); @@ -23,7 +39,7 @@ void audio_output_init() { xaudio2_lib = library_open( "XAudio2_7.dll" ); if( xaudio2_lib == NULL ) { - FATAL( "Couldn't open xaudio2_7.dll: %s", library_last_error() ); + FATAL( "Couldn't open XAudio2_7.dll: %s", library_last_error() ); } if( FAILED( XAudio2Create( &xaudio2, 0, XAUDIO2_DEFAULT_PROCESSOR ) ) ) { @@ -36,7 +52,9 @@ void audio_output_init() { } void audio_output_term() { + xaudio2->StopEngine(); mastering_voice->DestroyVoice(); + xaudio2->Release(); library_close( xaudio2_lib ); CoUninitialize(); @@ -49,17 +67,17 @@ static THREAD( audio_output_thread ) { AudioOutputDevice * device = ( AudioOutputDevice * ) data; // double buffering - s16 buffers[ 256 ][ 2 ]; + s16 buffers[ 3 ][ 256 ]; u32 buffer_idx = 0; for( ;; ) { for( ;; ) { XAUDIO2_VOICE_STATE state; device->voice->GetState( &state ); - if( state.BuffersQueued < ARRAY_COUNT( buffers ) - 1 ) { + if( state.BuffersQueued < ARRAY_COUNT( buffers ) ) { break; } - WaitForSingleObject( device->callbacks.event, INFINITE ); + WaitForSingleObject( device->event, INFINITE ); } device->callback( buffers[ buffer_idx ], ARRAY_COUNT( buffers[ buffer_idx ] ) ); @@ -68,6 +86,7 @@ static THREAD( audio_output_thread ) { zero_struct( &buf ); buf.AudioBytes = sizeof( buffers[ buffer_idx ] ); buf.pAudioData = ( const BYTE * ) buffers[ buffer_idx ]; + buf.pContext = device->event; if( FAILED( device->voice->SubmitSourceBuffer( &buf ) ) ) { FATAL( "SubmitSourceBuffer" ); @@ -82,30 +101,36 @@ static THREAD( audio_output_thread ) { void audio_output_open( AudioOutputDevice * device, AudioOutputCallback callback ) { WAVEFORMATEX format; zero_struct( &format ); - format.wFormatTag = 1; + format.wFormatTag = WAVE_FORMAT_PCM; format.nChannels = 1; format.nSamplesPerSec = 44100; - format.nAvgBytesPerSec = 44100; - format.nBlockAlign = 1; - format.wBitsPerSample = 8; - format.cbSize = 0; + format.wBitsPerSample = 16; + format.nBlockAlign = format.nChannels * format.wBitsPerSample / 8; + format.nAvgBytesPerSec = format.nSamplesPerSec * format.nBlockAlign; - if( FAILED( xaudio2->CreateSourceVoice( &device->voice, &format, 0, 0, &device->callbacks ) ) ) { + if( FAILED( xaudio2->CreateSourceVoice( &device->voice, &format, 0, 1.0f, &callbacks ) ) ) { FATAL( "CreateSourceVoice" ); } - device->callbacks.event = CreateEvent( NULL, FALSE, FALSE, NULL ); - if( device->callbacks.event == NULL ) { + device->event = CreateEvent( NULL, FALSE, FALSE, NULL ); + if( device->event == NULL ) { FATAL( "CreateEvent" ); } device->voice->Start( 0 ); + + device->callback = callback; + thread_init( &device->thread, audio_output_thread, device ); } void audio_output_close( AudioOutputDevice * device ) { + //thread_cancel( &device->thread ); + //thread_join( &device->thread ); + device->voice->Stop( 0 ); + device->voice->FlushSourceBuffers(); device->voice->DestroyVoice(); - if( CloseHandle( device->callbacks.event ) == 0 ) { + if( CloseHandle( device->event ) == 0 ) { FATAL( "CloseHandle" ); } } diff --git a/win32_audio_output.h b/win32_audio_output.h @@ -3,26 +3,12 @@ #include "intrinsics.h" #include "platform_thread.h" +#include <windows.h> #include <xaudio2.h> -struct AudioCallbacks : public IXAudio2VoiceCallback { - HANDLE event; - - void __stdcall OnBufferEnd( void * ) { - SetEvent( event ); - } - - void __stdcall OnBufferStart( void * ) { } - void __stdcall OnLoopEnd( void * ) { } - void __stdcall OnStreamEnd() { } - void __stdcall OnVoiceError( void *, HRESULT ) { } - void __stdcall OnVoiceProcessingPassStart( u32 ) { } - void __stdcall OnVoiceProcessingPassEnd() { } -}; - struct AudioOutputDevice { IXAudio2SourceVoice * voice; - AudioCallbacks callbacks; + HANDLE event; Thread thread; AudioOutputCallback * callback; };