From 20a1d0bc5bd0de88f83d3b7f468ea8ffbfbfe1e3 Mon Sep 17 00:00:00 2001 From: wm4 Date: Thu, 9 May 2013 12:10:09 +0200 Subject: 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. --- audio/out/ao_openal.c | 41 +++++++++++++++++++++++++++++++---------- 1 file changed, 31 insertions(+), 10 deletions(-) (limited to 'audio/out/ao_openal.c') 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; -- cgit v1.2.3