summaryrefslogtreecommitdiffstats
path: root/audio/out/ao_oss.c
diff options
context:
space:
mode:
Diffstat (limited to 'audio/out/ao_oss.c')
-rw-r--r--audio/out/ao_oss.c39
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,
},
};