summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorwm4 <wm4@nowhere>2013-11-10 23:24:21 +0100
committerwm4 <wm4@nowhere>2013-11-12 23:27:51 +0100
commit380fc765e4ad4e3ff828c9b0bd4a565ea2ba79ed (patch)
tree6cc32f550b219c903a932692f477c8b8b4f8cfc2
parentd115fb3b0eed9145817a20bc0070590f7428bddd (diff)
downloadmpv-380fc765e4ad4e3ff828c9b0bd4a565ea2ba79ed.tar.bz2
mpv-380fc765e4ad4e3ff828c9b0bd4a565ea2ba79ed.tar.xz
audio/out: prepare for non-interleaved audio
This comes with two internal AO API changes: 1. ao_driver.play now can take non-interleaved audio. For this purpose, the data pointer is changed to void **data, where data[0] corresponds to the pointer in the old API. Also, the len argument as well as the return value are now in samples, not bytes. "Sample" in this context means the unit of the smallest possible audio frame, i.e. sample_size * channels. 2. ao_driver.get_space now returns samples instead of bytes. (Similar to the play function.) Change all AOs to use the new API. The AO API as exposed to the rest of the player still uses the old API. It's emulated in ao.c. This is purely to split the commits changing all AOs and the commits adding actual support for outputting N-I audio.
-rw-r--r--audio/out/ao.c17
-rw-r--r--audio/out/ao.h4
-rw-r--r--audio/out/ao_alsa.c16
-rw-r--r--audio/out/ao_coreaudio.c8
-rw-r--r--audio/out/ao_dsound.c7
-rw-r--r--audio/out/ao_jack.c7
-rw-r--r--audio/out/ao_lavc.c23
-rw-r--r--audio/out/ao_null.c7
-rw-r--r--audio/out/ao_openal.c9
-rw-r--r--audio/out/ao_oss.c16
-rw-r--r--audio/out/ao_pcm.c7
-rw-r--r--audio/out/ao_portaudio.c8
-rw-r--r--audio/out/ao_pulse.c12
-rw-r--r--audio/out/ao_rsound.c6
-rw-r--r--audio/out/ao_sdl.c9
-rw-r--r--audio/out/ao_sndio.c8
-rw-r--r--audio/out/ao_wasapi.c13
17 files changed, 92 insertions, 85 deletions
diff --git a/audio/out/ao.c b/audio/out/ao.c
index 55db34becb..fd20270160 100644
--- a/audio/out/ao.c
+++ b/audio/out/ao.c
@@ -159,7 +159,10 @@ static struct ao *ao_create(bool probing, struct mpv_global *global,
talloc_free(chmap);
if (ao->driver->init(ao) < 0)
goto error;
- ao->bps = ao->channels.num * ao->samplerate * af_fmt2bits(ao->format) / 8;
+ ao->sstride = af_fmt2bits(ao->format) / 8;
+ if (!af_fmt_is_planar(ao->format))
+ ao->sstride *= ao->channels.num;
+ ao->bps = ao->samplerate * ao->sstride;
return ao;
error:
talloc_free(ao);
@@ -208,7 +211,8 @@ void ao_uninit(struct ao *ao, bool cut_audio)
int ao_play(struct ao *ao, void *data, int len, int flags)
{
- return ao->driver->play(ao, data, len, flags);
+ int r = ao->driver->play(ao, &data, len / ao->sstride, flags);
+ return r < 0 ? r : r * ao->sstride;
}
int ao_control(struct ao *ao, enum aocontrol cmd, void *arg)
@@ -229,7 +233,7 @@ double ao_get_delay(struct ao *ao)
int ao_get_space(struct ao *ao)
{
- return ao->driver->get_space(ao);
+ return ao->driver->get_space(ao) * ao->sstride;
}
void ao_reset(struct ao *ao)
@@ -254,10 +258,9 @@ int ao_play_silence(struct ao *ao, int samples)
{
if (samples <= 0 || AF_FORMAT_IS_SPECIAL(ao->format))
return 0;
- int s = ao->channels.num * (af_fmt2bits(ao->format) / 8);
- char *p = talloc_size(NULL, samples * s);
- af_fill_silence(p, samples * s, ao->format);
- int r = ao_play(ao, p, samples * s, 0);
+ char *p = talloc_size(NULL, samples * ao->sstride);
+ af_fill_silence(p, samples * ao->sstride, ao->format);
+ int r = ao_play(ao, p, samples * ao->sstride, 0);
talloc_free(p);
return r;
}
diff --git a/audio/out/ao.h b/audio/out/ao.h
index 159a6adc0f..eb1af990ff 100644
--- a/audio/out/ao.h
+++ b/audio/out/ao.h
@@ -56,7 +56,7 @@ struct ao_driver {
void (*uninit)(struct ao *ao, bool cut_audio);
void (*reset)(struct ao*ao);
int (*get_space)(struct ao *ao);
- int (*play)(struct ao *ao, void *data, int len, int flags);
+ int (*play)(struct ao *ao, void **data, int samples, int flags);
float (*get_delay)(struct ao *ao);
void (*pause)(struct ao *ao);
void (*resume)(struct ao *ao);
@@ -73,6 +73,8 @@ struct ao {
struct mp_chmap channels;
int format;
int bps; // bytes per second
+ int sstride; // size of a sample on each plane
+ // (format_size*num_channels/num_planes)
double pts; // some mplayer.c state (why is this here?)
struct bstr buffer;
int buffer_playable_size; // part of the part of the buffer the AO hasn't
diff --git a/audio/out/ao_alsa.c b/audio/out/ao_alsa.c
index 0d1c589e34..97c8b5acfd 100644
--- a/audio/out/ao_alsa.c
+++ b/audio/out/ao_alsa.c
@@ -636,18 +636,12 @@ static void reset(struct ao *ao)
alsa_error: ;
}
-/*
- plays 'len' bytes of 'data'
- returns: number of bytes played
- modified last at 29.06.02 by jp
- thanxs for marius <marius@rospot.com> for giving us the light ;)
- */
-
-static int play(struct ao *ao, void *data, int len, int flags)
+static int play(struct ao *ao, void **data, int samples, int flags)
{
struct priv *p = ao->priv;
int num_frames;
snd_pcm_sframes_t res = 0;
+ int len = samples * p->bytes_per_sample;
if (!(flags & AOPLAY_FINAL_CHUNK))
len = len / p->outburst * p->outburst;
num_frames = len / p->bytes_per_sample;
@@ -661,7 +655,7 @@ static int play(struct ao *ao, void *data, int len, int flags)
return 0;
do {
- res = snd_pcm_writei(p->alsa, data, num_frames);
+ res = snd_pcm_writei(p->alsa, data[0], num_frames);
if (res == -EINTR) {
/* nothing to do */
@@ -680,7 +674,7 @@ static int play(struct ao *ao, void *data, int len, int flags)
}
} while (res == 0);
- return res < 0 ? -1 : res * p->bytes_per_sample;
+ return res < 0 ? -1 : res;
alsa_error:
return -1;
@@ -701,7 +695,7 @@ static int get_space(struct ao *ao)
unsigned space = snd_pcm_status_get_avail(status) * p->bytes_per_sample;
if (space > p->buffersize) // Buffer underrun?
space = p->buffersize;
- return space;
+ return space / p->bytes_per_sample;
alsa_error:
return 0;
diff --git a/audio/out/ao_coreaudio.c b/audio/out/ao_coreaudio.c
index 4823eb43e1..d61ce63d01 100644
--- a/audio/out/ao_coreaudio.c
+++ b/audio/out/ao_coreaudio.c
@@ -578,10 +578,12 @@ coreaudio_error:
return CONTROL_ERROR;
}
-static int play(struct ao *ao, void *output_samples, int num_bytes, int flags)
+static int play(struct ao *ao, void **data, int samples, int flags)
{
struct priv *p = ao->priv;
struct priv_d *d = p->digital;
+ void *output_samples = data[0];
+ int num_bytes = samples * ao->sstride;
// Check whether we need to reset the digital output stream.
if (p->is_digital && d->stream_asbd_changed) {
@@ -599,7 +601,7 @@ static int play(struct ao *ao, void *output_samples, int num_bytes, int flags)
int wrote = mp_ring_write(p->buffer, output_samples, num_bytes);
audio_resume(ao);
- return wrote;
+ return wrote / ao->sstride;
}
static void reset(struct ao *ao)
@@ -612,7 +614,7 @@ static void reset(struct ao *ao)
static int get_space(struct ao *ao)
{
struct priv *p = ao->priv;
- return mp_ring_available(p->buffer);
+ return mp_ring_available(p->buffer) / ao->sstride;
}
static float get_delay(struct ao *ao)
diff --git a/audio/out/ao_dsound.c b/audio/out/ao_dsound.c
index 58812d80e6..f828a210dc 100644
--- a/audio/out/ao_dsound.c
+++ b/audio/out/ao_dsound.c
@@ -596,7 +596,7 @@ static int get_space(struct ao *ao)
int space = check_free_buffer_size(ao);
if (space < p->min_free_space)
return 0;
- return space - p->min_free_space;
+ return (space - p->min_free_space) / ao->sstride;
}
/**
@@ -606,9 +606,10 @@ static int get_space(struct ao *ao)
\param flags currently unused
\return number of played bytes
*/
-static int play(struct ao *ao, void *data, int len, int flags)
+static int play(struct ao *ao, void **data, int samples, int flags)
{
struct priv *p = ao->priv;
+ int len = samples * ao->sstride;
int space = check_free_buffer_size(ao);
if (space < len)
@@ -616,7 +617,7 @@ static int play(struct ao *ao, void *data, int len, int flags)
if (!(flags & AOPLAY_FINAL_CHUNK))
len = (len / p->outburst) * p->outburst;
- return write_buffer(ao, data, len);
+ return write_buffer(ao, data[0], len) / ao->sstride;
}
/**
diff --git a/audio/out/ao_jack.c b/audio/out/ao_jack.c
index 20dd0d4aab..f69c6c928d 100644
--- a/audio/out/ao_jack.c
+++ b/audio/out/ao_jack.c
@@ -319,19 +319,20 @@ static void audio_resume(struct ao *ao)
static int get_space(struct ao *ao)
{
struct priv *p = ao->priv;
- return mp_ring_available(p->ring);
+ return mp_ring_available(p->ring) / ao->sstride;
}
/**
* \brief write data into buffer and reset underrun flag
*/
-static int play(struct ao *ao, void *data, int len, int flags)
+static int play(struct ao *ao, void **data, int samples, int flags)
{
struct priv *p = ao->priv;
+ int len = samples * ao->sstride;
if (!(flags & AOPLAY_FINAL_CHUNK))
len -= len % p->outburst;
p->underrun = 0;
- return mp_ring_write(p->ring, data, len);
+ return mp_ring_write(p->ring, data[0], len) / ao->sstride;
}
#define OPT_BASE_STRUCT struct priv
diff --git a/audio/out/ao_lavc.c b/audio/out/ao_lavc.c
index b849f9b2b4..9be3a7b6ae 100644
--- a/audio/out/ao_lavc.c
+++ b/audio/out/ao_lavc.c
@@ -296,8 +296,6 @@ static void fill_with_padding(void *buf, int cnt, int sz, const void *padding)
}
// close audio device
-static int encode(struct ao *ao, double apts, void *data);
-static int play(struct ao *ao, void *data, int len, int flags);
static void uninit(struct ao *ao, bool cut_audio)
{
struct encode_lavc_context *ectx = ao->encode_lavc_ctx;
@@ -315,7 +313,7 @@ static int get_space(struct ao *ao)
{
struct priv *ac = ao->priv;
- return ac->aframesize * ac->sample_size * ao->channels.num * ac->framecount;
+ return ac->aframesize * ac->framecount;
}
// must get exactly ac->aframesize amount of data
@@ -444,10 +442,10 @@ static int encode(struct ao *ao, double apts, void *data)
return packet.size;
}
-// plays 'len' bytes of 'data'
+// plays 'samples' samples of 'ni_data[0]'
// it should round it down to frame sizes
-// return: number of bytes played
-static int play(struct ao *ao, void *data, int len, int flags)
+// return: number of samples played
+static int play(struct ao *ao, void **ni_data, int samples, int flags)
{
struct priv *ac = ao->priv;
struct encode_lavc_context *ectx = ao->encode_lavc_ctx;
@@ -457,6 +455,8 @@ static int play(struct ao *ao, void *data, int len, int flags)
double nextpts;
double pts = ao->pts;
double outpts;
+ void *data = ni_data[0];
+ int len = samples * ao->sstride;
int bytelen = len;
len /= ac->sample_size * ao->channels.num;
@@ -477,8 +477,9 @@ static int play(struct ao *ao, void *data, int len, int flags)
extralen / ac->sample_size,
ac->sample_size, ac->sample_padding);
// No danger of recursion, because AOPLAY_FINAL_CHUNK not set
- written = play(ao, paddingbuf, bytelen + extralen, 0);
- if (written < bytelen) {
+ written =
+ play(ao, &paddingbuf, (bytelen + extralen) / ao->sstride, 0);
+ if (written * ao->sstride < bytelen) {
MP_ERR(ao, "did not write enough data at the end\n");
}
talloc_free(paddingbuf);
@@ -492,7 +493,7 @@ static int play(struct ao *ao, void *data, int len, int flags)
while (encode(ao, outpts, NULL) > 0) ;
- return FFMIN(written, bytelen);
+ return (FFMIN(written, bytelen)) / ao->sstride;
}
if (pts == MP_NOPTS_VALUE) {
@@ -559,7 +560,7 @@ static int play(struct ao *ao, void *data, int len, int flags)
if (ac->offset_left <= -len) {
// skip whole frame
ac->offset_left += len;
- return len * ac->sample_size * ao->channels.num;
+ return len;
} else {
// skip part of this frame, buffer/encode the rest
bufpos -= ac->offset_left;
@@ -632,7 +633,7 @@ static int play(struct ao *ao, void *data, int len, int flags)
ectx->next_in_pts = nextpts;
}
- return bufpos * ac->sample_size * ao->channels.num;
+ return bufpos;
}
const struct ao_driver audio_out_lavc = {
diff --git a/audio/out/ao_null.c b/audio/out/ao_null.c
index 75e812b238..7470d9a824 100644
--- a/audio/out/ao_null.c
+++ b/audio/out/ao_null.c
@@ -96,18 +96,19 @@ static int get_space(struct ao *ao)
struct priv *priv = ao->priv;
drain(ao);
- return priv->buffersize - priv->buffered_bytes;
+ return (priv->buffersize - priv->buffered_bytes) / ao->sstride;
}
-static int play(struct ao *ao, void *data, int len, int flags)
+static int play(struct ao *ao, void **data, int samples, int flags)
{
struct priv *priv = ao->priv;
+ int len = samples * ao->sstride;
int maxbursts = (priv->buffersize - priv->buffered_bytes) / priv->outburst;
int playbursts = len / priv->outburst;
int bursts = playbursts > maxbursts ? maxbursts : playbursts;
priv->buffered_bytes += bursts * priv->outburst;
- return bursts * priv->outburst;
+ return (bursts * priv->outburst) / ao->sstride;
}
static float get_delay(struct ao *ao)
diff --git a/audio/out/ao_openal.c b/audio/out/ao_openal.c
index 6fdc388711..256e50f281 100644
--- a/audio/out/ao_openal.c
+++ b/audio/out/ao_openal.c
@@ -251,18 +251,19 @@ static int get_space(struct ao *ao)
queued = NUM_BUF - queued - 3;
if (queued < 0)
return 0;
- return queued * CHUNK_SIZE * ao->channels.num;
+ return (queued * CHUNK_SIZE * ao->channels.num) / ao->sstride;
}
/**
* \brief write data into buffer and reset underrun flag
*/
-static int play(struct ao *ao, void *data, int len, int flags)
+static int play(struct ao *ao, void **data, int samples, int flags)
{
ALint state;
int i, j, k;
int ch;
- int16_t *d = data;
+ int16_t *d = data[0];
+ int len = samples * ao->sstride;
len /= ao->channels.num * CHUNK_SIZE;
for (i = 0; i < len; i++) {
for (ch = 0; ch < ao->channels.num; ch++) {
@@ -278,7 +279,7 @@ static int play(struct ao *ao, void *data, int len, int flags)
alGetSourcei(sources[0], AL_SOURCE_STATE, &state);
if (state != AL_PLAYING) // checked here in case of an underrun
alSourcePlayv(ao->channels.num, sources);
- return len * ao->channels.num * CHUNK_SIZE;
+ return len * ao->channels.num * CHUNK_SIZE / ao->sstride;
}
static float get_delay(struct ao *ao)
diff --git a/audio/out/ao_oss.c b/audio/out/ao_oss.c
index a97424c1cb..09a2951629 100644
--- a/audio/out/ao_oss.c
+++ b/audio/out/ao_oss.c
@@ -457,7 +457,7 @@ static int get_space(struct ao *ao)
if (ioctl(p->audio_fd, SNDCTL_DSP_GETOSPACE, &p->zz) != -1) {
// calculate exact buffer space:
playsize = p->zz.fragments * p->zz.fragsize;
- return playsize;
+ return playsize / ao->sstride;
}
#endif
@@ -475,14 +475,14 @@ static int get_space(struct ao *ao)
}
#endif
- return p->outburst;
+ return p->outburst / ao->sstride;
}
// stop playing, keep buffers (for pause)
static void audio_pause(struct ao *ao)
{
struct priv *p = ao->priv;
- p->prepause_space = get_space(ao);
+ p->prepause_space = get_space(ao) * ao->sstride;
#ifdef SNDCTL_DSP_RESET
ioctl(p->audio_fd, SNDCTL_DSP_RESET, NULL);
#else
@@ -493,17 +493,18 @@ static void audio_pause(struct ao *ao)
// plays 'len' bytes of 'data'
// it should round it down to outburst*n
// return: number of bytes played
-static int play(struct ao *ao, void *data, int len, int flags)
+static int play(struct ao *ao, void **data, int samples, int flags)
{
struct priv *p = ao->priv;
+ int len = samples * ao->sstride;
if (len == 0)
return len;
if (len > p->outburst || !(flags & AOPLAY_FINAL_CHUNK)) {
len /= p->outburst;
len *= p->outburst;
}
- len = write(p->audio_fd, data, len);
- return len;
+ len = write(p->audio_fd, data[0], len);
+ return len / ao->sstride;
}
// resume playing, after audio_pause()
@@ -513,8 +514,7 @@ static void audio_resume(struct ao *ao)
#ifndef SNDCTL_DSP_RESET
reset(ao);
#endif
- int fillframes = (get_space(ao) - p->prepause_space) /
- (af_fmt2bits(ao->format) / 8 * ao->channels.num);
+ int fillframes = get_space(ao) - p->prepause_space / ao->sstride;
if (fillframes > 0)
ao_play_silence(ao, fillframes);
}
diff --git a/audio/out/ao_pcm.c b/audio/out/ao_pcm.c
index e94e6b569a..1d88fc6665 100644
--- a/audio/out/ao_pcm.c
+++ b/audio/out/ao_pcm.c
@@ -196,13 +196,14 @@ static int get_space(struct ao *ao)
return 65536;
}
-static int play(struct ao *ao, void *data, int len, int flags)
+static int play(struct ao *ao, void **data, int samples, int flags)
{
struct priv *priv = ao->priv;
+ int len = samples * ao->sstride;
- fwrite(data, len, 1, priv->fp);
+ fwrite(data[0], len, 1, priv->fp);
priv->data_length += len;
- return len;
+ return len / ao->sstride;
}
#define OPT_BASE_STRUCT struct priv
diff --git a/audio/out/ao_portaudio.c b/audio/out/ao_portaudio.c
index d75fad0aca..9c0d7804f8 100644
--- a/audio/out/ao_portaudio.c
+++ b/audio/out/ao_portaudio.c
@@ -280,13 +280,13 @@ error_exit:
return -1;
}
-static int play(struct ao *ao, void *data, int len, int flags)
+static int play(struct ao *ao, void **data, int samples, int flags)
{
struct priv *priv = ao->priv;
pthread_mutex_lock(&priv->ring_mutex);
- int write_len = mp_ring_write(priv->ring, data, len);
+ int write_len = mp_ring_write(priv->ring, data[0], samples * ao->sstride);
if (flags & AOPLAY_FINAL_CHUNK)
priv->play_remaining = true;
@@ -295,7 +295,7 @@ static int play(struct ao *ao, void *data, int len, int flags)
if (Pa_IsStreamStopped(priv->stream) == 1)
check_pa_ret(Pa_StartStream(priv->stream));
- return write_len;
+ return write_len / ao->sstride;
}
static int get_space(struct ao *ao)
@@ -308,7 +308,7 @@ static int get_space(struct ao *ao)
pthread_mutex_unlock(&priv->ring_mutex);
- return free;
+ return free / ao->sstride;
}
static float get_delay(struct ao *ao)
diff --git a/audio/out/ao_pulse.c b/audio/out/ao_pulse.c
index 1d7fcdd382..f1800f279c 100644
--- a/audio/out/ao_pulse.c
+++ b/audio/out/ao_pulse.c
@@ -377,14 +377,14 @@ static void cork(struct ao *ao, bool pause)
}
// Play the specified data to the pulseaudio server
-static int play(struct ao *ao, void *data, int len, int flags)
+static int play(struct ao *ao, void **data, int samples, int flags)
{
struct priv *priv = ao->priv;
pa_threaded_mainloop_lock(priv->mainloop);
- if (pa_stream_write(priv->stream, data, len, NULL, 0,
+ if (pa_stream_write(priv->stream, data[0], samples * ao->sstride, NULL, 0,
PA_SEEK_RELATIVE) < 0) {
GENERIC_ERR_MSG("pa_stream_write() failed");
- len = -1;
+ samples = -1;
}
if (flags & AOPLAY_FINAL_CHUNK) {
// Force start in case the stream was too short for prebuf
@@ -392,7 +392,7 @@ static int play(struct ao *ao, void *data, int len, int flags)
pa_operation_unref(op);
}
pa_threaded_mainloop_unlock(priv->mainloop);
- return len;
+ return samples;
}
// Reset the audio stream, i.e. flush the playback buffer on the server side
@@ -427,14 +427,14 @@ static void resume(struct ao *ao)
cork(ao, false);
}
-// Return number of bytes that may be written to the server without blocking
+// Return number of samples that may be written to the server without blocking
static int get_space(struct ao *ao)
{
struct priv *priv = ao->priv;
pa_threaded_mainloop_lock(priv->mainloop);
size_t space = pa_stream_writable_size(priv->stream);
pa_threaded_mainloop_unlock(priv->mainloop);
- return space;
+ return space / ao->sstride;
}
// Return the current latency in seconds
diff --git a/audio/out/ao_rsound.c b/audio/out/ao_rsound.c
index 95fadf7188..123ee14ef5 100644
--- a/audio/out/ao_rsound.c
+++ b/audio/out/ao_rsound.c
@@ -163,13 +163,13 @@ static void audio_resume(struct ao *ao)
static int get_space(struct ao *ao)
{
struct priv *priv = ao->priv;
- return rsd_get_avail(priv->rd);
+ return rsd_get_avail(priv->rd) / ao->sstride;
}
-static int play(struct ao *ao, void *data, int len, int flags)
+static int play(struct ao *ao, void **data, int samples, int flags)
{
struct priv *priv = ao->priv;
- return rsd_write(priv->rd, data, len);
+ return rsd_write(priv->rd, data[0], samples * ao->sstride) / ao->sstride;
}
static float get_delay(struct ao *ao)
diff --git a/audio/out/ao_sdl.c b/audio/out/ao_sdl.c
index d95a82615b..c2b1c9d947 100644
--- a/audio/out/ao_sdl.c
+++ b/audio/out/ao_sdl.c
@@ -261,7 +261,7 @@ static int get_space(struct ao *ao)
SDL_LockMutex(priv->buffer_mutex);
int space = av_fifo_space(priv->buffer);
SDL_UnlockMutex(priv->buffer_mutex);
- return space;
+ return space / ao->sstride;
}
static void pause(struct ao *ao)
@@ -292,20 +292,21 @@ static void resume(struct ao *ao)
do_resume(ao);
}
-static int play(struct ao *ao, void *data, int len, int flags)
+static int play(struct ao *ao, void **data, int samples, int flags)
{
struct priv *priv = ao->priv;
+ int len = samples * ao->sstride;
SDL_LockMutex(priv->buffer_mutex);
int free = av_fifo_space(priv->buffer);
if (len > free) len = free;
- av_fifo_generic_write(priv->buffer, data, len, NULL);
+ av_fifo_generic_write(priv->buffer, data[0], len, NULL);
SDL_CondSignal(priv->underrun_cond);
SDL_UnlockMutex(priv->buffer_mutex);
if (priv->unpause) {
priv->unpause = 0;
do_resume(ao);
}
- return len;
+ return len / ao->sstride;
}
static float get_delay(struct ao *ao)
diff --git a/audio/out/ao_sndio.c b/audio/out/ao_sndio.c
index 1786c0158d..cfe0616943 100644
--- a/audio/out/ao_sndio.c
+++ b/audio/out/ao_sndio.c
@@ -242,16 +242,16 @@ static void reset(struct ao *ao)
/*
* play given number of bytes until sio_write() blocks
*/
-static int play(struct ao *ao, void *data, int len, int flags)
+static int play(struct ao *ao, void **data, int samples, int flags)
{
struct priv *p = ao->priv;
int n;
- n = sio_write(p->hdl, data, len);
+ n = sio_write(p->hdl, data[0], samples * ao->sstride);
p->delay += n;
if (flags & AOPLAY_FINAL_CHUNK)
reset(ao);
- return n;
+ return n / ao->sstride;
}
/*
@@ -271,7 +271,7 @@ static int get_space(struct ao *ao)
; /* nothing */
sio_revents(p->hdl, p->pfd);
- return p->par.bufsz * p->par.pchan * p->par.bps - p->delay;
+ return (p->par.bufsz * p->par.pchan * p->par.bps - p->delay) / ao->sstride;
}
/*
diff --git a/audio/out/ao_wasapi.c b/audio/out/ao_wasapi.c
index 5d9f33278c..b43bf04753 100644
--- a/audio/out/ao_wasapi.c
+++ b/audio/out/ao_wasapi.c
@@ -1197,7 +1197,7 @@ static int get_space(struct ao *ao)
if (!ao || !ao->priv)
return -1;
struct wasapi_state *state = (struct wasapi_state *)ao->priv;
- return mp_ring_available(state->ringbuff);
+ return mp_ring_available(state->ringbuff) / ao->sstride;
}
static void reset_buffers(struct wasapi_state *state)
@@ -1339,25 +1339,24 @@ static void reset(struct ao *ao)
reset_buffers(state);
}
-static int play(struct ao *ao, void *data, int len, int flags)
+static int play(struct ao *ao, void **data, int samples, int flags)
{
- int ret = 0;
if (!ao || !ao->priv)
- return ret;
+ return 0;
struct wasapi_state *state = (struct wasapi_state *)ao->priv;
if (WaitForSingleObject(state->fatal_error, 0) == WAIT_OBJECT_0) {
/* something bad happened */
- return ret;
+ return 0;
}
- ret = mp_ring_write(state->ringbuff, data, len);
+ int ret = mp_ring_write(state->ringbuff, data[0], samples * ao->sstride);
if (!state->is_playing) {
/* start playing */
state->is_playing = 1;
SetEvent(state->hPlay);
}
- return ret;
+ return ret / ao->sstride;
}
static float get_delay(struct ao *ao)