diff options
Diffstat (limited to 'audio/out/ao_oss.c')
-rw-r--r-- | audio/out/ao_oss.c | 39 |
1 files changed, 15 insertions, 24 deletions
diff --git a/audio/out/ao_oss.c b/audio/out/ao_oss.c index 11b182e52d..afe5839dd5 100644 --- a/audio/out/ao_oss.c +++ b/audio/out/ao_oss.c @@ -4,7 +4,7 @@ * Original author: A'rpi * Support for >2 output channels added 2001-11-25 * - Steve Davies <steve@daviesfam.org> - * Rozhuk Ivan <rozhuk.im@gmail.com> 2020 + * Rozhuk Ivan <rozhuk.im@gmail.com> 2020-2023 * * This file is part of mpv. * @@ -35,8 +35,8 @@ #endif #include <sys/types.h> -#include "config.h" #include "audio/format.h" +#include "common/common.h" #include "common/msg.h" #include "options/options.h" #include "osdep/endian.h" @@ -49,10 +49,10 @@ #endif #define PATH_DEV_DSP "/dev/dsp" +#define PATH_DEV_MIXER "/dev/mixer" struct priv { int dsp_fd; - bool playing; double bps; /* Bytes per second. */ }; @@ -90,7 +90,7 @@ static const int format_table[][2] = { #define MP_WARN_IOCTL_ERR(__ao) \ MP_WARN((__ao), "%s: ioctl() fail, err = %i: %s\n", \ - __FUNCTION__, errno, strerror(errno)) + __FUNCTION__, errno, mp_strerror(errno)) static void uninit(struct ao *ao); @@ -115,7 +115,7 @@ static void device_descr_get(size_t dev_idx, char *buf, size_t buf_size) snprintf(dev_path, sizeof(dev_path), PATH_DEV_MIXER"%zu", dev_idx); int fd = open(dev_path, O_RDONLY); if (ioctl(fd, SOUND_MIXER_INFO, &mi) == 0) { - strncpy(buf, mi.name, buf_size); + strncpy(buf, mi.name, buf_size - 1); tmp = (buf_size - 1); } close(fd); @@ -187,11 +187,11 @@ static int init(struct ao *ao) /* Channels count. */ if (af_fmt_is_spdif(format)) { - /* Probably could be fixed by setting number of channels; - * needs testing. */ - if (channels.num != 2) { - MP_ERR(ao, "Format %s not implemented.\n", af_fmt_to_str(format)); - goto err_out; + nchannels = reqchannels = channels.num; + if (ioctl(p->dsp_fd, SNDCTL_DSP_CHANNELS, &nchannels) == -1) { + MP_ERR(ao, "Failed to set audio device to %d channels.\n", + reqchannels); + goto err_out_ioctl; } } else { struct mp_chmap_sel sel = {0}; @@ -240,7 +240,6 @@ static int init(struct ao *ao) ao->samplerate = samplerate; ao->channels = channels; p->bps = (channels.num * samplerate * af_fmt_to_bytes(format)); - p->playing = false; return 0; @@ -260,13 +259,12 @@ static void uninit(struct ao *ao) ioctl(p->dsp_fd, SNDCTL_DSP_HALT, NULL); close(p->dsp_fd); p->dsp_fd = -1; - p->playing = false; } static int control(struct ao *ao, enum aocontrol cmd, void *arg) { struct priv *p = ao->priv; - ao_control_vol_t *vol = (ao_control_vol_t *)arg; + float *vol = arg; int v; if (p->dsp_fd < 0) @@ -278,11 +276,10 @@ static int control(struct ao *ao, enum aocontrol cmd, void *arg) MP_WARN_IOCTL_ERR(ao); return CONTROL_ERROR; } - vol->right = ((v & 0xff00) >> 8); - vol->left = (v & 0x00ff); + *vol = ((v & 0x00ff) + ((v & 0xff00) >> 8)) / 2.0; return CONTROL_OK; case AOCONTROL_SET_VOLUME: - v = ((int)vol->right << 8) | (int)vol->left; + v = ((int)*vol << 8) | (int)*vol; if (ioctl(p->dsp_fd, SNDCTL_DSP_SETPLAYVOL, &v) == -1) { MP_WARN_IOCTL_ERR(ao); return CONTROL_ERROR; @@ -299,7 +296,6 @@ static void reset(struct ao *ao) int trig = 0; /* Clear buf and do not start playback after data written. */ - p->playing = false; if (ioctl(p->dsp_fd, SNDCTL_DSP_HALT, NULL) == -1 || ioctl(p->dsp_fd, SNDCTL_DSP_SETTRIGGER, &trig) == -1) { @@ -319,7 +315,6 @@ static void start(struct ao *ao) MP_WARN_IOCTL_ERR(ao); return; } - p->playing = true; } static bool audio_write(struct ao *ao, void **data, int samples) @@ -335,14 +330,12 @@ static bool audio_write(struct ao *ao, void **data, int samples) if (errno == EINTR) continue; MP_WARN(ao, "audio_write: write() fail, err = %i: %s.\n", - errno, strerror(errno)); - p->playing = false; + errno, mp_strerror(errno)); return false; } if ((size_t)rc != size) { MP_WARN(ao, "audio_write: unexpected partial write: required: %zu, written: %zu.\n", size, (size_t)rc); - p->playing = false; return false; } @@ -359,7 +352,6 @@ static void get_state(struct ao *ao, struct mp_pcm_state *state) ioctl(p->dsp_fd, SNDCTL_DSP_GETODELAY, &odelay) == -1) { MP_WARN_IOCTL_ERR(ao); - p->playing = false; memset(state, 0x00, sizeof(struct mp_pcm_state)); state->delay = 0.0; return; @@ -367,7 +359,7 @@ static void get_state(struct ao *ao, struct mp_pcm_state *state) state->free_samples = (info.bytes / ao->sstride); state->queued_samples = (ao->device_buffer - state->free_samples); state->delay = (odelay / p->bps); - state->playing = p->playing; + state->playing = (state->queued_samples != 0); } static void list_devs(struct ao *ao, struct ao_device_list *list) @@ -405,6 +397,5 @@ const struct ao_driver audio_out_oss = { .priv_size = sizeof(struct priv), .priv_defaults = &(const struct priv) { .dsp_fd = -1, - .playing = false, }, }; |