diff options
-rw-r--r-- | .SRCINFO | 41 | ||||
-rw-r--r-- | 0001-bluetooth-new-module-bluedio-fixup.patch | 276 | ||||
-rw-r--r-- | PKGBUILD | 57 |
3 files changed, 374 insertions, 0 deletions
diff --git a/.SRCINFO b/.SRCINFO new file mode 100644 index 000000000000..2ad7820d1002 --- /dev/null +++ b/.SRCINFO @@ -0,0 +1,41 @@ +pkgbase = pulseaudio-bluedio + pkgdesc = Fixup Pulseaudio module for my Bluedio headset + pkgver = 13.0 + pkgrel = 3 + url = https://www.freedesktop.org/wiki/Software/PulseAudio/ + arch = x86_64 + license = GPL + makedepends = libasyncns + makedepends = libcap + makedepends = attr + makedepends = libxtst + makedepends = libsm + makedepends = libsndfile + makedepends = rtkit + makedepends = libsoxr + makedepends = speexdsp + makedepends = tdb + makedepends = systemd + makedepends = dbus + makedepends = avahi + makedepends = bluez + makedepends = bluez-libs + makedepends = jack2 + makedepends = sbc + makedepends = lirc + makedepends = openssl + makedepends = fftw + makedepends = orc + makedepends = gtk3 + makedepends = webrtc-audio-processing + makedepends = check + makedepends = git + makedepends = meson + makedepends = xmltoman + source = git+https://gitlab.freedesktop.org/pulseaudio/pulseaudio.git#commit=200618b32f0964a479d69c9b6e5073e6931c370a + source = 0001-bluetooth-new-module-bluedio-fixup.patch + sha256sums = SKIP + sha256sums = bc83a8075decebf7b18efd165593ad0f658dd97881c21804dae3699c1df8bc2f + +pkgname = pulseaudio-bluedio + diff --git a/0001-bluetooth-new-module-bluedio-fixup.patch b/0001-bluetooth-new-module-bluedio-fixup.patch new file mode 100644 index 000000000000..c03ef980d26b --- /dev/null +++ b/0001-bluetooth-new-module-bluedio-fixup.patch @@ -0,0 +1,276 @@ +From 4bf7d1ccab86a4b23dea2c8be8e0debef8998a40 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?C=C3=A9dric=20Schieli?= <cschieli@gmail.com> +Date: Sun, 12 Jan 2020 11:34:33 +0100 +Subject: [PATCH] bluetooth: new module-bluedio-fixup +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +Signed-off-by: Cédric Schieli <cschieli@gmail.com> +--- + src/Makefile.am | 6 + + src/modules/bluetooth/module-bluedio-fixup.c | 215 +++++++++++++++++++ + src/modules/meson.build | 1 + + 3 files changed, 222 insertions(+) + create mode 100644 src/modules/bluetooth/module-bluedio-fixup.c + +diff --git a/src/Makefile.am b/src/Makefile.am +index 437311de6..37c817898 100644 +--- a/src/Makefile.am ++++ b/src/Makefile.am +@@ -1491,6 +1491,7 @@ endif + if HAVE_BLUEZ_5 + modlibexec_LTLIBRARIES += \ + libbluez5-util.la \ ++ module-bluedio-fixup.la \ + module-bluez5-discover.la \ + module-bluez5-device.la + endif +@@ -2174,6 +2175,11 @@ module_bluez5_device_la_LDFLAGS = $(MODULE_LDFLAGS) + module_bluez5_device_la_LIBADD = $(MODULE_LIBADD) libbluez5-util.la + module_bluez5_device_la_CFLAGS = $(AM_CFLAGS) -DPA_MODULE_NAME=module_bluez5_device + ++module_bluedio_fixup_la_SOURCES = modules/bluetooth/module-bluedio-fixup.c ++module_bluedio_fixup_la_LDFLAGS = $(MODULE_LDFLAGS) ++module_bluedio_fixup_la_LIBADD = $(MODULE_LIBADD) libbluez5-util.la ++module_bluedio_fixup_la_CFLAGS = $(AM_CFLAGS) -DPA_MODULE_NAME=module_bluedio_fixup ++ + # Apple Airtunes/RAOP + module_raop_sink_la_SOURCES = modules/raop/module-raop-sink.c + module_raop_sink_la_LDFLAGS = $(MODULE_LDFLAGS) +diff --git a/src/modules/bluetooth/module-bluedio-fixup.c b/src/modules/bluetooth/module-bluedio-fixup.c +new file mode 100644 +index 000000000..7f82be281 +--- /dev/null ++++ b/src/modules/bluetooth/module-bluedio-fixup.c +@@ -0,0 +1,215 @@ ++#ifdef HAVE_CONFIG_H ++#include <config.h> ++#endif ++ ++#include <pulse/xmalloc.h> ++#include <pulse/mainloop-api.h> ++ ++#include <pulsecore/core.h> ++#include <pulsecore/core-util.h> ++#include <pulsecore/core-scache.h> ++#include <pulsecore/i18n.h> ++#include <pulsecore/sink.h> ++#include <pulsecore/modargs.h> ++#include <pulsecore/namereg.h> ++#include <pulsecore/log.h> ++ ++PA_MODULE_AUTHOR("Cédric Schieli"); ++PA_MODULE_DESCRIPTION(_("Load an equalizer to fix the Bluedio sink.")); ++PA_MODULE_VERSION(PACKAGE_VERSION); ++PA_MODULE_LOAD_ONCE(true); ++PA_MODULE_USAGE( ++ "control=<ladspa control values> " ++ "sample=<sample to play on load>"); ++ ++#define BLUEDIO_ALIAS "Bluedio" ++#define EQ_SINK_NAME "bluedio_eq" ++#define DEFAULT_CONTROL_VALUES "-16,-14,-12,-10,-8,-6,-4,-2,0,2,4,6,8,10,12" ++#define DEFAULT_SAMPLE "service-login.oga" ++#define BLUEDIO_PORT "headset-output" ++ ++static const char* const valid_modargs[] = { ++ "control", ++ "sample", ++ NULL, ++}; ++ ++struct userdata { ++ pa_hook_slot *put_slot; ++ pa_hook_slot *unlink_slot; ++ uint32_t bluedio_sink; ++ uint32_t ladspa_module; ++ char *control; ++ char *sample; ++ pa_core *core; ++}; ++ ++static bool is_bluedio_sink(pa_sink *sink) { ++ const char *prop; ++ ++ pa_assert(sink); ++ ++ prop = pa_proplist_gets(sink->proplist, "bluez.alias"); ++ if (!prop || !pa_streq(prop, BLUEDIO_ALIAS)) ++ return false; ++ prop = pa_proplist_gets(sink->proplist, "bluetooth.protocol"); ++ if (!prop || !pa_streq(prop, "a2dp_sink")) ++ return false; ++ return true; ++} ++ ++static void play_sample(pa_mainloop_api *api PA_GCC_UNUSED, void *userdata) { ++ struct userdata *u = userdata; ++ ++ pa_assert(u); ++ ++ if (pa_namereg_is_valid_name(EQ_SINK_NAME)) { ++ if (pa_scache_play_item_by_name(u->core, u->sample, EQ_SINK_NAME, 65536, NULL, NULL) < 0) ++ pa_log_warn("Error playing sample"); ++ pa_core_set_configured_default_sink(u->core, EQ_SINK_NAME); ++ } ++} ++ ++static void load_ladspa_sink(pa_core *c, pa_sink *sink, struct userdata* u) { ++ char *t; ++ pa_module *m = NULL; ++ ++ pa_assert(c); ++ pa_assert(sink); ++ pa_assert(u); ++ pa_assert(u->ladspa_module == PA_INVALID_INDEX); ++ ++ pa_log_debug("Autoloading module-ladspa-sink"); ++ ++ t = pa_sprintf_malloc("sink_name=" EQ_SINK_NAME " sink_master=%s plugin=mbeq_1197 label=mbeq control=%s", sink->name, u->control); ++ if (!pa_module_load(&m, c, "module-ladspa-sink", t)) ++ u->ladspa_module = m ? m->index : PA_INVALID_INDEX; ++ pa_xfree(t); ++ ++ if (!m) ++ pa_log_warn("Unable to load module-ladspa-sink"); ++} ++ ++static pa_hook_result_t put_hook_callback(pa_core *c, pa_sink *sink, void* userdata) { ++ struct userdata *u = userdata; ++ ++ pa_assert(c); ++ pa_assert(sink); ++ pa_assert(u); ++ ++ /* There's no point in doing anything if the core is shut down anyway */ ++ if (c->state == PA_CORE_SHUTDOWN) ++ return PA_HOOK_OK; ++ ++ if (pa_streq(sink->name, EQ_SINK_NAME)) { ++ pa_mainloop_api_once(c->mainloop, play_sample, u); ++ return PA_HOOK_OK; ++ } ++ ++ if (!is_bluedio_sink(sink)) ++ return PA_HOOK_OK; ++ ++ u->bluedio_sink = sink->index; ++ ++ load_ladspa_sink(c, sink, u); ++ ++ return PA_HOOK_OK; ++} ++ ++static pa_hook_result_t unlink_hook_callback(pa_core *c, pa_sink *sink, void* userdata) { ++ struct userdata *u = userdata; ++ ++ pa_assert(c); ++ pa_assert(sink); ++ pa_assert(u); ++ ++ /* First check to see if it's our own ladspa-sink that's been removed... */ ++ if (u->ladspa_module != PA_INVALID_INDEX && sink->module && sink->module->index == u->ladspa_module) { ++ pa_log_debug("Autoloaded ladspa-sink removed"); ++ u->ladspa_module = PA_INVALID_INDEX; ++ return PA_HOOK_OK; ++ } ++ ++ /* There's no point in doing anything if the core is shut down anyway */ ++ if (c->state == PA_CORE_SHUTDOWN) ++ return PA_HOOK_OK; ++ ++ if (u->bluedio_sink == PA_INVALID_INDEX) ++ return PA_HOOK_OK; ++ ++ if (sink->index != u->bluedio_sink) ++ return PA_HOOK_OK; ++ ++ u->bluedio_sink = PA_INVALID_INDEX; ++ ++ pa_module_unload_request_by_index(c, u->ladspa_module, true); ++ ++ return PA_HOOK_OK; ++} ++ ++int pa__init(pa_module*m) { ++ pa_modargs *ma = NULL; ++ struct userdata *u; ++ pa_sink *sink; ++ uint32_t idx; ++ ++ pa_assert(m); ++ ++ if (!(ma = pa_modargs_new(m->argument, valid_modargs))) { ++ pa_log("Failed to parse module arguments"); ++ return -1; ++ } ++ ++ m->userdata = u = pa_xnew(struct userdata, 1); ++ u->core = m->core; ++ u->control = pa_xstrdup(pa_modargs_get_value(ma, "control", DEFAULT_CONTROL_VALUES)); ++ u->sample = pa_xstrdup(pa_modargs_get_value(ma, "sample", DEFAULT_SAMPLE)); ++ u->put_slot = pa_hook_connect(&m->core->hooks[PA_CORE_HOOK_SINK_PUT], PA_HOOK_LATE, (pa_hook_cb_t) put_hook_callback, u); ++ u->unlink_slot = pa_hook_connect(&m->core->hooks[PA_CORE_HOOK_SINK_UNLINK], PA_HOOK_EARLY, (pa_hook_cb_t) unlink_hook_callback, u); ++ u->ladspa_module = PA_INVALID_INDEX; ++ u->bluedio_sink = PA_INVALID_INDEX; ++ ++ PA_IDXSET_FOREACH(sink, m->core->sinks, idx) { ++ if (is_bluedio_sink(sink)) ++ u->bluedio_sink = idx; ++ if (sink->module && sink->name && pa_streq(sink->name, EQ_SINK_NAME)) ++ u->ladspa_module = sink->module->index; ++ } ++ ++ if (u->bluedio_sink == PA_INVALID_INDEX) { ++ if (u->ladspa_module != PA_INVALID_INDEX) { ++ pa_module_unload_request_by_index(m->core, u->ladspa_module, true); ++ u->ladspa_module = PA_INVALID_INDEX; ++ pa_log_warn("Orphaned ladspa-sink removal requested"); ++ } ++ } else { ++ if (u->ladspa_module == PA_INVALID_INDEX) { ++ sink = pa_idxset_get_by_index(m->core->sinks, u->bluedio_sink); ++ load_ladspa_sink(m->core, sink, u); ++ } ++ } ++ ++ pa_modargs_free(ma); ++ ++ return 0; ++} ++ ++void pa__done(pa_module*m) { ++ struct userdata *u; ++ ++ pa_assert(m); ++ ++ if (!(u = m->userdata)) ++ return; ++ ++ if (u->put_slot) ++ pa_hook_slot_free(u->put_slot); ++ if (u->unlink_slot) ++ pa_hook_slot_free(u->unlink_slot); ++ if (u->ladspa_module != PA_INVALID_INDEX && m->core->state != PA_CORE_SHUTDOWN) ++ pa_module_unload_request_by_index(m->core, u->ladspa_module, true); ++ ++ pa_xfree(u->control); ++ pa_xfree(u->sample); ++ pa_xfree(u); ++} +diff --git a/src/modules/meson.build b/src/modules/meson.build +index 92d5871f9..2abf255d5 100644 +--- a/src/modules/meson.build ++++ b/src/modules/meson.build +@@ -113,6 +113,7 @@ if get_option('bluez5') + [ 'module-bluetooth-policy', 'bluetooth/module-bluetooth-policy.c', [], [], [dbus_dep] ], + [ 'module-bluez5-device', 'bluetooth/module-bluez5-device.c', [], [], [], libbluez5_util ], + [ 'module-bluez5-discover', 'bluetooth/module-bluez5-discover.c', [], [], [dbus_dep], libbluez5_util ], ++ [ 'module-bluedio-fixup', 'bluetooth/module-bluedio-fixup.c', [], [], [], libbluez5_util ], + ] + endif + +-- +2.25.0 + diff --git a/PKGBUILD b/PKGBUILD new file mode 100644 index 000000000000..61d6f9ee843a --- /dev/null +++ b/PKGBUILD @@ -0,0 +1,57 @@ +# Maintainer: Jan Alexander Steffens (heftig) <jan.steffens@gmail.com> +# Contributor: Daniel J Griffiths <ghost1227@archlinux.us> +# Contributor: Corrado Primier <bardo@aur.archlinux.org> +# Contributor: William Rea <sillywilly@gmail.com> + +pkgbase=pulseaudio-bluedio +pkgname=pulseaudio-bluedio +pkgdesc="Fixup Pulseaudio module for my Bluedio headset" +pkgver=13.0 +pkgrel=3 +arch=(x86_64) +url="https://www.freedesktop.org/wiki/Software/PulseAudio/" +license=(GPL) +makedepends=(libasyncns libcap attr libxtst libsm libsndfile rtkit libsoxr + speexdsp tdb systemd dbus avahi bluez bluez-libs jack2 sbc + lirc openssl fftw orc gtk3 webrtc-audio-processing check git meson + xmltoman) +_commit=200618b32f0964a479d69c9b6e5073e6931c370a # tags/v13.0^0 +source=("git+https://gitlab.freedesktop.org/pulseaudio/pulseaudio.git#commit=$_commit" + 0001-bluetooth-new-module-bluedio-fixup.patch) +sha256sums=('SKIP' + 'bc83a8075decebf7b18efd165593ad0f658dd97881c21804dae3699c1df8bc2f') + +pkgver() { + cd pulseaudio + git describe --tags | sed 's/^v//;s/-/+/g' +} + +prepare() { + cd pulseaudio + + # Freeze version before patching + ./git-version-gen doesnt-exist >.tarball-version + + git apply -3 ../0001-bluetooth-new-module-bluedio-fixup.patch +} + +build() { + arch-meson pulseaudio build \ + -D gcov=false \ + -D pulsedsp-location='/usr/\$LIB/pulseaudio' \ + -D udevrulesdir=/usr/lib/udev/rules.d + ninja -C build src/modules/module-bluedio-fixup.so +} + +package_pulseaudio-bluedio() { + local pulsever=$(cd pulseaudio; ./git-version-gen .tarball-version) + while [[ $pulsever = *.*.* ]]; do + pulsever=${pulsever%.*} + done + pulsever=${pulsever%%-*} + + install -s -D -t "${pkgdir}/usr/lib/pulse-${pulsever}/modules" build/src/modules/module-bluedio-fixup.so + +} + +# vim:set sw=2 et: |