summaryrefslogtreecommitdiffstats
path: root/audio/out/ao_alsa.c
diff options
context:
space:
mode:
authorwm4 <wm4@nowhere>2013-05-09 18:06:26 +0200
committerwm4 <wm4@nowhere>2013-05-12 21:24:57 +0200
commitecc6e379b24dd5e37b864ae599a154880a2bd2d0 (patch)
treef439d10380a5f234b660cabb236470cabb1d4d0d /audio/out/ao_alsa.c
parentab8f28a672fbd8d21a98c265976068e80be082a7 (diff)
downloadmpv-ecc6e379b24dd5e37b864ae599a154880a2bd2d0.tar.bz2
mpv-ecc6e379b24dd5e37b864ae599a154880a2bd2d0.tar.xz
audio/out: channel map selection
Make all AOs use what has been introduced in the previous commit. Note that even AOs which can handle all possible layouts (like ao_null) use the new functions. This might be important if in the future ao_select_champ() possibly honors global user options about downmixing and so on.
Diffstat (limited to 'audio/out/ao_alsa.c')
-rw-r--r--audio/out/ao_alsa.c53
1 files changed, 30 insertions, 23 deletions
diff --git a/audio/out/ao_alsa.c b/audio/out/ao_alsa.c
index 477caa51de..bb7a5cbb15 100644
--- a/audio/out/ao_alsa.c
+++ b/audio/out/ao_alsa.c
@@ -330,22 +330,35 @@ static const char *device_channel_layouts[][2] = {
{"surround41", "fl-fr-bl-br-lfe"},
{"surround51", "fl-fr-bl-br-fc-lfe"},
{"surround71", "fl-fr-bl-br-fc-lfe-sl-sr"},
- {0}
};
-// Find a device that contains exactly all the requested speakers.
-// Set *request to the required channel order.
-static const char *find_device(struct mp_chmap *request)
+#define ARRAY_LEN(x) (sizeof(x) / sizeof((x)[0]))
+
+#define NUM_ALSA_CHMAPS ARRAY_LEN(device_channel_layouts)
+
+static const char *select_chmap(struct ao *ao)
{
- for (int n = 0; device_channel_layouts[n][0]; n++) {
- struct mp_chmap map = {0};
- mp_chmap_from_str(&map, bstr0(device_channel_layouts[n][1]));
- if (mp_chmap_equals_reordered(&map, request)) {
- *request = map;
+ struct mp_chmap_sel sel = {0};
+ struct mp_chmap maps[NUM_ALSA_CHMAPS];
+ for (int n = 0; n < NUM_ALSA_CHMAPS; n++) {
+ mp_chmap_from_str(&maps[n], bstr0(device_channel_layouts[n][1]));
+ mp_chmap_sel_add_map(&sel, &maps[n]);
+ };
+
+ if (!ao_chmap_sel_adjust(ao, &sel, &ao->channels))
+ return NULL;
+
+ for (int n = 0; n < NUM_ALSA_CHMAPS; n++) {
+ if (mp_chmap_equals(&ao->channels, &maps[n]))
return device_channel_layouts[n][0];
- }
}
- return NULL;
+
+ char *name = mp_chmap_to_str(&ao->channels);
+ mp_tmsg(MSGT_AO, MSGL_ERR,
+ "[AO_ALSA] channel layout %s (%d ch) not supported.\n",
+ name, ao->channels.num);
+ talloc_free(name);
+ return "default";
}
static int try_open_device(struct ao *ao, const char *device, int open_mode,
@@ -449,16 +462,7 @@ static int init(struct ao *ao, char *params)
"alsa-spdif-init: playing AC3/iec61937/iec958, %i channels\n",
ao->channels.num);
} else {
- device.str = find_device(&ao->channels);
- if (!device.str) {
- char *name = mp_chmap_to_str(&ao->channels);
- device.str = "default";
- mp_chmap_from_channels(&ao->channels, ao->channels.num);
- mp_tmsg(MSGT_AO, MSGL_ERR,
- "[AO_ALSA] channel layout %s (%d ch) not supported.\n",
- name, ao->channels.num);
- talloc_free(name);
- }
+ device.str = select_chmap(ao);
if (strcmp(device.str, "default") != 0 && ao->format == AF_FORMAT_FLOAT_NE)
{
// hack - use the converter plugin (why the heck?)
@@ -535,8 +539,11 @@ static int init(struct ao *ao, char *params)
(p->alsa, alsa_hwparams, &num_channels);
CHECK_ALSA_ERROR("Unable to set channels");
- if (num_channels != ao->channels.num)
- mp_chmap_from_channels(&ao->channels, num_channels);
+ if (num_channels != ao->channels.num) {
+ mp_tmsg(MSGT_AO, MSGL_ERR,
+ "[AO_ALSA] Couldn't get requested number of channels.\n");
+ mp_chmap_from_channels_alsa(&ao->channels, num_channels);
+ }
/* workaround for buggy rate plugin (should be fixed in ALSA 1.0.11)
prefer our own resampler, since that allows users to choose the resampler,