I've got audio samples; how to play them correctly with the SDL? -
i'm in process of writing simple frontend libretro cores, , i'm attacking audio part, hardest (i never ever dealt sound-related before, it's possible got totally wrong).
the way works, libretro cores regularly call function prototyped such, have implement myself:
typedef size_t (*retro_audio_sample_batch_t)(const int16_t *data, size_t count);
the data
parameter array of interlaced stereo data ({ left, right, left, ...}
), , count
number of samples (so array element count count * 2).
here these data:
- when libretro core sending me samples
- i concatenate them audio buffer
- when sdl calling audio callback method,
- i copy as requested , available audio buffer stream buffer
- if not enough data available, fill rest of stream buffer 0's
- if buffer has more data requested, remove played , keep rest
however, isn't right. despite being recognizable, sound garbled , full of noise. i'm not sure might missing : seems retroarch frontend (the official frontend libretro cores) doing sort of resampling, have no idea is. resampling required? can me issues come that?
here full code, partly reproduced below:
static int16_t * g_audio_samples = null; static size_t g_audio_sample_count = 0; static void audio_write( int16_t const * samples, size_t count ) { sdl_lockaudio( ); int16_t * previous_samples = g_audio_samples; size_t previous_count = g_audio_sample_count; g_audio_sample_count = previous_count + count; g_audio_samples = calloc( g_audio_sample_count * 2, sizeof( int16_t ) ); ( size_t index = 0; index < previous_count; ++ index ) g_audio_samples[ index ] = previous_samples[ index ]; ( size_t index = 0; index < count; ++ index ) g_audio_samples[ previous_count + index ] = samples[ index ]; free( previous_samples ); sdl_unlockaudio( ); } static void audio_callback( void * userdata, uint8 * stream, int length ) { int16_t * available_samples = g_audio_samples; size_t available_sample_count = g_audio_sample_count; size_t requested_sample_count = length / 2; size_t requested_byte_length = requested_sample_count * 2; size_t providen_sample_count = requested_sample_count < available_sample_count ? requested_sample_count : available_sample_count; size_t providen_byte_length = providen_sample_count * 2; memcpy( stream, available_samples, providen_byte_length ); memset( stream + providen_byte_length, 0, requested_byte_length - providen_byte_length ); g_audio_samples = null; g_audio_sample_count = 0; if ( providen_sample_count < available_sample_count ) audio_write( available_samples + providen_sample_count, available_sample_count - providen_sample_count ); free( available_samples ); } size_t bridge_virtjs_audio_push_sample_batch( int16_t const * samples, size_t count ) { audio_write( samples, count ); return count; }
Comments
Post a Comment