[pulseaudio-discuss] [PATCH 09/11] alsa: jack input device implementation
David Henningsson
david.henningsson at canonical.com
Tue Aug 30 12:25:02 PDT 2011
Signed-off-by: David Henningsson <david.henningsson at canonical.com>
---
src/Makefile.am | 1 +
src/modules/alsa/alsa-jack-inputdev.c | 364 +++++++++++++++++++++++++++++++++
src/modules/alsa/alsa-jack-inputdev.h | 48 +++++
src/modules/alsa/alsa-mixer.c | 50 ++---
src/modules/alsa/alsa-mixer.h | 6 +-
src/modules/alsa/alsa-sink.c | 2 +-
src/modules/alsa/alsa-source.c | 2 +-
src/modules/alsa/module-alsa-card.c | 8 +-
8 files changed, 448 insertions(+), 33 deletions(-)
create mode 100644 src/modules/alsa/alsa-jack-inputdev.c
create mode 100644 src/modules/alsa/alsa-jack-inputdev.h
diff --git a/src/Makefile.am b/src/Makefile.am
index dd143a1..7f24433 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -1543,6 +1543,7 @@ module_coreaudio_device_la_LIBADD = $(MODULE_LIBADD)
libalsa_util_la_SOURCES = \
modules/alsa/alsa-util.c modules/alsa/alsa-util.h \
modules/alsa/alsa-mixer.c modules/alsa/alsa-mixer.h \
+ modules/alsa/alsa-jack-inputdev.c modules/alsa/alsa-jack-inputdev.h \
modules/alsa/alsa-sink.c modules/alsa/alsa-sink.h \
modules/alsa/alsa-source.c modules/alsa/alsa-source.h \
modules/reserve-wrap.c modules/reserve-wrap.h
diff --git a/src/modules/alsa/alsa-jack-inputdev.c b/src/modules/alsa/alsa-jack-inputdev.c
new file mode 100644
index 0000000..8595ce5
--- /dev/null
+++ b/src/modules/alsa/alsa-jack-inputdev.c
@@ -0,0 +1,364 @@
+/***
+ This file is part of PulseAudio.
+
+ Copyright 2011 Canonical Ltd
+ Copyright 2011 Wolfson Microelectronics PLC
+
+ PulseAudio is free software; you can redistribute it and/or modify
+ it under the terms of the GNU Lesser General Public License as published
+ by the Free Software Foundation; either version 2.1 of the License,
+ or (at your option) any later version.
+
+ PulseAudio is distributed in the hope that it will be useful, but
+ WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public License
+ along with PulseAudio; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
+ USA.
+***/
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <errno.h>
+#include <fcntl.h>
+#include <unistd.h>
+#include <libudev.h>
+#include <linux/input.h>
+
+#include "alsa-jack-inputdev.h"
+
+#include <pulsecore/core-util.h>
+#include <pulsecore/strlist.h>
+#include <pulsecore/core.h>
+#include <pulse/xmalloc.h>
+
+struct pa_alsa_jack_inputdev {
+ int fd;
+ pa_io_event* io_event;
+ pa_core* core;
+ int64_t switches_supported;
+ char *devname;
+ pa_hashmap *links; /* Has struct pa_alsa_jack_inputdev_link pointers in it */
+};
+
+
+/* (mostly) from slimlogic/wolfson start */
+
+static const char *jack_get_input_id(const char *path) {
+ int i;
+
+ for( i = 0; i < (int) strlen(path); i++) {
+ if (pa_startswith(path + i, "/event"))
+ return path + i + 6;
+ }
+
+ return NULL;
+}
+
+static pa_bool_t input_node_belongs_to_device(
+ const char *device,
+ const char *node) {
+
+ char *cd;
+ pa_bool_t b;
+
+ cd = pa_sprintf_malloc("/sys%s", device);
+ b = pa_startswith(node, cd);
+ pa_xfree(cd);
+ return b;
+}
+
+static pa_strlist* alsa_jack_inputdev_udev_detect(struct udev* udev, const char* match_path) {
+ struct udev_enumerate *enumerate;
+ struct udev_list_entry *item, *first;
+ const char *jack_path;
+ const char *jack_input;
+ pa_strlist *result = NULL;
+
+ if (!(enumerate = udev_enumerate_new(udev)))
+ pa_log("Failed to initialize udev enumerator");
+ else {
+ if (udev_enumerate_add_match_subsystem(enumerate, "input"))
+ pa_log_debug("Failed to match to subsystem input");
+
+ if (udev_enumerate_scan_devices(enumerate))
+ pa_log_debug("Failed to scan for devices");
+ first = udev_enumerate_get_list_entry(enumerate);
+ udev_list_entry_foreach(item, first) {
+ jack_path = udev_list_entry_get_name(item);
+ if (input_node_belongs_to_device(match_path, jack_path)) {
+ jack_input = jack_get_input_id(jack_path);
+ if (jack_input) {
+ pa_log_debug("found jack input device %s\n", jack_input);
+ result = pa_strlist_prepend(result, jack_input);
+ }
+ }
+ }
+ udev_enumerate_unref(enumerate);
+ }
+ return result;
+}
+
+/* (mostly) from slimlogic/wolfson end */
+
+static char* get_match_path_from_card_idx(struct udev* udev, int card_idx) {
+ char* t;
+ struct udev_device* card;
+
+ t = pa_sprintf_malloc("%s/class/sound/card%i", udev_get_sys_path(udev), card_idx);
+ card = udev_device_new_from_syspath(udev, t);
+ pa_xfree(t);
+ if (!card) {
+ pa_log_error("Udev error getting udev device :-(");
+ return NULL;
+ }
+
+ return pa_xstrdup(udev_device_get_devpath(card));
+}
+
+static void add_inputdev(pa_hashmap* devs, const char* jack_id) {
+ const char *devpath = pa_sprintf_malloc("/dev/input/event%s", jack_id);
+ int fd;
+ char devname[256] = "";
+ int64_t switches = 0;
+
+ pa_assert(SW_MAX <= 63); /* Or switches variable will overflow */
+ pa_assert(devs);
+
+ fd = open(devpath, O_RDONLY);
+ if (fd < 0) {
+ pa_log_info("Could not open %s, error = %s", devpath, strerror(errno));
+ return;
+ }
+
+ if (ioctl(fd, EVIOCGNAME(sizeof(devname)), devname) < 0) {
+ pa_log_warn("Ioctl EVIOCGNAME error %s", strerror(errno));
+ goto finish;
+ }
+ pa_log_debug("Device %s has name \"%s\".", devpath, devname);
+
+ if (ioctl(fd, EVIOCGBIT(EV_SW, SW_MAX), &switches) < 0) {
+ pa_log_warn("Ioctl EVIOCGBIT error %s", strerror(errno));
+ goto finish;
+ }
+
+ if (switches == 0) {
+ pa_log_debug("Device %s does not have any switches.", devname);
+ goto finish;
+ } else {
+ /* Create the new input device */
+ pa_alsa_jack_inputdev *dev = pa_xnew0(pa_alsa_jack_inputdev, 1);
+
+ dev->fd = fd;
+ dev->switches_supported = switches;
+ pa_log_debug("Device %s has switches 0x%x.", devname, (int) switches);
+ dev->devname = pa_xstrdup(devname);
+ dev->links = pa_hashmap_new(pa_idxset_trivial_hash_func, pa_idxset_trivial_compare_func);
+ pa_hashmap_put(devs, dev, dev);
+ return;
+ }
+
+finish:
+ close(fd);
+}
+
+pa_hashmap* pa_alsa_jack_inputdev_enum(int alsa_card_index) {
+ pa_hashmap *result = pa_hashmap_new(pa_idxset_trivial_hash_func, pa_idxset_trivial_compare_func);
+ struct udev* udev = NULL;
+ char* match_path = NULL;
+ pa_strlist* jack_names = NULL;
+
+ if (!(udev = udev_new())) {
+ pa_log("Failed to open udev context.");
+ goto finish;
+ }
+
+ /* Step 1: Get a sysfs path to match input devices to */
+ if (!(match_path = get_match_path_from_card_idx(udev, alsa_card_index)))
+ goto finish;
+
+ /* Step 2: Enumerate all input devices */
+ jack_names = alsa_jack_inputdev_udev_detect(udev, match_path);
+
+ /* Step 3: Open input devices and query capabilities */
+ while (jack_names) {
+ char* jack_id;
+ jack_names = pa_strlist_pop(jack_names, &jack_id);
+ add_inputdev(result, jack_id);
+ pa_xfree(jack_id);
+ }
+
+finish:
+ if (match_path)
+ pa_xfree(match_path);
+ if (udev)
+ udev_unref(udev);
+
+ pa_log_debug("Found %d jack input devices.", pa_hashmap_size(result));
+ return result;
+}
+
+const char* swstrings[SW_MAX+1] = {
+ [SW_HEADPHONE_INSERT] = "Headphone",
+ [SW_MICROPHONE_INSERT] = "Microphone",
+ [SW_LINEOUT_INSERT] = "LineOut",
+ [SW_VIDEOOUT_INSERT] = "VideoOut",
+};
+
+/* Match an alsa path against input devices. Returns matched device or NULL */
+pa_alsa_jack_inputdev_link* pa_alsa_jack_inputdev_match(pa_hashmap* devs, pa_alsa_path* path) {
+ void *state;
+ pa_alsa_jack_inputdev *dev;
+ pa_alsa_jack_inputdev_link *jil;
+ char *name = path->jack_inputdev_name;
+ char *code = path->jack_inputdev_code;
+
+ if (!name && !code)
+ return NULL;
+/* pa_log_debug("Matching against %d devices ", pa_hashmap_size(devs));*/
+ PA_HASHMAP_FOREACH(dev, devs, state) {
+ int64_t switches;
+ int i;
+
+/* pa_log_debug("Matching against %s ", dev->devname);*/
+ if (name) {
+ if (!strstr(dev->devname, name))
+ continue;
+ }
+
+ for (i = 0; i < SW_MAX; i++) {
+ int64_t bitval = 1LL << i;
+ if ((dev->switches_supported & bitval) == 0)
+ continue;
+ if (!swstrings[i])
+ continue;
+ if ((!code) || strstr(code, swstrings[i]))
+ switches |= bitval;
+ }
+
+ if (!switches)
+ continue;
+
+ /* Found a match, let's add it! */
+ jil = pa_xnew0(pa_alsa_jack_inputdev_link, 1);
+ jil->path = path;
+ jil->dev = dev;
+ jil->switches_enable = switches;
+ pa_hashmap_put(dev->links, jil, jil);
+ pa_log_debug("Matched input device %s to control path %s, jil = %p", dev->devname, pa_strnull(path->name), jil);
+
+ return jil;
+ }
+ return NULL;
+}
+
+static void jack_report(pa_alsa_jack_inputdev *dev, uint64_t bitmask, uint64_t bitvalue) {
+ pa_alsa_jack_inputdev_link *jil;
+ void* state;
+ PA_HASHMAP_FOREACH(jil, dev->links, state) {
+ if (jil->switches_enable & bitmask) {
+ pa_assert(jil->port);
+ pa_device_port_set_available(jil->port, bitmask & bitvalue ? PA_PORT_AVAILABLE_YES : PA_PORT_AVAILABLE_NO, dev->core);
+ }
+ }
+}
+
+static void jack_inputdev_cb(pa_mainloop_api*ea, pa_io_event* e, int fd, pa_io_event_flags_t events, void *userdata) {
+ pa_alsa_jack_inputdev* dev = userdata;
+ struct input_event event;
+
+ pa_assert(dev);
+
+ if (pa_read(dev->fd, &event, sizeof(event), NULL) != sizeof(event)) {
+ pa_log_warn("Failed to read event from dev %s", dev->devname);
+ return;
+ }
+
+ pa_log_debug("jack_report: name %s event type %x code %x value %x", dev->devname, event.type, event.code, event.value);
+ if (event.type == EV_SW)
+ jack_report(dev, 1 << event.code, event.value ? ~0 : 0);
+}
+
+
+static void jack_get_initial_state(pa_alsa_jack_inputdev *dev)
+{
+ uint64_t switches;
+ int err;
+
+ pa_assert(SW_MAX < 63);
+ err = ioctl(dev->fd, EVIOCGSW(sizeof(switches)), &switches);
+ if (err < 0) {
+ pa_log("Failed to read initial %s jack status %s", dev->devname, strerror(errno));
+ return;
+ }
+
+ /* We got all bits, set them correctly */
+ jack_report(dev, (1LL << (SW_MAX+1)) - 1, switches);
+}
+
+static void jack_inputdev_start_listening(pa_alsa_jack_inputdev* dev, pa_core* core) {
+ pa_assert(dev);
+
+ dev->core = core;
+ dev->io_event = core->mainloop->io_new(core->mainloop, dev->fd, PA_IO_EVENT_INPUT, jack_inputdev_cb, dev);
+ if (!dev->io_event) {
+ pa_log_warn("Failed to create io event for dev %s :-(", dev->devname);
+ return;
+ }
+ core->mainloop->io_enable(dev->io_event, PA_IO_EVENT_INPUT);
+ jack_get_initial_state(dev);
+}
+
+static void jack_inputdev_free(pa_alsa_jack_inputdev* dev) {
+
+ if (!dev)
+ return;
+
+ if (dev->links) {
+ pa_alsa_jack_inputdev_link* jil;
+ while ((jil = pa_hashmap_steal_first(dev->links))) {
+ if (jil->port)
+ pa_device_port_unref(jil->port);
+ pa_xfree(jil);
+ }
+ pa_hashmap_free(dev->links, NULL, NULL);
+ }
+
+ if (dev->io_event && dev->core) {
+ dev->core->mainloop->io_free(dev->io_event);
+ }
+
+ if (dev->fd)
+ close(dev->fd);
+
+ pa_xfree(dev);
+}
+
+void pa_alsa_jack_inputdev_free(pa_hashmap* devs) {
+ pa_alsa_jack_inputdev* dev;
+
+ if (!devs)
+ return;
+ while ((dev = pa_hashmap_steal_first(devs)))
+ jack_inputdev_free(dev);
+ pa_hashmap_free(devs, NULL, NULL);
+}
+
+void pa_alsa_jack_inputdev_start(pa_hashmap* devs, pa_core* core) {
+ pa_alsa_jack_inputdev* dev;
+ void* state;
+
+ PA_HASHMAP_FOREACH(dev, devs, state) {
+ if (!dev->links || pa_hashmap_isempty(dev->links)) {
+ pa_hashmap_remove(devs, dev);
+ jack_inputdev_free(dev);
+ }
+ else
+ jack_inputdev_start_listening(dev, core);
+ }
+}
diff --git a/src/modules/alsa/alsa-jack-inputdev.h b/src/modules/alsa/alsa-jack-inputdev.h
new file mode 100644
index 0000000..8ca5238
--- /dev/null
+++ b/src/modules/alsa/alsa-jack-inputdev.h
@@ -0,0 +1,48 @@
+/***
+ This file is part of PulseAudio.
+
+ Copyright 2011 Canonical Ltd
+ FIXME: Some code stolen from earlier patches, from Wolfson Microelectronics PLC
+
+ PulseAudio is free software; you can redistribute it and/or modify
+ it under the terms of the GNU Lesser General Public License as published
+ by the Free Software Foundation; either version 2.1 of the License,
+ or (at your option) any later version.
+
+ PulseAudio is distributed in the hope that it will be useful, but
+ WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public License
+ along with PulseAudio; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
+ USA.
+***/
+#ifndef fooalsajackinputdevhfoo
+#define fooalsajackinputdevhfoo
+
+#include <pulsecore/idxset.h>
+#include <pulsecore/hashmap.h>
+#include "alsa-mixer.h"
+
+struct pa_alsa_jack_inputdev_link {
+ pa_device_port *port;
+ pa_alsa_path *path;
+ pa_alsa_jack_inputdev *dev;
+ int64_t switches_enable;
+};
+
+/* Return a list of input devices belonging to this card */
+pa_hashmap* pa_alsa_jack_inputdev_enum(int alsa_card_index);
+
+/* Match an alsa path against input devices. Returns NULL if no match.
+ Returned link pointer is owned by input device and does not need to be freed. */
+pa_alsa_jack_inputdev_link* pa_alsa_jack_inputdev_match(pa_hashmap* devs, pa_alsa_path* path);
+
+/* Start listening to input dev change events, and reports initial state */
+void pa_alsa_jack_inputdev_start(pa_hashmap* devs, pa_core* core);
+
+void pa_alsa_jack_inputdev_free(pa_hashmap* devs);
+
+#endif
diff --git a/src/modules/alsa/alsa-mixer.c b/src/modules/alsa/alsa-mixer.c
index e68258d..f248b95 100644
--- a/src/modules/alsa/alsa-mixer.c
+++ b/src/modules/alsa/alsa-mixer.c
@@ -49,6 +49,7 @@
#include "alsa-mixer.h"
#include "alsa-util.h"
+#include "alsa-jack-inputdev.h"
struct description_map {
const char *name;
@@ -2539,7 +2540,7 @@ static void path_create_settings(pa_alsa_path *p) {
element_create_settings(p->elements, NULL);
}
-int pa_alsa_path_probe(pa_alsa_path *p, snd_mixer_t *m, pa_bool_t ignore_dB) {
+int pa_alsa_path_probe(pa_alsa_path *p, snd_mixer_t *m, pa_bool_t ignore_dB, pa_alsa_profile_set *profile_set) {
pa_alsa_element *e;
double min_dB[PA_CHANNEL_POSITION_MAX], max_dB[PA_CHANNEL_POSITION_MAX];
pa_channel_position_t t;
@@ -2621,6 +2622,9 @@ int pa_alsa_path_probe(pa_alsa_path *p, snd_mixer_t *m, pa_bool_t ignore_dB) {
return -1;
}
+ if (profile_set)
+ p->jack_inputdev_link = pa_alsa_jack_inputdev_match(profile_set->jack_inputdevs, p);
+
path_drop_unsupported(p);
path_make_options_unique(p);
path_create_settings(p);
@@ -3054,7 +3058,10 @@ static void path_set_condense(pa_alsa_path_set *ps, snd_mixer_t *m) {
if (p == p2)
continue;
- /* FIXME: a is not a subset of b if a has a matched port and b has not. */
+ /* a is not a subset of b if a has a matched input device and b has not. */
+ if (p->jack_inputdev_link && ((!p2->jack_inputdev_link) ||
+ p->jack_inputdev_link->dev != p2->jack_inputdev_link->dev))
+ is_subset = FALSE;
/* Compare the elements of each set... */
pa_assert_se(ea = p->elements);
@@ -3126,31 +3133,7 @@ static void path_set_make_paths_unique(pa_alsa_path_set *ps) {
/* This function is no longer used. */
void pa_alsa_path_set_probe(pa_alsa_path_set *ps, snd_mixer_t *m, pa_bool_t ignore_dB) {
- pa_alsa_path *p, *n;
-
- pa_assert(ps);
-
- if (ps->probed)
- return;
-
- for (p = ps->paths; p; p = n) {
- n = p->next;
-
- if (pa_alsa_path_probe(p, m, ignore_dB) < 0) {
- PA_LLIST_REMOVE(pa_alsa_path, ps->paths, p);
- /* pa_alsa_path_free(p); Paths are now owned by the profile set */
- }
- }
-
- pa_log_debug("Found mixer paths (before tidying):");
- pa_alsa_path_set_dump(ps);
-
- path_set_condense(ps, m);
- path_set_make_paths_unique(ps);
- ps->probed = TRUE;
-
- pa_log_debug("Available mixer paths (after tidying):");
- pa_alsa_path_set_dump(ps);
+ return;
}
static void mapping_free(pa_alsa_mapping *m) {
@@ -3724,7 +3707,7 @@ static void mapping_paths_probe(pa_alsa_mapping *m, pa_alsa_profile *profile, pa
for (p = ps->paths; p; p = np) {
np = p->next;
- if (pa_alsa_path_probe(p, mixer_handle, m->profile_set->ignore_dB) < 0) {
+ if (pa_alsa_path_probe(p, mixer_handle, m->profile_set->ignore_dB, m->profile_set) < 0) {
PA_LLIST_REMOVE(pa_alsa_path, ps->paths, p);
}
}
@@ -4372,7 +4355,13 @@ static pa_device_port* device_port_alsa_init(pa_hashmap *ports,
data = PA_DEVICE_PORT_DATA(p);
data->path = path;
data->setting = setting;
+ pa_log_debug("Adding port: path = %s, link-dev = %p", path->name, path->jack_inputdev_link);
+ if (path->jack_inputdev_link) {
+ path->jack_inputdev_link->port = p;
+ pa_device_port_ref(p);
+ }
}
+ pa_log_debug("Adding port %s to profile %s", p->name, cp->name);
pa_hashmap_put(p->profiles, cp->name, cp);
return p;
@@ -4385,10 +4374,13 @@ void pa_alsa_path_set_add_ports(pa_alsa_path_set *ps, pa_card_profile *cp, pa_ha
pa_assert(cp);
pa_assert(ports);
+ pa_log_debug("pa_alsa_path_set_add_ports: ps = %p, profile = %s", ps, cp->name);
+
if (!ps)
return;
PA_LLIST_FOREACH(path, ps->paths) {
+ pa_log_debug("pa_alsa_path_set_add_ports: path = %p, %s", path, path->name);
if (!path->settings || !path->settings->next) {
/* If there is no or just one setting we only need a
* single entry */
@@ -4429,6 +4421,8 @@ void pa_alsa_add_ports(pa_hashmap **p, pa_alsa_path_set *ps) {
pa_assert(!*p);
pa_assert(ps);
+ *p = pa_hashmap_new(pa_idxset_string_hash_func, pa_idxset_string_compare_func);
+
/* if there is no path, we don't want a port list */
if (!ps->paths)
return;
diff --git a/src/modules/alsa/alsa-mixer.h b/src/modules/alsa/alsa-mixer.h
index 1d99b13..75edc02 100644
--- a/src/modules/alsa/alsa-mixer.h
+++ b/src/modules/alsa/alsa-mixer.h
@@ -45,6 +45,8 @@ typedef struct pa_alsa_profile pa_alsa_profile;
typedef struct pa_alsa_decibel_fix pa_alsa_decibel_fix;
typedef struct pa_alsa_profile_set pa_alsa_profile_set;
typedef struct pa_alsa_port_data pa_alsa_port_data;
+typedef struct pa_alsa_jack_inputdev_link pa_alsa_jack_inputdev_link;
+typedef struct pa_alsa_jack_inputdev pa_alsa_jack_inputdev;
#include "alsa-util.h"
@@ -168,6 +170,7 @@ struct pa_alsa_path {
char *jack_inputdev_name;
char *jack_inputdev_code;
+ pa_alsa_jack_inputdev_link *jack_inputdev_link;
pa_bool_t probed:1;
pa_bool_t supported:1;
@@ -212,7 +215,7 @@ void pa_alsa_element_dump(pa_alsa_element *e);
pa_alsa_path *pa_alsa_path_new(const char *fname, pa_alsa_direction_t direction);
pa_alsa_path *pa_alsa_path_synthesize(const char *element, pa_alsa_direction_t direction);
-int pa_alsa_path_probe(pa_alsa_path *p, snd_mixer_t *m, pa_bool_t ignore_dB);
+int pa_alsa_path_probe(pa_alsa_path *p, snd_mixer_t *m, pa_bool_t ignore_dB, pa_alsa_profile_set *profile_set);
void pa_alsa_path_dump(pa_alsa_path *p);
int pa_alsa_path_get_volume(pa_alsa_path *p, snd_mixer_t *m, const pa_channel_map *cm, pa_cvolume *v);
int pa_alsa_path_get_mute(pa_alsa_path *path, snd_mixer_t *m, pa_bool_t *muted);
@@ -295,6 +298,7 @@ struct pa_alsa_profile_set {
pa_hashmap *decibel_fixes;
pa_hashmap *input_paths;
pa_hashmap *output_paths;
+ pa_hashmap *jack_inputdevs;
pa_bool_t auto_profiles;
pa_bool_t ignore_dB:1;
diff --git a/src/modules/alsa/alsa-sink.c b/src/modules/alsa/alsa-sink.c
index 612ad5b..850e07b 100644
--- a/src/modules/alsa/alsa-sink.c
+++ b/src/modules/alsa/alsa-sink.c
@@ -1796,7 +1796,7 @@ static void find_mixer(struct userdata *u, pa_alsa_mapping *mapping, const char
if (!(u->mixer_path = pa_alsa_path_synthesize(element, PA_ALSA_DIRECTION_OUTPUT)))
goto fail;
- if (pa_alsa_path_probe(u->mixer_path, u->mixer_handle, ignore_dB) < 0)
+ if (pa_alsa_path_probe(u->mixer_path, u->mixer_handle, ignore_dB, NULL) < 0)
goto fail;
pa_log_debug("Probed mixer path %s:", u->mixer_path->name);
diff --git a/src/modules/alsa/alsa-source.c b/src/modules/alsa/alsa-source.c
index 8318498..e34e51f 100644
--- a/src/modules/alsa/alsa-source.c
+++ b/src/modules/alsa/alsa-source.c
@@ -1508,7 +1508,7 @@ static void find_mixer(struct userdata *u, pa_alsa_mapping *mapping, const char
if (!(u->mixer_path = pa_alsa_path_synthesize(element, PA_ALSA_DIRECTION_INPUT)))
goto fail;
- if (pa_alsa_path_probe(u->mixer_path, u->mixer_handle, ignore_dB) < 0)
+ if (pa_alsa_path_probe(u->mixer_path, u->mixer_handle, ignore_dB, NULL) < 0)
goto fail;
pa_log_debug("Probed mixer path %s:", u->mixer_path->name);
diff --git a/src/modules/alsa/module-alsa-card.c b/src/modules/alsa/module-alsa-card.c
index 7b120be..3eea300 100644
--- a/src/modules/alsa/module-alsa-card.c
+++ b/src/modules/alsa/module-alsa-card.c
@@ -40,6 +40,7 @@
#include "alsa-sink.h"
#include "alsa-source.h"
#include "module-alsa-card-symdef.h"
+#include "alsa-jack-inputdev.h"
PA_MODULE_AUTHOR("Lennart Poettering");
PA_MODULE_DESCRIPTION("ALSA Card");
@@ -348,11 +349,11 @@ int pa__init(pa_module *m) {
u->profile_set = pa_alsa_profile_set_new(fn, &u->core->default_channel_map);
pa_xfree(fn);
- u->profile_set->ignore_dB = ignore_dB;
-
if (!u->profile_set)
goto fail;
+ u->profile_set->ignore_dB = ignore_dB;
+ u->profile_set->jack_inputdevs = pa_alsa_jack_inputdev_enum(alsa_card_index);
pa_alsa_profile_set_probe(u->profile_set, u->device_id, &m->core->default_sample_spec, m->core->default_n_fragments, m->core->default_fragment_size_msec);
pa_alsa_profile_set_dump(u->profile_set);
@@ -409,6 +410,7 @@ int pa__init(pa_module *m) {
u->card->set_profile = card_set_profile;
init_profile(u);
+ pa_alsa_jack_inputdev_start(u->profile_set->jack_inputdevs, m->core);
if (reserve)
pa_reserve_wrapper_unref(reserve);
@@ -474,6 +476,8 @@ void pa__done(pa_module*m) {
pa_alsa_source_free(s);
}
+ pa_alsa_jack_inputdev_free(u->profile_set->jack_inputdevs);
+
if (u->card)
pa_card_free(u->card);
--
1.7.5.4
More information about the pulseaudio-discuss
mailing list