diff options
author | neonloop | 2021-03-12 16:11:08 +0000 |
---|---|---|
committer | neonloop | 2021-03-12 16:11:08 +0000 |
commit | e117e43bd06627f7fadb2c58adf07e058f100579 (patch) | |
tree | 5ee6bc026b2c6790f4cf5df1f166f3da8c4831d7 /shell/audio/sdl | |
parent | 6d4c2c9b14b626df0fa71cb1869770d2923a470d (diff) | |
download | snes9x2002-e117e43bd06627f7fadb2c58adf07e058f100579.tar.gz snes9x2002-e117e43bd06627f7fadb2c58adf07e058f100579.tar.bz2 snes9x2002-e117e43bd06627f7fadb2c58adf07e058f100579.zip |
Initial trimui s support
Diffstat (limited to 'shell/audio/sdl')
-rw-r--r-- | shell/audio/sdl/sound_output.c | 119 |
1 files changed, 119 insertions, 0 deletions
diff --git a/shell/audio/sdl/sound_output.c b/shell/audio/sdl/sound_output.c new file mode 100644 index 0000000..0758718 --- /dev/null +++ b/shell/audio/sdl/sound_output.c @@ -0,0 +1,119 @@ +#include <sys/ioctl.h> +#include <stdint.h> +#include <stdbool.h> +#include <fcntl.h> +#include <unistd.h> +#include <SDL/SDL.h> + +#include "sound_output.h" + +#define UNDERRUN_THRESHOLD 0.5 + +static int32_t BUFFSIZE; +static uint8_t *buffer; +static uint32_t buf_read_pos = 0; +static uint32_t buf_write_pos = 0; +static int32_t buffered_bytes = 0; + +static int32_t sdl_read_buffer(uint8_t* data, int32_t len) +{ + if (buffered_bytes >= len) + { + if(buf_read_pos + len <= BUFFSIZE ) + { + memcpy(data, buffer + buf_read_pos, len); + } + else + { + int32_t tail = BUFFSIZE - buf_read_pos; + memcpy(data, buffer + buf_read_pos, tail); + memcpy(data + tail, buffer, len - tail); + } + buf_read_pos = (buf_read_pos + len) % BUFFSIZE; + buffered_bytes -= len; + } + + return len; +} + + +static void sdl_write_buffer(uint8_t* data, int32_t len) +{ + SDL_LockAudio(); + for(uint32_t i = 0; i < len; i += 4) + { + while (buffered_bytes == BUFFSIZE) { + SDL_UnlockAudio(); + usleep(1000); + SDL_LockAudio(); + } + *(int32_t*)((char*)(buffer + buf_write_pos)) = *(int32_t*)((char*)(data + i)); + //memcpy(buffer + buf_write_pos, data + i, 4); + buf_write_pos = (buf_write_pos + 4) % BUFFSIZE; + buffered_bytes += 4; + } + SDL_UnlockAudio(); +} + +void sdl_callback(void *unused, uint8_t *stream, int32_t len) +{ + sdl_read_buffer((uint8_t *)stream, len); +} +uint32_t Audio_Init() +{ + SDL_AudioSpec aspec, obtained; + + BUFFSIZE = (SOUND_SAMPLES_SIZE * 2 * 2) * 4; + buffer = (uint8_t *) malloc(BUFFSIZE); + + /* Add some silence to the buffer */ + buffered_bytes = 0; + buf_read_pos = 0; + buf_write_pos = 0; + + aspec.format = AUDIO_S16SYS; + aspec.freq = SOUND_OUTPUT_FREQUENCY; + aspec.channels = 2; + aspec.samples = SOUND_SAMPLES_SIZE; + aspec.callback = (sdl_callback); + aspec.userdata = NULL; + + /* initialize the SDL Audio system */ + if (SDL_InitSubSystem (SDL_INIT_AUDIO | SDL_INIT_NOPARACHUTE)) + { + printf("SDL: Initializing of SDL Audio failed: %s.\n", SDL_GetError()); + return 1; + } + + /* Open the audio device and start playing sound! */ + if(SDL_OpenAudio(&aspec, &obtained) < 0) + { + printf("SDL: Unable to open audio: %s\n", SDL_GetError()); + return 1; + } + + SDL_PauseAudio(0); + + return 0; +} + +void Audio_Write(int16_t* restrict buffer, uint32_t buffer_size) +{ + sdl_write_buffer(buffer, buffer_size * 4); +} + +bool Audio_Underrun_Likely() { + bool underrun_likely = false; + SDL_LockAudio(); + underrun_likely = buffered_bytes < BUFFSIZE * UNDERRUN_THRESHOLD; + SDL_UnlockAudio(); + return underrun_likely; +} + +void Audio_Close() +{ + SDL_PauseAudio(1); + SDL_CloseAudio(); + SDL_QuitSubSystem(SDL_INIT_AUDIO); + buffer = NULL; +} |