summaryrefslogtreecommitdiffstats
path: root/audio
diff options
context:
space:
mode:
authorwm4 <wm4@nowhere>2013-05-09 12:10:09 +0200
committerwm4 <wm4@nowhere>2013-05-12 21:24:56 +0200
commit20a1d0bc5bd0de88f83d3b7f468ea8ffbfbfe1e3 (patch)
treee395b5e9b4c2b84b4c962855a3da21afe0e9f21b /audio
parentd9582ad0a41ed5452ad29bf8511e8c6a3bdbe6f8 (diff)
downloadmpv-20a1d0bc5bd0de88f83d3b7f468ea8ffbfbfe1e3.tar.bz2
mpv-20a1d0bc5bd0de88f83d3b7f468ea8ffbfbfe1e3.tar.xz
ao_openal: use channel map instead of ALSA fixed layout
Now mpv's channel map is used to map each channel to a speaker. This allows in theory for playback of any layout for which ao_openal actually has a speaker defined. Also add the back-center (BC) speaker, which allows playback of 6.0 audio. Enabling more layouts by adding other speakers would be possible, but I'm not sure about the speaker positions.
Diffstat (limited to 'audio')
-rw-r--r--audio/out/ao_openal.c41
1 files changed, 31 insertions, 10 deletions
diff --git a/audio/out/ao_openal.c b/audio/out/ao_openal.c
index e6e1369a2f..4c906802e1 100644
--- a/audio/out/ao_openal.c
+++ b/audio/out/ao_openal.c
@@ -109,17 +109,29 @@ static void list_devices(void) {
}
}
+struct speaker {
+ int id;
+ float pos[3];
+};
+
+static const struct speaker speaker_pos[] = {
+ {MP_SPEAKER_ID_FL, {-1, 0, 0.5}},
+ {MP_SPEAKER_ID_FR, { 1, 0, 0.5}},
+ {MP_SPEAKER_ID_FC, { 0, 0, 1}},
+ {MP_SPEAKER_ID_LFE, { 0, 0, 0.1}},
+ {MP_SPEAKER_ID_BL, {-1, 0, -1}},
+ {MP_SPEAKER_ID_BR, { 1, 0, -1}},
+ {MP_SPEAKER_ID_BC, { 0, 0, -1}},
+ {MP_SPEAKER_ID_SL, {-1, 0, 0}},
+ {MP_SPEAKER_ID_SR, { 1, 0, 0}},
+ {-1},
+};
+
static int init(int rate, const struct mp_chmap *channels, int format,
int flags)
{
float position[3] = {0, 0, 0};
float direction[6] = {0, 0, 1, 0, -1, 0};
- float sppos[MAX_CHANS][3] = {
- {-1, 0, 0.5}, {1, 0, 0.5},
- {-1, 0, -1}, {1, 0, -1},
- {0, 0, 1}, {0, 0, 0.1},
- {-1, 0, 0}, {1, 0, 0},
- };
ALCdevice *dev = NULL;
ALCcontext *ctx = NULL;
ALCint freq = 0;
@@ -144,6 +156,18 @@ static int init(int rate, const struct mp_chmap *channels, int format,
ao_data.channels.num);
goto err_out;
}
+ struct speaker speakers[MAX_CHANS];
+ for (i = 0; i < ao_data.channels.num; i++) {
+ speakers[i].id = -1;
+ for (int n = 0; speaker_pos[n].id >= 0; n++) {
+ if (speaker_pos[n].id == ao_data.channels.speaker[i])
+ speakers[i] = speaker_pos[n];
+ }
+ if (speakers[i].id < 0) {
+ mp_msg(MSGT_AO, MSGL_FATAL, "[OpenAL] Unknown channel layout\n");
+ goto err_out;
+ }
+ }
dev = alcOpenDevice(device);
if (!dev) {
mp_msg(MSGT_AO, MSGL_FATAL, "[OpenAL] could not open device\n");
@@ -158,11 +182,9 @@ static int init(int rate, const struct mp_chmap *channels, int format,
cur_buf[i] = 0;
unqueue_buf[i] = 0;
alGenBuffers(NUM_BUF, buffers[i]);
- alSourcefv(sources[i], AL_POSITION, sppos[i]);
+ alSourcefv(sources[i], AL_POSITION, speakers[i].pos);
alSource3f(sources[i], AL_VELOCITY, 0, 0, 0);
}
- if (ao_data.channels.num == 1)
- alSource3f(sources[0], AL_POSITION, 0, 0, 1);
alcGetIntegerv(dev, ALC_FREQUENCY, 1, &freq);
if (alcGetError(dev) == ALC_NO_ERROR && freq)
rate = freq;
@@ -171,7 +193,6 @@ static int init(int rate, const struct mp_chmap *channels, int format,
ao_data.bps = ao_data.channels.num * rate * 2;
ao_data.buffersize = CHUNK_SIZE * NUM_BUF;
ao_data.outburst = ao_data.channels.num * CHUNK_SIZE;
- mp_chmap_reorder_to_alsa(&ao_data.channels); // sppos[][] matrix is for ALSA
tmpbuf = malloc(CHUNK_SIZE);
free(device);
return 1;