medfall

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

commit 817038f43b95090e2223ae1814878d0f00fdad61
parent 3d53ac04ea38e49dfa24a9a0426809880577a190
Author: Michael Savage <mikejsavage@gmail.com>
Date:   Wed Sep 14 22:30:25 +0100

*_audio.h -> *_audio_output.h, split linux_audio into header and implementation

Diffstat:
Makefile | 2+-
audio.cc | 5+++--
linux_audio.h | 120-------------------------------------------------------------------------------
linux_audio_output.cc | 116+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
linux_audio_output.h | 19+++++++++++++++++++
mixer.cc | 2+-
mixer.h | 2+-
platform_audio.h | 10----------
platform_audio_output.cc | 7+++++++
platform_audio_output.h | 10++++++++++
10 files changed, 158 insertions(+), 135 deletions(-)
diff --git a/Makefile b/Makefile @@ -7,7 +7,7 @@ all: $(BINS) $(MODULES) test_lockfree # Binary dependencies medfall: main.o gl.o log.o memory_arena.o glad.o pp: pp.o log.o stb_image.o lz4.o lz4hc.o -sound: audio.o mixer.o log.o memory_arena.o wave.o +sound: audio.o mixer.o log.o memory_arena.o wave.o platform_audio_output.o srv: server/main.o rng/well512.o # Module dependencies diff --git a/audio.cc b/audio.cc @@ -6,8 +6,7 @@ #include "mixer.h" #include "wave.h" #include "assets.h" -#define PLATFORM_AUDIO_IMPLEMENTATION 1 -#include "platform_audio.h" +#include "platform_audio_output.h" static SoundData make_sin_wave( u32 sample_rate, u32 frequency ) { const u32 num_samples = sample_rate * ( 1.0f / frequency ); @@ -32,6 +31,8 @@ int main( int argc, char ** argv ) { MemoryArena arena; memarena_init( &arena, memory, sizeof( memory ) ); + audio_output_init(); + AudioOutputDevice output_device; audio_output_open( &output_device ); mixer_init( &output_device ); diff --git a/linux_audio.h b/linux_audio.h @@ -1,120 +0,0 @@ -#ifndef _LINUX_AUDIO_H_ -#define _LINUX_AUDIO_H_ - -#include <stdio.h> -#include <stdarg.h> -#include <dlfcn.h> - -#include <alsa/asoundlib.h> - -#include "intrinsics.h" -#include "log.h" - -struct AudioOutputDevice { - snd_pcm_t * pcm; -}; - -void audio_output_open( AudioOutputDevice * device ); -void audio_output_close( AudioOutputDevice * device ); -void audio_output_write( AudioOutputDevice * device, s16 * samples, size_t num_samples ); - -#endif // _LINUX_AUDIO_H_ - -#ifdef PLATFORM_AUDIO_IMPLEMENTATION - -// copied from alsa headers -static int ( *_snd_lib_error_set_handler )( snd_lib_error_handler_t handler ) = NULL; -static const char * ( *_snd_strerror )( int errnum ) = NULL; -static int ( *_snd_pcm_open )( snd_pcm_t ** pcm, const char * name, snd_pcm_stream_t stream, int mode ) = NULL; -static int ( *_snd_pcm_set_params )( snd_pcm_t * pcm, snd_pcm_format_t format, snd_pcm_access_t access, unsigned int channels, unsigned int rate, int soft_resample, unsigned int latency ) = NULL; -static snd_pcm_sframes_t ( *_snd_pcm_writen )( snd_pcm_t * pcm, void ** bufs, snd_pcm_uframes_t size ) = NULL; -static int ( *_snd_pcm_recover )( snd_pcm_t * pcm, int err, int silent ) = NULL; -static int ( *_snd_pcm_close )( snd_pcm_t * pcm ) = NULL; - -static void audio_error_handler( const char * file, int line, const char * function, int err, const char * fmt, ... ) { - printf( "error in %s at %s:%d\n", file, function, line ); - - va_list args; - va_start( args, fmt ); - vprintf( fmt, args ); - va_end( args ); - printf( "\n" ); -} - -void audio_output_open( AudioOutputDevice * device ) { - // TODO: make an audio_output_init_lib function to do this + dlload - static bool audio_inited = false; - if( !audio_inited ) { - void * alsa_lib = dlopen( "libasound.so", RTLD_NOW ); - if( alsa_lib == NULL ) { - FATAL( "Couldn't open libasound.so: %s", dlerror() ); - } - - _snd_lib_error_set_handler = ( int ( * )( snd_lib_error_handler_t ) ) dlsym( alsa_lib, "snd_lib_error_set_handler" ); - _snd_strerror = ( const char * ( * )( int ) ) dlsym( alsa_lib, "snd_strerror" ); - _snd_pcm_open = ( int ( * ) ( snd_pcm_t **, const char *, snd_pcm_stream_t, int ) ) dlsym( alsa_lib, "snd_pcm_open" ); - _snd_pcm_set_params = ( int ( * ) ( snd_pcm_t *, snd_pcm_format_t, snd_pcm_access_t, unsigned int, unsigned int, int, unsigned int ) ) dlsym( alsa_lib, "snd_pcm_set_params" ); - _snd_pcm_writen = ( snd_pcm_sframes_t ( * ) ( snd_pcm_t *, void **, snd_pcm_uframes_t ) ) dlsym( alsa_lib, "snd_pcm_writen" ); - _snd_pcm_recover = ( int ( * )( snd_pcm_t *, int, int ) ) dlsym( alsa_lib, "snd_pcm_recover" ); - _snd_pcm_close = ( int ( * ) ( snd_pcm_t * ) ) dlsym( alsa_lib, "snd_pcm_close" ); - - if( - _snd_lib_error_set_handler == NULL - || _snd_strerror == NULL - || _snd_pcm_open == NULL - || _snd_pcm_set_params == NULL - || _snd_pcm_writen == NULL - || _snd_pcm_recover == NULL - || _snd_pcm_close == NULL - ) { - FATAL( "Couldn't load ALSA functions" ); - } - - _snd_lib_error_set_handler( audio_error_handler ); - - audio_inited = true; - } - - const int channels = 2; - const int sample_rate = 44100; - const int ms = 1000; - const int latency = 10 * ms; - - int err_open = _snd_pcm_open( &device->pcm, "default", SND_PCM_STREAM_PLAYBACK, 0 ); - if( err_open != 0 ) { - // TODO: maybe don't kill the program - FATAL( "Couldn't open sound output: %s", _snd_strerror( err_open ) ); - } - - int err_params = _snd_pcm_set_params( device->pcm, - SND_PCM_FORMAT_S16_LE, SND_PCM_ACCESS_RW_NONINTERLEAVED, - channels, sample_rate, 1, latency ); - if( err_params != 0 ) { - // TODO: maybe don't kill the program - FATAL( "Couldn't configure sound output: %s", _snd_strerror( err_params ) ); - } -} - -void audio_output_close( AudioOutputDevice * device ) { - int err = _snd_pcm_close( device->pcm ); - if( err != 0 ) { - // TODO: maybe don't kill the program - FATAL( "Couldn't close sound output: %s", _snd_strerror( err ) ); - } -} - -void audio_output_write( AudioOutputDevice * device, s16 * samples, size_t num_samples ) { - for( u32 i = 0; i < num_samples; ) { - s16 * channels[ 2 ] = { samples + i, samples + i }; - - snd_pcm_sframes_t written = _snd_pcm_writen( device->pcm, ( void ** ) channels, num_samples - i ); - if( written <= 0 ) { - _snd_pcm_recover( device->pcm, written, 1 ); - } - else { - i += written; - } - } -} - -#endif diff --git a/linux_audio_output.cc b/linux_audio_output.cc @@ -0,0 +1,116 @@ +#include <stdio.h> +#include <stdarg.h> +#include <dlfcn.h> +#include <err.h> + +#include <alsa/asoundlib.h> + +#include "intrinsics.h" +#include "log.h" +#include "platform_library.h" +#include "linux_audio_output.h" + +// copied from alsa headers +static int ( *_snd_lib_error_set_handler )( snd_lib_error_handler_t handler ) = NULL; +static const char * ( *_snd_strerror )( int errnum ) = NULL; +static int ( *_snd_pcm_open )( snd_pcm_t ** pcm, const char * name, snd_pcm_stream_t stream, int mode ) = NULL; +static int ( *_snd_pcm_set_params )( snd_pcm_t * pcm, snd_pcm_format_t format, snd_pcm_access_t access, unsigned int channels, unsigned int rate, int soft_resample, unsigned int latency ) = NULL; +static snd_pcm_sframes_t ( *_snd_pcm_writen )( snd_pcm_t * pcm, void ** bufs, snd_pcm_uframes_t size ) = NULL; +static int ( *_snd_pcm_recover )( snd_pcm_t * pcm, int err, int silent ) = NULL; +static int ( *_snd_pcm_close )( snd_pcm_t * pcm ) = NULL; + +static Library alsa_lib = NULL; + +static void audio_error_handler( const char * file, int line, const char * function, int err, const char * fmt, ... ) { + printf( "error in %s at %s:%d\n", file, function, line ); + + va_list args; + va_start( args, fmt ); + vprintf( fmt, args ); + va_end( args ); + printf( "\n" ); +} + +void audio_output_init() { + alsa_lib = library_open( "libasound.so" ); + if( alsa_lib == NULL ) { + FATAL( "Couldn't open libasound.so: %s", dlerror() ); + } + + _snd_lib_error_set_handler = ( int ( * )( snd_lib_error_handler_t ) ) library_function( alsa_lib, "snd_lib_error_set_handler" ); + _snd_strerror = ( const char * ( * )( int ) ) library_function( alsa_lib, "snd_strerror" ); + _snd_pcm_open = ( int ( * ) ( snd_pcm_t **, const char *, snd_pcm_stream_t, int ) ) library_function( alsa_lib, "snd_pcm_open" ); + _snd_pcm_set_params = ( int ( * ) ( snd_pcm_t *, snd_pcm_format_t, snd_pcm_access_t, unsigned int, unsigned int, int, unsigned int ) ) library_function( alsa_lib, "snd_pcm_set_params" ); + _snd_pcm_writen = ( snd_pcm_sframes_t ( * ) ( snd_pcm_t *, void **, snd_pcm_uframes_t ) ) library_function( alsa_lib, "snd_pcm_writen" ); + _snd_pcm_recover = ( int ( * )( snd_pcm_t *, int, int ) ) library_function( alsa_lib, "snd_pcm_recover" ); + _snd_pcm_close = ( int ( * ) ( snd_pcm_t * ) ) library_function( alsa_lib, "snd_pcm_close" ); + + if( + _snd_lib_error_set_handler == NULL + || _snd_strerror == NULL + || _snd_pcm_open == NULL + || _snd_pcm_set_params == NULL + || _snd_pcm_writen == NULL + || _snd_pcm_recover == NULL + || _snd_pcm_close == NULL + ) { + FATAL( "Couldn't load ALSA functions" ); + } + + _snd_lib_error_set_handler( audio_error_handler ); +} + +void audio_output_term() { + _snd_lib_error_set_handler = NULL; + _snd_strerror = NULL; + _snd_pcm_open = NULL; + _snd_pcm_set_params = NULL; + _snd_pcm_writen = NULL; + _snd_pcm_recover = NULL; + _snd_pcm_close = NULL; + + library_close( alsa_lib ); +} + +void audio_output_open( AudioOutputDevice * device ) { + const int channels = 2; + const int sample_rate = 44100; + const int ms = 1000; + const int latency = 10 * ms; + + int err_open = _snd_pcm_open( &device->pcm, "default", SND_PCM_STREAM_PLAYBACK, 0 ); + if( err_open != 0 ) { + // TODO: maybe don't kill the program + FATAL( "Couldn't open sound output: %s", _snd_strerror( err_open ) ); + } + + int err_params = _snd_pcm_set_params( device->pcm, + SND_PCM_FORMAT_S16_LE, SND_PCM_ACCESS_RW_NONINTERLEAVED, + channels, sample_rate, 1, latency ); + if( err_params != 0 ) { + // TODO: maybe don't kill the program + FATAL( "Couldn't configure sound output: %s", _snd_strerror( err_params ) ); + } +} + +void audio_output_close( AudioOutputDevice * device ) { + int err = _snd_pcm_close( device->pcm ); + if( err != 0 ) { + // TODO: maybe don't kill the program + FATAL( "Couldn't close sound output: %s", _snd_strerror( err ) ); + } +} + +void audio_output_write( AudioOutputDevice * device, s16 * samples, size_t num_samples ) { + for( u32 i = 0; i < num_samples; ) { + s16 * channels[ 2 ] = { samples + i, samples + i }; + + snd_pcm_sframes_t written = _snd_pcm_writen( device->pcm, ( void ** ) channels, num_samples - i ); + if( written <= 0 ) { + _snd_pcm_recover( device->pcm, written, 1 ); + } + else { + i += written; + } + } +} diff --git a/linux_audio_output.h b/linux_audio_output.h @@ -0,0 +1,19 @@ +#ifndef _LINUX_AUDIO_H_ +#define _LINUX_AUDIO_H_ + +#include <alsa/asoundlib.h> + +#include "intrinsics.h" + +struct AudioOutputDevice { + snd_pcm_t * pcm; +}; + +void audio_output_init(); +void audio_output_term(); + +void audio_output_open( AudioOutputDevice * device ); +void audio_output_close( AudioOutputDevice * device ); +void audio_output_write( AudioOutputDevice * device, s16 * samples, size_t num_samples ); + +#endif // _LINUX_AUDIO_H_ diff --git a/mixer.cc b/mixer.cc @@ -1,6 +1,6 @@ #include "intrinsics.h" #include "mixer.h" -#include "platform_audio.h" +#include "platform_audio_output.h" #include "nonblocking_fixed_spsc_queue.h" struct PlayingSound { diff --git a/mixer.h b/mixer.h @@ -6,7 +6,7 @@ #include "intrinsics.h" #include "assets.h" -#include "platform_audio.h" +#include "platform_audio_output.h" typedef u64 PlayingSoundID; #define INVALID_SOUND_ID U64_MAX diff --git a/platform_audio.h b/platform_audio.h @@ -1,10 +0,0 @@ -// #ifndef _PLATFORM_AUDIO_H_ -// #define _PLATFORM_AUDIO_H_ - -#if defined( __linux__ ) -#include "linux_audio.h" -#else -#error new platform -#endif - -// #endif // _PLATFORM_AUDIO_H_ diff --git a/platform_audio_output.cc b/platform_audio_output.cc @@ -0,0 +1,7 @@ +#include "platform.h" + +#if PLATFORM_LINUX +#include "linux_audio_output.cc" +#else +#error new platform +#endif diff --git a/platform_audio_output.h b/platform_audio_output.h @@ -0,0 +1,10 @@ +// #ifndef _PLATFORM_AUDIO_H_ +// #define _PLATFORM_AUDIO_H_ + +#if defined( __linux__ ) +#include "linux_audio_output.h" +#else +#error new platform +#endif + +// #endif // _PLATFORM_AUDIO_H_