medfall

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

commit bd18dda0f3aa406641f7f55a8e67c6deddfd8030
parent 53aba482ca5d34f6c2dc100ef7b5f90d089390d5
Author: Michael Savage <mikejsavage@gmail.com>
Date:   Mon Jan 23 23:22:33 +0200

Start working on Windows audio output with XAudio2

Diffstat:
platform_audio_output.cc | 4+++-
platform_audio_output.h | 4+++-
win32_audio_output.cc | 106+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
win32_audio_output.h | 9+++++++++
4 files changed, 121 insertions(+), 2 deletions(-)
diff --git a/platform_audio_output.cc b/platform_audio_output.cc @@ -1,6 +1,8 @@ #include "platform.h" -#if PLATFORM_LINUX +#if PLATFORM_WINDOWS +#include "win32_audio_output.cc" +#elif PLATFORM_LINUX #include "linux_audio_output.cc" #elif PLATFORM_OSX #include "darwin_audio_output.cc" diff --git a/platform_audio_output.h b/platform_audio_output.h @@ -14,7 +14,9 @@ void audio_output_term(); void audio_output_open( AudioOutputDevice * device, AudioOutputCallback callback ); void audio_output_close( AudioOutputDevice * device ); -#if PLATFORM_LINUX +#if PLATFORM_WINDOWS +#include "win32_audio_output.h" +#elif PLATFORM_LINUX #include "linux_audio_output.h" #elif PLATFORM_OSX #include "darwin_audio_output.h" diff --git a/win32_audio_output.cc b/win32_audio_output.cc @@ -0,0 +1,106 @@ +// https://github.com/walbourn/directx-sdk-samples/blob/master/XAudio2/XAudio2AsyncStream/XAudio2AsyncStream.cpp + +#include <windows.h> +#include <wrl/client.h> +#include <C:/Program Files (x86)/Microsoft DirectX SDK (June 2010)/Include/comdecl.h> +#include <C:/Program Files (x86)/Microsoft DirectX SDK (June 2010)/Include/xaudio2.h> + +#include "intrinsics.h" +#include "log.h" +#include "platform_audio_output.h" +// #include "platform_library.h" +#include "platform_thread.h" + +// static Library xaudio_lib = NULL; + +static IXAudio2 * xaudio2 = NULL; +static IXAudio2MasteringVoice * mastering_voice = NULL; + +void audio_output_init() { + if( FAILED( CoInitializeEx( nullptr, COINIT_MULTITHREADED ) ) ) { + FATAL( "CoInitializeEx" ); + } + + if( FAILED( XAudio2Create( &xaudio2, 0, XAUDIO2_DEFAULT_PROCESSOR ) ) ) { + FATAL( "XAudio2Create" ); + } + + if( FAILED( xaudio2->CreateMasteringVoice( &mastering_voice ) ) ) { + FATAL( "CreateMasteringVoice" ); + } + + // xaudio_lib = library_open( "xaudio2_7.dll" ); + // if( xaudio_lib == NULL ) { + // FATAL( "Couldn't open xaudio2_7.dll: %s", library_last_error() ); + // } +} + +void audio_output_term() { + // library_close( xaudio_lib ); + + mastering_voice->DestroyVoice(); + xaudio2->Reset(); + + CoUninitialize(); + + xaudio2 = NULL; + mastering_voice = NULL; +} + +static THREAD( audio_output_thread ) { + AudioOutputDevice * device = ( AudioOutputDevice * ) data; + + // double buffering + s16 buffers[ 1024 ][ 2 ]; + u32 buffer_idx = 0; + for( ;; ) { + for( ;; ) { + XAUDIO2_VOICE_STATE state; + device->voice->GetState( &state ); + if( state.BuffersQueued < ARRAY_COUNT( buffers ) - 1 ) { + break; + } + + // WaitForSingleObject( voiceContext.hBufferEndEvent, INFINITE ); + // TODO: wait for semaphore or something + } + + device->callback( buffers[ buffer_idx ], ARRAY_COUNT( buffers[ buffer_idx ] ) ); + + XAUDIO2_BUFFER buf; + zero( &buf ); + buf.AudioBytes = sizeof( buffers[ buffer_idx ] ); + buf.pAudioData = buffers[ buffer_idx ]; + + if( FAILED( device->voice->SubmitSourceBuffer( &buf ) ) ) { + FATAL( "SubmitSourceBuffer" ); + } + + buffer_idx = ( buffer_idx + 1 ) % ARRAY_COUNT( buffers ); + } + + THREAD_END; +} + +void audio_output_open( AudioOutputDevice * device, AudioOutputCallback callback ) { + WAVEFORMATEX format; + zero( &format ); + format.wFormatTag = 1; + format.nChannels = 1; + format.nSamplesPerSec = 44100; + format.nAvgBytesPerSec = 44100; + format.nBlockAlign = 1; + format.wBitsPerSample = 8; + format.cbSize = 0; + + if( FAILED( xaudio2->CreateSourceVoice( &device->voice, &format ) ) ) { + FATAL( "CreateSourceVoice" ); + } + + device->voice->start( 0, 0 ); +} + +void audio_output_close( AudioOutputDevice * device ) { + device->voice->Stop( 0 ); + device->voice->DestroyVoice(); +} diff --git a/win32_audio_output.h b/win32_audio_output.h @@ -0,0 +1,9 @@ +#pragma once + +#include "platform_thread.h" + +struct AudioOutputDevice { + IXAudio2SourceVoice * voice; + Thread thread; + AudioOutputCallback * callback; +};