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/alsa | |
parent | 6d4c2c9b14b626df0fa71cb1869770d2923a470d (diff) | |
download | snes9x2002-e117e43bd06627f7fadb2c58adf07e058f100579.tar.gz snes9x2002-e117e43bd06627f7fadb2c58adf07e058f100579.tar.bz2 snes9x2002-e117e43bd06627f7fadb2c58adf07e058f100579.zip |
Initial trimui s support
Diffstat (limited to 'shell/audio/alsa')
-rw-r--r-- | shell/audio/alsa/sound_output.c | 146 |
1 files changed, 146 insertions, 0 deletions
diff --git a/shell/audio/alsa/sound_output.c b/shell/audio/alsa/sound_output.c new file mode 100644 index 0000000..4da70a7 --- /dev/null +++ b/shell/audio/alsa/sound_output.c @@ -0,0 +1,146 @@ +#include <sys/ioctl.h> +#include <stdint.h> +#include <fcntl.h> +#include <unistd.h> +#include <alsa/asoundlib.h> + +#include "sound_output.h" + +static snd_pcm_t *handle; + +uint32_t Audio_Init() +{ + snd_pcm_hw_params_t *params; + uint32_t val; + int32_t dir = -1; + snd_pcm_uframes_t frames; + + /* Open PCM device for playback. */ + int32_t rc = snd_pcm_open(&handle, "default", SND_PCM_STREAM_PLAYBACK, 0); + + if (rc < 0) + rc = snd_pcm_open(&handle, "plughw:0,0,0", SND_PCM_STREAM_PLAYBACK, 0); + + if (rc < 0) + rc = snd_pcm_open(&handle, "plughw:0,0", SND_PCM_STREAM_PLAYBACK, 0); + + if (rc < 0) + rc = snd_pcm_open(&handle, "plughw:1,0,0", SND_PCM_STREAM_PLAYBACK, 0); + + if (rc < 0) + rc = snd_pcm_open(&handle, "plughw:1,0", SND_PCM_STREAM_PLAYBACK, 0); + + if (rc < 0) + { + fprintf(stderr, "unable to open PCM device: %s\n", snd_strerror(rc)); + return 1; + } + + /* Allocate a hardware parameters object. */ + snd_pcm_hw_params_alloca(¶ms); + + /* Fill it in with default values. */ + rc = snd_pcm_hw_params_any(handle, params); + if (rc < 0) + { + fprintf(stderr, "Error:snd_pcm_hw_params_any %s\n", snd_strerror(rc)); + return 1; + } + + /* Set the desired hardware parameters. */ + + /* Interleaved mode */ + rc = snd_pcm_hw_params_set_access(handle, params, SND_PCM_ACCESS_RW_INTERLEAVED); + if (rc < 0) + { + fprintf(stderr, "Error:snd_pcm_hw_params_set_access %s\n", snd_strerror(rc)); + return 1; + } + + /* Signed 16-bit little-endian format */ + rc = snd_pcm_hw_params_set_format(handle, params, SND_PCM_FORMAT_S16_LE); + if (rc < 0) + { + fprintf(stderr, "Error:snd_pcm_hw_params_set_format %s\n", snd_strerror(rc)); + return 1; + } + + /* Two channels (stereo) */ + rc = snd_pcm_hw_params_set_channels(handle, params, 2); + if (rc < 0) + { + fprintf(stderr, "Error:snd_pcm_hw_params_set_channels %s\n", snd_strerror(rc)); + return 1; + } + + val = SOUND_OUTPUT_FREQUENCY; + rc = snd_pcm_hw_params_set_rate_near(handle, params, &val, &dir); + if (rc < 0) + { + fprintf(stderr, "Error:snd_pcm_hw_params_set_rate_near %s\n", snd_strerror(rc)); + return 1; + } + + /* Set period size to settings.aica.BufferSize frames. */ + frames = SOUND_SAMPLES_SIZE; + rc = snd_pcm_hw_params_set_period_size_near(handle, params, &frames, &dir); + if (rc < 0) + { + fprintf(stderr, "Error:snd_pcm_hw_params_set_buffer_size_near %s\n", snd_strerror(rc)); + return 1; + } + frames *= 4; + rc = snd_pcm_hw_params_set_buffer_size_near(handle, params, &frames); + if (rc < 0) + { + fprintf(stderr, "Error:snd_pcm_hw_params_set_buffer_size_near %s\n", snd_strerror(rc)); + return 1; + } + + /* Write the parameters to the driver */ + rc = snd_pcm_hw_params(handle, params); + if (rc < 0) + { + fprintf(stderr, "Unable to set hw parameters: %s\n", snd_strerror(rc)); + return 1; + } + + return 0; +} + +void Audio_Write(int16_t* restrict buffer, uint32_t buffer_size) +{ + uint32_t i; + long ret, len; + + if (!handle) return; + + len = buffer_size; + + ret = snd_pcm_writei(handle, buffer, len); + while(ret != len) + { + if (ret < 0) + { + snd_pcm_prepare( handle ); + } + else + { + len -= ret; + } + ret = snd_pcm_writei(handle, buffer, len); + } +} + +bool Audio_Underrun_Likely() { + return false; +} + +void Audio_Close() +{ + if (handle) + { + snd_pcm_drain(handle); + snd_pcm_close(handle); + } +} |