summaryrefslogtreecommitdiffstats
path: root/audio
diff options
context:
space:
mode:
authorwm4 <wm4@nowhere>2013-11-10 23:39:22 +0100
committerwm4 <wm4@nowhere>2013-11-12 23:30:37 +0100
commit7510caa0c5ef3db320d1065f869d14c0eddecf79 (patch)
tree4fe8245ea0a69f17b26fdd333a4d546db9c3c3ce /audio
parentdab6eaaa5e48d7a333564a29b0e04440d24a4ba5 (diff)
downloadmpv-7510caa0c5ef3db320d1065f869d14c0eddecf79.tar.bz2
mpv-7510caa0c5ef3db320d1065f869d14c0eddecf79.tar.xz
ao_openal: support non-interleaved output
Since ao_openal simulates multi-channel audio by placing a bunch of mono-sources in 3D space, non-interleaved audio is a perfect match for it. We just have to remove the interleaving code.
Diffstat (limited to 'audio')
-rw-r--r--audio/out/ao_openal.c29
1 files changed, 11 insertions, 18 deletions
diff --git a/audio/out/ao_openal.c b/audio/out/ao_openal.c
index 256e50f281..c126852389 100644
--- a/audio/out/ao_openal.c
+++ b/audio/out/ao_openal.c
@@ -45,12 +45,12 @@
#define MAX_CHANS MP_NUM_CHANNELS
#define NUM_BUF 128
#define CHUNK_SIZE 512
+#define CHUNK_SAMPLES (CHUNK_SIZE / 2)
static ALuint buffers[MAX_CHANS][NUM_BUF];
static ALuint sources[MAX_CHANS];
static int cur_buf[MAX_CHANS];
static int unqueue_buf[MAX_CHANS];
-static int16_t *tmpbuf;
static struct ao *ao_data;
@@ -169,8 +169,7 @@ static int init(struct ao *ao)
alcGetIntegerv(dev, ALC_FREQUENCY, 1, &freq);
if (alcGetError(dev) == ALC_NO_ERROR && freq)
ao->samplerate = freq;
- ao->format = AF_FORMAT_S16_NE;
- tmpbuf = malloc(CHUNK_SIZE);
+ ao->format = AF_FORMAT_S16P;
return 0;
err_out:
@@ -182,7 +181,6 @@ static void uninit(struct ao *ao, bool immed)
{
ALCcontext *ctx = alcGetCurrentContext();
ALCdevice *dev = alcGetContextsDevice(ctx);
- free(tmpbuf);
if (!immed) {
ALint state;
alGetSourcei(sources[0], AL_SOURCE_STATE, &state);
@@ -251,7 +249,7 @@ static int get_space(struct ao *ao)
queued = NUM_BUF - queued - 3;
if (queued < 0)
return 0;
- return (queued * CHUNK_SIZE * ao->channels.num) / ao->sstride;
+ return queued * CHUNK_SAMPLES;
}
/**
@@ -260,26 +258,21 @@ static int get_space(struct ao *ao)
static int play(struct ao *ao, void **data, int samples, int flags)
{
ALint state;
- int i, j, k;
- int ch;
- 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++) {
- for (j = 0, k = ch; j < CHUNK_SIZE / 2; j++, k += ao->channels.num)
- tmpbuf[j] = d[k];
- alBufferData(buffers[ch][cur_buf[ch]], AL_FORMAT_MONO16, tmpbuf,
+ int num = samples / CHUNK_SAMPLES;
+ for (int i = 0; i < num; i++) {
+ for (int ch = 0; ch < ao->channels.num; ch++) {
+ int16_t *d = data[ch];
+ d += i * CHUNK_SAMPLES;
+ alBufferData(buffers[ch][cur_buf[ch]], AL_FORMAT_MONO16, d,
CHUNK_SIZE, ao->samplerate);
alSourceQueueBuffers(sources[ch], 1, &buffers[ch][cur_buf[ch]]);
cur_buf[ch] = (cur_buf[ch] + 1) % NUM_BUF;
}
- d += ao->channels.num * CHUNK_SIZE / 2;
}
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 / ao->sstride;
+ return num * CHUNK_SAMPLES;
}
static float get_delay(struct ao *ao)
@@ -287,7 +280,7 @@ static float get_delay(struct ao *ao)
ALint queued;
unqueue_buffers();
alGetSourcei(sources[0], AL_BUFFERS_QUEUED, &queued);
- return queued * CHUNK_SIZE / 2 / (float)ao->samplerate;
+ return queued * CHUNK_SAMPLES / (float)ao->samplerate;
}
#define OPT_BASE_STRUCT struct priv