Re: [pulseaudio-discuss] Frequency autoswitching with E-MU 0404 USB

2019-04-22 Thread Conrad Jones
This is interesting, are you requiring to switch the profile only on the
white edition ?

I ask because I have a box full of these in storage, it would be
interesting if there is a difference if there is different firmware at play
on the device

On Mon, Apr 22, 2019 at 11:46 PM edio  wrote:

> I was looking for clues here and there, until I stumbled on this gist:
>
> https://github.com/taravasya/taravasya_snips/commit/a99bc93365aafbdc8a735fe24a9f4107f857144e#diff-e2c3b1bfad69cc1fb921d18bdb7c2bd5
>
> That gave me an idea, that perhaps switching profile from Duplex to
> Output would solve my issue.
>
> Indeed it did! I switched profile to Analog Stereo Output (instead of
> Duplex) and frequency autoswitching started working.
>
> Would you consider this a bug either in PulseAudio or Linux kernel?
>
> Thanks
>
> On 4/22/19 12:07 PM, edio wrote:
> > Hello,
> > I'm having trouble with sampling frequency autoswitching when using
> > E-MU 0404 USB soundcard.
> >
> > This case is rather strange.
> >
> > I have 2 E-MU 0404 USB soundcards: regular one (model EM8761) and
> > white edition (model EM8762).
> >
> > Autoswitching in PulseAudio works with the regular one but not with
> > the white edition. However in ALSA both sound cards work as expected.
> >
> > Here's dmesg output when I connect both:
> >
> > 
> > [  842.304339] usb 1-1.2: new high-speed USB device number 6 using dwc2
> > [  842.446437] usb 1-1.2: New USB device found, idVendor=041e,
> > idProduct=3f04, bcdDevice= 1.00
> > [  842.466211] usb 1-1.2: New USB device strings: Mfr=1, Product=2,
> > SerialNumber=3
> > [  842.479357] usb 1-1.2: Product: E-MU 0404 | USB
> > [  842.489520] usb 1-1.2: Manufacturer: E-MU Systems, Inc.
> > [  842.500246] usb 1-1.2: SerialNumber:
> > E-MU-09-3F04-07D90916-0914D-8761T2A
> > ...
> > [  901.444396] usb 1-1.2: new high-speed USB device number 7 using dwc2
> > [  901.586367] usb 1-1.2: New USB device found, idVendor=041e,
> > idProduct=3f04, bcdDevice= 1.00
> > [  901.603744] usb 1-1.2: New USB device strings: Mfr=1, Product=2,
> > SerialNumber=3
> > [  901.616060] usb 1-1.2: Product: E-MU 0404 | USB
> > [  901.625459] usb 1-1.2: Manufacturer: E-MU Systems, Inc.
> > [  901.635506] usb 1-1.2: SerialNumber:
> > E-MU-43-3F04-07D70109-0964D-STATION 01
> > 
> >
> > From this both seem to be the same: vendor and product IDs are the
> > same. Yet somehow, PulseAudio works differently for them. Is there
> > maybe some sound card specific code in PulseAudio?
> >
> > Would appreciate any hints and suggestions on how to debug the issue.
> >
> > Thanks
> >
> ___
> pulseaudio-discuss mailing list
> pulseaudio-discuss@lists.freedesktop.org
> https://lists.freedesktop.org/mailman/listinfo/pulseaudio-discuss
___
pulseaudio-discuss mailing list
pulseaudio-discuss@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/pulseaudio-discuss

Re: [pulseaudio-discuss] Frequency autoswitching with E-MU 0404 USB

2019-04-22 Thread edio

I was looking for clues here and there, until I stumbled on this gist:
https://github.com/taravasya/taravasya_snips/commit/a99bc93365aafbdc8a735fe24a9f4107f857144e#diff-e2c3b1bfad69cc1fb921d18bdb7c2bd5

That gave me an idea, that perhaps switching profile from Duplex to 
Output would solve my issue.


Indeed it did! I switched profile to Analog Stereo Output (instead of 
Duplex) and frequency autoswitching started working.


Would you consider this a bug either in PulseAudio or Linux kernel?

Thanks

On 4/22/19 12:07 PM, edio wrote:

Hello,
I'm having trouble with sampling frequency autoswitching when using 
E-MU 0404 USB soundcard.


This case is rather strange.

I have 2 E-MU 0404 USB soundcards: regular one (model EM8761) and 
white edition (model EM8762).


Autoswitching in PulseAudio works with the regular one but not with 
the white edition. However in ALSA both sound cards work as expected.


Here's dmesg output when I connect both:


[  842.304339] usb 1-1.2: new high-speed USB device number 6 using dwc2
[  842.446437] usb 1-1.2: New USB device found, idVendor=041e, 
idProduct=3f04, bcdDevice= 1.00
[  842.466211] usb 1-1.2: New USB device strings: Mfr=1, Product=2, 
SerialNumber=3

[  842.479357] usb 1-1.2: Product: E-MU 0404 | USB
[  842.489520] usb 1-1.2: Manufacturer: E-MU Systems, Inc.
[  842.500246] usb 1-1.2: SerialNumber: 
E-MU-09-3F04-07D90916-0914D-8761T2A

...
[  901.444396] usb 1-1.2: new high-speed USB device number 7 using dwc2
[  901.586367] usb 1-1.2: New USB device found, idVendor=041e, 
idProduct=3f04, bcdDevice= 1.00
[  901.603744] usb 1-1.2: New USB device strings: Mfr=1, Product=2, 
SerialNumber=3

[  901.616060] usb 1-1.2: Product: E-MU 0404 | USB
[  901.625459] usb 1-1.2: Manufacturer: E-MU Systems, Inc.
[  901.635506] usb 1-1.2: SerialNumber: 
E-MU-43-3F04-07D70109-0964D-STATION 01



From this both seem to be the same: vendor and product IDs are the 
same. Yet somehow, PulseAudio works differently for them. Is there 
maybe some sound card specific code in PulseAudio?


Would appreciate any hints and suggestions on how to debug the issue.

Thanks


___
pulseaudio-discuss mailing list
pulseaudio-discuss@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/pulseaudio-discuss

[pulseaudio-discuss] Frequency autoswitching with E-MU 0404 USB

2019-04-22 Thread edio

Hello,
I'm having trouble with sampling frequency autoswitching when using E-MU 
0404 USB soundcard.


This case is rather strange.

I have 2 E-MU 0404 USB soundcards: regular one (model EM8761) and white 
edition (model EM8762).


Autoswitching in PulseAudio works with the regular one but not with the 
white edition. However in ALSA both sound cards work as expected.


Here's dmesg output when I connect both:


[  842.304339] usb 1-1.2: new high-speed USB device number 6 using dwc2
[  842.446437] usb 1-1.2: New USB device found, idVendor=041e, 
idProduct=3f04, bcdDevice= 1.00
[  842.466211] usb 1-1.2: New USB device strings: Mfr=1, Product=2, 
SerialNumber=3

[  842.479357] usb 1-1.2: Product: E-MU 0404 | USB
[  842.489520] usb 1-1.2: Manufacturer: E-MU Systems, Inc.
[  842.500246] usb 1-1.2: SerialNumber: E-MU-09-3F04-07D90916-0914D-8761T2A
...
[  901.444396] usb 1-1.2: new high-speed USB device number 7 using dwc2
[  901.586367] usb 1-1.2: New USB device found, idVendor=041e, 
idProduct=3f04, bcdDevice= 1.00
[  901.603744] usb 1-1.2: New USB device strings: Mfr=1, Product=2, 
SerialNumber=3

[  901.616060] usb 1-1.2: Product: E-MU 0404 | USB
[  901.625459] usb 1-1.2: Manufacturer: E-MU Systems, Inc.
[  901.635506] usb 1-1.2: SerialNumber: 
E-MU-43-3F04-07D70109-0964D-STATION 01



From this both seem to be the same: vendor and product IDs are the 
same. Yet somehow, PulseAudio works differently for them. Is there maybe 
some sound card specific code in PulseAudio?


Would appreciate any hints and suggestions on how to debug the issue.

Thanks

___
pulseaudio-discuss mailing list
pulseaudio-discuss@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/pulseaudio-discuss

[pulseaudio-discuss] [PATCH v9 6/8] bluetooth: Implement A2DP codec switching and backchannel support

2019-04-22 Thread Pali Rohár
Some A2DP codecs (like FastStream or aptX Low Latency) are bi-directional
and can be used for both music playback and audio call. This patch
implements usage of backchannel if A2DP codec provided by pulseaudio API
supports it.

A2DP codec switching needs new version of bluez as older version does not
provide needed DBus API.

Pulseaudio use for each A2DP codec separate pulseaudio profile, therefore
codec switching is implemented via changing pulseaudio profile and
currently used A2DP codec is visible in pulseaudio profile.

Getting list of supported codecs by remote device is supported only by new
version of bluez daemon.

If old version is detected then profile is created for every codec
supported by pulseaudio (therefore also codecs unavailable by remote
endpoint). Old version of bluez daemon does not support profile switching,
so unavailable profile codecs are harmless.
---
 src/modules/bluetooth/bluez5-util.c| 476 +++--
 src/modules/bluetooth/bluez5-util.h|  39 +-
 src/modules/bluetooth/module-bluez5-device.c   | 409 ++---
 src/modules/bluetooth/module-bluez5-discover.c |   3 +-
 4 files changed, 764 insertions(+), 163 deletions(-)

diff --git a/src/modules/bluetooth/bluez5-util.c 
b/src/modules/bluetooth/bluez5-util.c
index 3c5a000c0..4e4ab0cb8 100644
--- a/src/modules/bluetooth/bluez5-util.c
+++ b/src/modules/bluetooth/bluez5-util.c
@@ -171,11 +171,13 @@ static const char 
*transport_state_to_string(pa_bluetooth_transport_state_t stat
 }
 
 static bool device_supports_profile(pa_bluetooth_device *device, 
pa_bluetooth_profile_t profile) {
+const pa_a2dp_codec_capabilities *a2dp_codec_capabilities;
+const pa_a2dp_codec *a2dp_codec;
+bool is_a2dp_sink;
+pa_hashmap *endpoints;
+void *state;
+
 switch (profile) {
-case PA_BLUETOOTH_PROFILE_A2DP_SINK:
-return !!pa_hashmap_get(device->uuids, 
PA_BLUETOOTH_UUID_A2DP_SINK);
-case PA_BLUETOOTH_PROFILE_A2DP_SOURCE:
-return !!pa_hashmap_get(device->uuids, 
PA_BLUETOOTH_UUID_A2DP_SOURCE);
 case PA_BLUETOOTH_PROFILE_HEADSET_HEAD_UNIT:
 return !!pa_hashmap_get(device->uuids, PA_BLUETOOTH_UUID_HSP_HS)
 || !!pa_hashmap_get(device->uuids, 
PA_BLUETOOTH_UUID_HSP_HS_ALT)
@@ -184,10 +186,33 @@ static bool device_supports_profile(pa_bluetooth_device 
*device, pa_bluetooth_pr
 return !!pa_hashmap_get(device->uuids, PA_BLUETOOTH_UUID_HSP_AG)
 || !!pa_hashmap_get(device->uuids, PA_BLUETOOTH_UUID_HFP_AG);
 case PA_BLUETOOTH_PROFILE_OFF:
-pa_assert_not_reached();
+return true;
+default:
+break;
+}
+
+a2dp_codec = pa_bluetooth_profile_to_a2dp_codec(profile);
+is_a2dp_sink = pa_bluetooth_profile_is_a2dp_sink(profile);
+
+if (is_a2dp_sink && !pa_hashmap_get(device->uuids, 
PA_BLUETOOTH_UUID_A2DP_SINK))
+return false;
+else if (!is_a2dp_sink && !pa_hashmap_get(device->uuids, 
PA_BLUETOOTH_UUID_A2DP_SOURCE))
+return false;
+
+if (is_a2dp_sink)
+endpoints = pa_hashmap_get(device->a2dp_sink_endpoints, 
_codec->id);
+else
+endpoints = pa_hashmap_get(device->a2dp_source_endpoints, 
_codec->id);
+
+if (!endpoints)
+return false;
+
+PA_HASHMAP_FOREACH(a2dp_codec_capabilities, endpoints, state) {
+if 
(a2dp_codec->can_accept_capabilities(a2dp_codec_capabilities->buffer, 
a2dp_codec_capabilities->size, is_a2dp_sink))
+return true;
 }
 
-pa_assert_not_reached();
+return false;
 }
 
 static bool device_is_profile_connected(pa_bluetooth_device *device, 
pa_bluetooth_profile_t profile) {
@@ -199,9 +224,11 @@ static bool 
device_is_profile_connected(pa_bluetooth_device *device, pa_bluetoot
 
 static unsigned device_count_disconnected_profiles(pa_bluetooth_device 
*device) {
 pa_bluetooth_profile_t profile;
+unsigned bluetooth_profile_count;
 unsigned count = 0;
 
-for (profile = 0; profile < PA_BLUETOOTH_PROFILE_COUNT; profile++) {
+bluetooth_profile_count = pa_bluetooth_profile_count();
+for (profile = 0; profile < bluetooth_profile_count; profile++) {
 if (!device_supports_profile(device, profile))
 continue;
 
@@ -224,6 +251,7 @@ static void wait_for_profiles_cb(pa_mainloop_api *api, 
pa_time_event* event, con
 pa_bluetooth_device *device = userdata;
 pa_strbuf *buf;
 pa_bluetooth_profile_t profile;
+unsigned bluetooth_profile_count;
 bool first = true;
 char *profiles_str;
 
@@ -231,7 +259,8 @@ static void wait_for_profiles_cb(pa_mainloop_api *api, 
pa_time_event* event, con
 
 buf = pa_strbuf_new();
 
-for (profile = 0; profile < PA_BLUETOOTH_PROFILE_COUNT; profile++) {
+bluetooth_profile_count = pa_bluetooth_profile_count();
+for (profile = 0; profile < bluetooth_profile_count; profile++) {
 if (device_is_profile_connected(device, profile))
 

[pulseaudio-discuss] [PATCH v9 2/8] bluetooth: Add A2DP aptX and aptX HD codecs support

2019-04-22 Thread Pali Rohár
This patch provides support for aptX and aptX HD codecs in bluetooth A2DP
profile. It uses open source LGPLv2.1+ licensed libopenaptx library which
can be found at https://github.com/pali/libopenaptx.

aptX for s24 stereo samples provides fixed 6:1 compression ratio and
bitrate 352.8 kbit/s, aptX HD provides fixed 4:1 compression ratio and
bitrate 529.2 kbit/s.

According to soundexpert research, aptX codec used in bluetooth A2DP is no
better than SBC High Quality settings. And you cannot hear difference
between aptX and SBC High Quality, aptX is just a copper-less overpriced
audio cable.

aptX HD is high-bitrate version of aptX. It has clearly noticeable increase
in sound quality (not dramatic though taking into account the increase in
bitrate).

http://soundexpert.org/news/-/blogs/audio-quality-of-bluetooth-aptx
---
 configure.ac|  36 +++
 src/Makefile.am |   6 +
 src/modules/bluetooth/a2dp-codec-aptx.c | 400 
 src/modules/bluetooth/a2dp-codec-util.c |   8 +
 4 files changed, 450 insertions(+)
 create mode 100644 src/modules/bluetooth/a2dp-codec-aptx.c

diff --git a/configure.ac b/configure.ac
index b44ed1595..de63d7aa7 100644
--- a/configure.ac
+++ b/configure.ac
@@ -1106,6 +1106,40 @@ AC_SUBST(HAVE_BLUEZ_5_NATIVE_HEADSET)
 AM_CONDITIONAL([HAVE_BLUEZ_5_NATIVE_HEADSET], [test 
"x$HAVE_BLUEZ_5_NATIVE_HEADSET" = x1])
 AS_IF([test "x$HAVE_BLUEZ_5_NATIVE_HEADSET" = "x1"], 
AC_DEFINE([HAVE_BLUEZ_5_NATIVE_HEADSET], 1, [Bluez 5 native headset backend 
enabled]))
 
+ Bluetooth A2DP aptX codec (optional) ###
+
+AC_ARG_ENABLE([aptx],
+AS_HELP_STRING([--disable-aptx],[Disable optional bluetooth A2DP aptX and 
aptX HD codecs support (via libopenaptx)]))
+AC_ARG_VAR([OPENAPTX_CPPFLAGS], [C preprocessor flags for openaptx])
+AC_ARG_VAR([OPENAPTX_LDFLAGS], [linker flags for openaptx])
+
+CPPFLAGS_SAVE="$CPPFLAGS"
+LDFLAGS_SAVE="$LDFLAGS"
+LIBS_SAVE="$LIBS"
+
+CPPFLAGS="$CPPFLAGS $OPENAPTX_CPPFLAGS"
+LDFLAGS="$LDFLAGS $OPENAPTX_LDFLAGS"
+
+AS_IF([test "x$HAVE_BLUEZ_5" = "x1" && test "x$enable_aptx" != "xno"],
+[AC_CHECK_HEADER([openaptx.h],
+[AC_SEARCH_LIBS([aptx_init], [openaptx],
+[HAVE_OPENAPTX=1; AS_IF([test "x$ac_cv_search_aptx_init" != "xnone 
required"], [OPENAPTX_LDFLAGS="$OPENAPTX_LDFLAGS $ac_cv_search_aptx_init"])],
+[HAVE_OPENAPTX=0])],
+[HAVE_OPENAPTX=0])])
+
+CPPFLAGS="$CPPFLAGS_SAVE"
+LDFLAGS="$LDFLAGS_SAVE"
+LIBS="$LIBS_SAVE"
+
+AS_IF([test "x$HAVE_BLUEZ_5" = "x1" && test "x$enable_aptx" = "xyes" && test 
"x$HAVE_OPENAPTX" = "x0"],
+[AC_MSG_ERROR([*** libopenaptx from https://github.com/pali/libopenaptx 
not found])])
+
+AC_SUBST(OPENAPTX_CPPFLAGS)
+AC_SUBST(OPENAPTX_LDFLAGS)
+AC_SUBST(HAVE_OPENAPTX)
+AM_CONDITIONAL([HAVE_OPENAPTX], [test "x$HAVE_OPENAPTX" = "x1"])
+AS_IF([test "x$HAVE_OPENAPTX" = "x1"], AC_DEFINE([HAVE_OPENAPTX], 1, [Have 
openaptx codec library]))
+
  UDEV support (optional) 
 
 AC_ARG_ENABLE([udev],
@@ -1591,6 +1625,7 @@ AS_IF([test "x$HAVE_SYSTEMD_JOURNAL" = "x1"], 
ENABLE_SYSTEMD_JOURNAL=yes, ENABLE
 AS_IF([test "x$HAVE_BLUEZ_5" = "x1"], ENABLE_BLUEZ_5=yes, ENABLE_BLUEZ_5=no)
 AS_IF([test "x$HAVE_BLUEZ_5_OFONO_HEADSET" = "x1"], 
ENABLE_BLUEZ_5_OFONO_HEADSET=yes, ENABLE_BLUEZ_5_OFONO_HEADSET=no)
 AS_IF([test "x$HAVE_BLUEZ_5_NATIVE_HEADSET" = "x1"], 
ENABLE_BLUEZ_5_NATIVE_HEADSET=yes, ENABLE_BLUEZ_5_NATIVE_HEADSET=no)
+AS_IF([test "x$HAVE_OPENAPTX" = "x1"], ENABLE_APTX=yes, ENABLE_APTX=no)
 AS_IF([test "x$HAVE_HAL_COMPAT" = "x1"], ENABLE_HAL_COMPAT=yes, 
ENABLE_HAL_COMPAT=no)
 AS_IF([test "x$HAVE_TCPWRAP" = "x1"], ENABLE_TCPWRAP=yes, ENABLE_TCPWRAP=no)
 AS_IF([test "x$HAVE_LIBSAMPLERATE" = "x1"], ENABLE_LIBSAMPLERATE="yes 
(DEPRECATED)", ENABLE_LIBSAMPLERATE=no)
@@ -1649,6 +1684,7 @@ echo "
   Enable BlueZ 5:  ${ENABLE_BLUEZ_5}
 Enable ofono headsets: ${ENABLE_BLUEZ_5_OFONO_HEADSET}
 Enable native headsets:${ENABLE_BLUEZ_5_NATIVE_HEADSET}
+Enable aptX+aptXHD codecs: ${ENABLE_APTX}
 Enable udev:   ${ENABLE_UDEV}
   Enable HAL->udev compat: ${ENABLE_HAL_COMPAT}
 Enable systemd
diff --git a/src/Makefile.am b/src/Makefile.am
index 5ef870e32..a303578bb 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -2154,6 +2154,12 @@ libbluez5_util_la_SOURCES += 
modules/bluetooth/a2dp-codec-sbc.c
 libbluez5_util_la_LIBADD += $(SBC_LIBS)
 libbluez5_util_la_CFLAGS += $(SBC_CFLAGS)
 
+if HAVE_OPENAPTX
+libbluez5_util_la_SOURCES += modules/bluetooth/a2dp-codec-aptx.c
+libbluez5_util_la_CPPFLAGS += $(OPENAPTX_CPPFLAGS)
+libbluez5_util_la_LDFLAGS += $(OPENAPTX_LDFLAGS)
+endif
+
 module_bluez5_discover_la_SOURCES = modules/bluetooth/module-bluez5-discover.c
 module_bluez5_discover_la_LDFLAGS = $(MODULE_LDFLAGS)
 module_bluez5_discover_la_LIBADD = $(MODULE_LIBADD) $(DBUS_LIBS) 
libbluez5-util.la
diff --git a/src/modules/bluetooth/a2dp-codec-aptx.c 

[pulseaudio-discuss] [PATCH v9 7/8] bluetooth: policy: Treat bi-directional A2DP profiles as suitable for VOIP

2019-04-22 Thread Pali Rohár
Previously module-bluetooth-policy was switching from A2DP to HSP profile
when VOIP application started recording of source. Now it switch to profile
with the highest priority which has both sink and source. In most cases it
is HSP profile, but it can be also bi-directional A2DP profile (e.g.
FastStream codec) as it has better audio quality.
---
 src/modules/bluetooth/module-bluetooth-policy.c | 123 
 1 file changed, 62 insertions(+), 61 deletions(-)

diff --git a/src/modules/bluetooth/module-bluetooth-policy.c 
b/src/modules/bluetooth/module-bluetooth-policy.c
index 04313aa84..9652a91fe 100644
--- a/src/modules/bluetooth/module-bluetooth-policy.c
+++ b/src/modules/bluetooth/module-bluetooth-policy.c
@@ -59,7 +59,12 @@ struct userdata {
 pa_hook_slot *card_init_profile_slot;
 pa_hook_slot *card_unlink_slot;
 pa_hook_slot *profile_available_changed_slot;
-pa_hashmap *will_need_revert_card_map;
+pa_hashmap *profile_switch_map;
+};
+
+struct profile_switch {
+const char *from_profile;
+const char *to_profile;
 };
 
 /* When a source is created, loopback it to default sink */
@@ -142,43 +147,57 @@ static pa_hook_result_t sink_put_hook_callback(pa_core 
*c, pa_sink *sink, void *
 return PA_HOOK_OK;
 }
 
-static void card_set_profile(struct userdata *u, pa_card *card, bool 
revert_to_a2dp)
-{
+static void card_set_profile(struct userdata *u, pa_card *card, const char 
*revert_to_profile_name) {
+pa_card_profile *iter_profile;
 pa_card_profile *profile;
+struct profile_switch *ps;
+char *old_profile_name;
 void *state;
 
-/* Find available profile and activate it */
-PA_HASHMAP_FOREACH(profile, card->profiles, state) {
-if (profile->available == PA_AVAILABLE_NO)
-continue;
-
-/* Check for correct profile based on revert_to_a2dp */
-if (revert_to_a2dp) {
-if (!pa_startswith(profile->name, "a2dp_sink"))
+if (revert_to_profile_name) {
+profile = pa_hashmap_get(card->profiles, revert_to_profile_name);
+} else {
+/* Find highest priority profile with both sink and source */
+profile = NULL;
+PA_HASHMAP_FOREACH(iter_profile, card->profiles, state) {
+if (iter_profile->available == PA_AVAILABLE_NO)
 continue;
-} else {
-if (!pa_streq(profile->name, "headset_head_unit"))
+if (iter_profile->n_sources == 0 || iter_profile->n_sinks == 0)
 continue;
+if (!profile || profile->priority < iter_profile->priority)
+profile = iter_profile;
 }
+}
 
-pa_log_debug("Setting card '%s' to profile '%s'", card->name, 
profile->name);
+if (!profile) {
+pa_log_warn("Could not find any suitable profile for card '%s'", 
card->name);
+return;
+}
 
-if (pa_card_set_profile(card, profile, false) != 0) {
-pa_log_warn("Could not set profile '%s'", profile->name);
-continue;
-}
+old_profile_name = card->active_profile->name;
+
+pa_log_debug("Setting card '%s' from profile '%s' to profile '%s'", 
card->name, old_profile_name, profile->name);
 
-/* When we are not in revert_to_a2dp phase flag this card for 
will_need_revert */
-if (!revert_to_a2dp)
-pa_hashmap_put(u->will_need_revert_card_map, card, 
PA_INT_TO_PTR(1));
+if (pa_card_set_profile(card, profile, false) != 0) {
+pa_log_warn("Could not set profile '%s'", profile->name);
+return;
+}
 
-break;
+/* When not reverting, store data for future reverting */
+if (!revert_to_profile_name) {
+ps = pa_xnew0(struct profile_switch, 1);
+ps->from_profile = old_profile_name;
+ps->to_profile = profile->name;
+pa_hashmap_put(u->profile_switch_map, card, ps);
 }
 }
 
 /* Switch profile for one card */
-static void switch_profile(pa_card *card, bool revert_to_a2dp, void *userdata) 
{
+static void switch_profile(pa_card *card, bool revert, void *userdata) {
 struct userdata *u = userdata;
+struct profile_switch *ps;
+const char *from_profile;
+const char *to_profile;
 const char *s;
 
 /* Only consider bluetooth cards */
@@ -186,29 +205,25 @@ static void switch_profile(pa_card *card, bool 
revert_to_a2dp, void *userdata) {
 if (!s || !pa_streq(s, "bluetooth"))
 return;
 
-if (revert_to_a2dp) {
-/* In revert_to_a2dp phase only consider cards with will_need_revert 
flag and remove it */
-if (!pa_hashmap_remove(u->will_need_revert_card_map, card))
+if (revert) {
+/* In revert phase only consider cards which switched profile */
+if (!(ps = pa_hashmap_remove(u->profile_switch_map, card)))
 return;
 
-/* Skip card if does not have active hsp profile */
-if (!pa_streq(card->active_profile->name, "headset_head_unit"))
-return;
+

[pulseaudio-discuss] [PATCH v9 8/8] bluetooth: policy: Set initial A2DP profile which bluez already activated

2019-04-22 Thread Pali Rohár
Bluez and remote device decide which A2DP codec would use. Use this
selected A2DP codec as initial profile in pulseaudio.

In most cases it is either last used codec or codec with higher priority by
defined by remote device.
---
 src/modules/bluetooth/module-bluetooth-policy.c | 37 ++---
 1 file changed, 33 insertions(+), 4 deletions(-)

diff --git a/src/modules/bluetooth/module-bluetooth-policy.c 
b/src/modules/bluetooth/module-bluetooth-policy.c
index 9652a91fe..a0be36f1d 100644
--- a/src/modules/bluetooth/module-bluetooth-policy.c
+++ b/src/modules/bluetooth/module-bluetooth-policy.c
@@ -306,15 +306,44 @@ static pa_hook_result_t 
source_output_unlink_hook_callback(pa_core *c, pa_source
 }
 
 static pa_hook_result_t card_init_profile_hook_callback(pa_core *c, pa_card 
*card, void *userdata) {
+pa_card_profile *iter_profile;
+pa_card_profile *profile;
+void *state;
+
 pa_assert(c);
 pa_assert(card);
 
-/* If there are not some source outputs do nothing */
-if (source_output_count(c, userdata) == 0)
+/* If there are some source outputs set initial profile to some with 
source */
+if (source_output_count(c, userdata) > 0) {
+pa_log_debug("There is some source output, trying to choose initial 
profile with source for card %s", card->name);
+switch_profile(card, false, userdata);
 return PA_HOOK_OK;
+}
+
+/* Otherwise switch to already active A2DP profile chosen by bluez */
+pa_log_debug("Looking for A2DP profile activated by bluez for card %s", 
card->name);
 
-/* Set initial profile to some with source */
-switch_profile(card, false, userdata);
+profile = NULL;
+
+PA_HASHMAP_FOREACH(iter_profile, card->profiles, state) {
+/* Bluez active profiles has "yes" availability */
+if (iter_profile->available != PA_AVAILABLE_YES)
+continue;
+
+/* Ignore non-A2DP profiles */
+if (!pa_startswith(iter_profile->name, "a2dp_"))
+continue;
+
+pa_log_debug("%s is active", iter_profile->name);
+
+if (!profile || iter_profile->priority > profile->priority)
+profile = iter_profile;
+}
+
+if (profile) {
+pa_log_info("Setting active A2DP profile '%s' for card %s", 
profile->name, card->name);
+pa_card_set_profile(card, profile, true);
+}
 
 return PA_HOOK_OK;
 }
-- 
2.11.0

___
pulseaudio-discuss mailing list
pulseaudio-discuss@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/pulseaudio-discuss

[pulseaudio-discuss] [PATCH v9 5/8] bluetooth: policy: Reflect a2dp profile names

2019-04-22 Thread Pali Rohár
In next patches, codec name is appended end the end of a2dp profile names.
---
 src/modules/bluetooth/module-bluetooth-policy.c | 12 ++--
 1 file changed, 6 insertions(+), 6 deletions(-)

diff --git a/src/modules/bluetooth/module-bluetooth-policy.c 
b/src/modules/bluetooth/module-bluetooth-policy.c
index 0a6d59d28..04313aa84 100644
--- a/src/modules/bluetooth/module-bluetooth-policy.c
+++ b/src/modules/bluetooth/module-bluetooth-policy.c
@@ -85,7 +85,7 @@ static pa_hook_result_t source_put_hook_callback(pa_core *c, 
pa_source *source,
 if (!s)
 return PA_HOOK_OK;
 
-if (u->enable_a2dp_source && pa_streq(s, "a2dp_source"))
+if (u->enable_a2dp_source && pa_startswith(s, "a2dp_source"))
 role = "music";
 else if (u->enable_ag && pa_streq(s, "headset_audio_gateway"))
 role = "phone";
@@ -154,7 +154,7 @@ static void card_set_profile(struct userdata *u, pa_card 
*card, bool revert_to_a
 
 /* Check for correct profile based on revert_to_a2dp */
 if (revert_to_a2dp) {
-if (!pa_streq(profile->name, "a2dp_sink"))
+if (!pa_startswith(profile->name, "a2dp_sink"))
 continue;
 } else {
 if (!pa_streq(profile->name, "headset_head_unit"))
@@ -196,11 +196,11 @@ static void switch_profile(pa_card *card, bool 
revert_to_a2dp, void *userdata) {
 return;
 
 /* Skip card if already has active a2dp profile */
-if (pa_streq(card->active_profile->name, "a2dp_sink"))
+if (pa_startswith(card->active_profile->name, "a2dp_sink"))
 return;
 } else {
 /* Skip card if does not have active a2dp profile */
-if (!pa_streq(card->active_profile->name, "a2dp_sink"))
+if (!pa_startswith(card->active_profile->name, "a2dp_sink"))
 return;
 
 /* Skip card if already has active hsp profile */
@@ -307,7 +307,7 @@ static pa_hook_result_t 
card_init_profile_hook_callback(pa_core *c, pa_card *car
 
 /* Ignore card if has already set other initial profile than a2dp */
 if (card->active_profile &&
-!pa_streq(card->active_profile->name, "a2dp_sink"))
+!pa_startswith(card->active_profile->name, "a2dp_sink"))
 return PA_HOOK_OK;
 
 /* Set initial profile to hsp */
@@ -359,7 +359,7 @@ static pa_hook_result_t 
profile_available_hook_callback(pa_core *c, pa_card_prof
 return PA_HOOK_OK;
 
 /* Do not automatically switch profiles for headsets, just in case */
-if (pa_streq(profile->name, "a2dp_sink") || pa_streq(profile->name, 
"headset_head_unit"))
+if (pa_startswith(profile->name, "a2dp_sink") || pa_streq(profile->name, 
"headset_head_unit"))
 return PA_HOOK_OK;
 
 is_active_profile = card->active_profile == profile;
-- 
2.11.0

___
pulseaudio-discuss mailing list
pulseaudio-discuss@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/pulseaudio-discuss

[pulseaudio-discuss] [PATCH v9 1/8] bluetooth: Fix A2DP codec API to provide information about data buffer

2019-04-22 Thread Pali Rohár
Each codec has different compression ratio and own method how to calculate
buffer size of encoded or decoded samples. So change A2DP codec API to
provide this information for module-bluez5-device module and fix
a2dp_prepare_encoder_buffer() and a2dp_prepare_decoder_buffer() functions.

API functions get_read_buffer_size() and get_write_buffer_size() now set
both decoded and encoded buffer sizes. Function reduce_encoder_bitrate()
was changed to not return new buffer size (it was not obvious if buffer
size was for encoded or decoded samples), but caller rather should call
get_write_buffer_size() to get new sizes.
---
 src/modules/bluetooth/a2dp-codec-api.h   | 17 ++--
 src/modules/bluetooth/a2dp-codec-sbc.c   | 25 ++---
 src/modules/bluetooth/module-bluez5-device.c | 41 ++--
 3 files changed, 50 insertions(+), 33 deletions(-)

diff --git a/src/modules/bluetooth/a2dp-codec-api.h 
b/src/modules/bluetooth/a2dp-codec-api.h
index 55bb9ff70..517dc76f1 100644
--- a/src/modules/bluetooth/a2dp-codec-api.h
+++ b/src/modules/bluetooth/a2dp-codec-api.h
@@ -72,15 +72,14 @@ typedef struct pa_a2dp_codec {
 /* Reset internal state of codec info data in codec_info */
 void (*reset)(void *codec_info);
 
-/* Get read block size for codec */
-size_t (*get_read_block_size)(void *codec_info, size_t read_link_mtu);
-/* Get write block size for codec */
-size_t (*get_write_block_size)(void *codec_info, size_t write_link_mtu);
-
-/* Reduce encoder bitrate for codec, returns new write block size or zero
- * if not changed, called when socket is not accepting encoded data fast
- * enough */
-size_t (*reduce_encoder_bitrate)(void *codec_info, size_t write_link_mtu);
+/* Get buffer sizes for read operations */
+void (*get_read_buffer_size)(void *codec_info, size_t read_link_mtu, 
size_t *output_buffer_size, size_t *encoded_buffer_size);
+/* Get buffer sizes for write operations */
+void (*get_write_buffer_size)(void *codec_info, size_t write_link_mtu, 
size_t *input_buffer_size, size_t *encoded_buffer_size);
+
+/* Reduce encoder bitrate for codec, returns non-zero on failure,
+ * called when socket is not accepting encoded data fast enough */
+int (*reduce_encoder_bitrate)(void *codec_info);
 
 /* Encode input_buffer of input_size to output_buffer of output_size,
  * returns size of filled ouput_buffer and set processed to size of
diff --git a/src/modules/bluetooth/a2dp-codec-sbc.c 
b/src/modules/bluetooth/a2dp-codec-sbc.c
index cdc20d7f0..ae71f72e9 100644
--- a/src/modules/bluetooth/a2dp-codec-sbc.c
+++ b/src/modules/bluetooth/a2dp-codec-sbc.c
@@ -423,7 +423,10 @@ static void *init(bool for_encoding, bool for_backchannel, 
const uint8_t *config
 sbc_info->min_bitpool = config->min_bitpool;
 sbc_info->max_bitpool = config->max_bitpool;
 
-/* Set minimum bitpool for source to get the maximum possible block_size */
+/* Set minimum bitpool for source to get the maximum possible buffer size
+ * in get_buffer_size() function. Buffer size is inversely proportional to
+ * frame length which depends on bitpool value. Bitpool is controlled by
+ * other side from range [min_bitpool, max_bitpool]. */
 sbc_info->initial_bitpool = for_encoding ? sbc_info->max_bitpool : 
sbc_info->min_bitpool;
 
 set_params(sbc_info);
@@ -475,20 +478,22 @@ static void reset(void *codec_info) {
 sbc_info->seq_num = 0;
 }
 
-static size_t get_block_size(void *codec_info, size_t link_mtu) {
+static void get_buffer_size(void *codec_info, size_t link_mtu, size_t 
*decoded_buffer_size, size_t *encoded_buffer_size) {
 struct sbc_info *sbc_info = (struct sbc_info *) codec_info;
+size_t rtp_data_size = sizeof(struct rtp_header) + sizeof(struct 
rtp_payload);
+size_t num_of_frames = (link_mtu - rtp_data_size) / sbc_info->frame_length;
 
-return (link_mtu - sizeof(struct rtp_header) - sizeof(struct rtp_payload))
-   / sbc_info->frame_length * sbc_info->codesize;
+*decoded_buffer_size = num_of_frames * sbc_info->codesize;
+*encoded_buffer_size = num_of_frames * sbc_info->frame_length + 
rtp_data_size;
 }
 
-static size_t reduce_encoder_bitrate(void *codec_info, size_t write_link_mtu) {
+static int reduce_encoder_bitrate(void *codec_info) {
 struct sbc_info *sbc_info = (struct sbc_info *) codec_info;
 uint8_t bitpool;
 
 /* Check if bitpool is already at its limit */
 if (sbc_info->sbc.bitpool <= SBC_BITPOOL_DEC_LIMIT)
-return 0;
+return -1;
 
 bitpool = sbc_info->sbc.bitpool - SBC_BITPOOL_DEC_STEP;
 
@@ -496,10 +501,10 @@ static size_t reduce_encoder_bitrate(void *codec_info, 
size_t write_link_mtu) {
 bitpool = SBC_BITPOOL_DEC_LIMIT;
 
 if (sbc_info->sbc.bitpool == bitpool)
-return 0;
+return -1;
 
 set_bitpool(sbc_info, bitpool);
-return get_block_size(codec_info, write_link_mtu);
+return 0;
 }
 
 static 

[pulseaudio-discuss] [PATCH v9 4/8] bluetooth: Add more variants of SBC codec

2019-04-22 Thread Pali Rohár
Specify configuration for Low, Middle, High and Ultra High Quality of SBC
codec. SBC codec in Ultra High Quality has higher quality than aptX.

Automatic Quality mode matches configuration of SBC codec which was used
before this change. Which means that it accept configuration between Low
and High quality.

Current SBC code was extended to allow definitions of arbitrary
configuration variants of SBC codec parameters.
---
 src/modules/bluetooth/a2dp-codec-sbc.c  | 728 ++--
 src/modules/bluetooth/a2dp-codec-util.c |  18 +-
 2 files changed, 611 insertions(+), 135 deletions(-)

diff --git a/src/modules/bluetooth/a2dp-codec-sbc.c 
b/src/modules/bluetooth/a2dp-codec-sbc.c
index ae71f72e9..21116b6ac 100644
--- a/src/modules/bluetooth/a2dp-codec-sbc.c
+++ b/src/modules/bluetooth/a2dp-codec-sbc.c
@@ -36,8 +36,71 @@
 #include "a2dp-codec-api.h"
 #include "rtp.h"
 
-#define SBC_BITPOOL_DEC_LIMIT 32
-#define SBC_BITPOOL_DEC_STEP 5
+/* Below are capabilities tables for different qualities. Order of 
capabilities in tables are from the most preferred to the least preferred. */
+
+#define FIXED_SBC_CAPS(mode, freq, bitpool) { .channel_mode = (mode), 
.frequency = (freq), .min_bitpool = (bitpool), .max_bitpool = (bitpool), 
.allocation_method = SBC_ALLOCATION_LOUDNESS, .subbands = SBC_SUBBANDS_8, 
.block_length = SBC_BLOCK_LENGTH_16 }
+
+/* SBC Low Quality, Joint Stereo is same as FastStream's SBC codec 
configuration, Mono was calculated to match Joint Stereo */
+static a2dp_sbc_t sbc_lq_caps_table[] = {
+FIXED_SBC_CAPS(SBC_CHANNEL_MODE_JOINT_STEREO, SBC_SAMPLING_FREQ_44100, 
29), /* 195.7 kbps */
+FIXED_SBC_CAPS(SBC_CHANNEL_MODE_JOINT_STEREO, SBC_SAMPLING_FREQ_48000, 
29), /* 213   kbps */
+FIXED_SBC_CAPS(SBC_CHANNEL_MODE_MONO, SBC_SAMPLING_FREQ_44100, 
15), /* 104.7 kbps */
+FIXED_SBC_CAPS(SBC_CHANNEL_MODE_MONO, SBC_SAMPLING_FREQ_48000, 
15), /* 114   kbps */
+};
+
+/* SBC Middle Quality, based on A2DP spec: Recommended sets of SBC parameters 
*/
+static a2dp_sbc_t sbc_mq_caps_table[] = {
+FIXED_SBC_CAPS(SBC_CHANNEL_MODE_JOINT_STEREO, SBC_SAMPLING_FREQ_44100, 
SBC_BITPOOL_MQ_JOINT_STEREO_44100), /* bitpool = 35, 228.8 kbps */
+FIXED_SBC_CAPS(SBC_CHANNEL_MODE_JOINT_STEREO, SBC_SAMPLING_FREQ_48000, 
SBC_BITPOOL_MQ_JOINT_STEREO_48000), /* bitpool = 33, 237   kbps */
+FIXED_SBC_CAPS(SBC_CHANNEL_MODE_MONO, SBC_SAMPLING_FREQ_44100, 
SBC_BITPOOL_MQ_MONO_44100), /* bitpool = 19, 126.8 kbps */
+FIXED_SBC_CAPS(SBC_CHANNEL_MODE_MONO, SBC_SAMPLING_FREQ_48000, 
SBC_BITPOOL_MQ_MONO_48000), /* bitpool = 18, 132   kbps */
+};
+
+/* SBC High Quality, based on A2DP spec: Recommended sets of SBC parameters */
+static a2dp_sbc_t sbc_hq_caps_table[] = {
+FIXED_SBC_CAPS(SBC_CHANNEL_MODE_JOINT_STEREO, SBC_SAMPLING_FREQ_44100, 
SBC_BITPOOL_HQ_JOINT_STEREO_44100), /* bitpool = 53, 328   kbps */
+FIXED_SBC_CAPS(SBC_CHANNEL_MODE_JOINT_STEREO, SBC_SAMPLING_FREQ_48000, 
SBC_BITPOOL_HQ_JOINT_STEREO_48000), /* bitpool = 51, 345   kbps */
+FIXED_SBC_CAPS(SBC_CHANNEL_MODE_MONO, SBC_SAMPLING_FREQ_44100, 
SBC_BITPOOL_HQ_MONO_44100), /* bitpool = 31, 192.9 kbps */
+FIXED_SBC_CAPS(SBC_CHANNEL_MODE_MONO, SBC_SAMPLING_FREQ_48000, 
SBC_BITPOOL_HQ_MONO_48000), /* bitpool = 29, 210   kbps */
+};
+
+/* SBC Ultra High Quality, calculated to minimize wasted bytes and to be below 
max possible 512 kbps */
+static a2dp_sbc_t sbc_uhq1_caps_table[] = {
+FIXED_SBC_CAPS(SBC_CHANNEL_MODE_JOINT_STEREO, SBC_SAMPLING_FREQ_44100, 
76), /* 454.8 kbps */
+FIXED_SBC_CAPS(SBC_CHANNEL_MODE_JOINT_STEREO, SBC_SAMPLING_FREQ_48000, 
76), /* 495   kbps */
+FIXED_SBC_CAPS(SBC_CHANNEL_MODE_STEREO,   SBC_SAMPLING_FREQ_44100, 
76), /* 452   kbps */
+FIXED_SBC_CAPS(SBC_CHANNEL_MODE_STEREO,   SBC_SAMPLING_FREQ_48000, 
76), /* 492   kbps */
+};
+static a2dp_sbc_t sbc_uhq2_caps_table[] = {
+FIXED_SBC_CAPS(SBC_CHANNEL_MODE_DUAL_CHANNEL, SBC_SAMPLING_FREQ_44100, 
38), /* 452   kbps */
+FIXED_SBC_CAPS(SBC_CHANNEL_MODE_DUAL_CHANNEL, SBC_SAMPLING_FREQ_48000, 
38), /* 492   kbps */
+FIXED_SBC_CAPS(SBC_CHANNEL_MODE_MONO, SBC_SAMPLING_FREQ_44100, 
37), /* 226   kbps */
+FIXED_SBC_CAPS(SBC_CHANNEL_MODE_MONO, SBC_SAMPLING_FREQ_48000, 
37), /* 246   kbps */
+};
+/* In most cases bluetooth headsets would support only sbc dual channel mode
+ * for 2 channels as they have limited maximal bitpool value to 53.
+ * We need to define it in two tables to disallow invalid combination of
+ * joint stereo with bitpool 38 which is not UHQ. */
+
+#undef FIXED_SBC_CAPS
+
+/* SBC Auto Quality, only one row which allow any possible configuration up to 
common High Quality */
+/* We need to ensure that bitrate is below max possible 512 kbps, therefore 
limit configuration to High Quality */
+static a2dp_sbc_t sbc_auto_caps_table[] = { {
+.channel_mode = SBC_CHANNEL_MODE_MONO | 

[pulseaudio-discuss] [PATCH v9 0/8] Bluetooth A2DP codecs

2019-04-22 Thread Pali Rohár
In this patch series was dropped all patches which are already applied
in git master branch.

There are 2 new patches: "Fix A2DP codec API to provide information about
data buffer" and "policy: Set initial A2DP profile which bluez already
activated".

So with profile/codec switching we can relay on bluez functionality of
remembering the last used codec.

Changes in v9:
 * Fix parsing uuids of remote SEP endpoints
 * Remove wrong assert in FastStream codec
 * Fix logic in SBC codec for checking if two config/capabilities are
   compatible
 * Split SBC UHQ into two sub-codecs - it is needed to ensure that
   remote endpoint does not choose bitpool for dualchannel configuration
   (38) and channel mode for stereo configuration -- which is SBC middle
   quality configuration
 * Simplify encode and decode functions for aptX codec
 * Change FastStream codec code which handles bugs in firmware
 * Fix A2DP codec API to provide information about data buffer
 * Ensure that module-bluez5-discover does not unload
   module-bluez5-device when codec switching operation is in progress
 * Set initial A2DP profile which bluez already activated

Pali Rohár (8):
  bluetooth: Fix A2DP codec API to provide information about data buffer
  bluetooth: Add A2DP aptX and aptX HD codecs support
  bluetooth: Add A2DP FastStream codec support
  bluetooth: Add more variants of SBC codec
  bluetooth: policy: Reflect a2dp profile names
  bluetooth: Implement A2DP codec switching and backchannel support
  bluetooth: policy: Treat bi-directional A2DP profiles as suitable for
VOIP
  bluetooth: policy: Set initial A2DP profile which bluez already
activated

 configure.ac|  36 ++
 src/Makefile.am |   8 +
 src/modules/bluetooth/a2dp-codec-api.h  |  17 +-
 src/modules/bluetooth/a2dp-codec-aptx.c | 400 +
 src/modules/bluetooth/a2dp-codec-faststream.c   | 453 ++
 src/modules/bluetooth/a2dp-codec-sbc.c  | 751 +++-
 src/modules/bluetooth/a2dp-codec-util.c |  26 +-
 src/modules/bluetooth/bluez5-util.c | 476 ++-
 src/modules/bluetooth/bluez5-util.h |  39 +-
 src/modules/bluetooth/module-bluetooth-policy.c | 152 +++--
 src/modules/bluetooth/module-bluez5-device.c| 440 +-
 src/modules/bluetooth/module-bluez5-discover.c  |   3 +-
 12 files changed, 2416 insertions(+), 385 deletions(-)
 create mode 100644 src/modules/bluetooth/a2dp-codec-aptx.c
 create mode 100644 src/modules/bluetooth/a2dp-codec-faststream.c

-- 
2.11.0

___
pulseaudio-discuss mailing list
pulseaudio-discuss@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/pulseaudio-discuss

[pulseaudio-discuss] [PATCH v9 3/8] bluetooth: Add A2DP FastStream codec support

2019-04-22 Thread Pali Rohár
This patch provides support for FastStream codec in bluetooth A2DP profile.
FastStream codec is bi-directional, which means that support both music
playback and microphone voice at the same time.

FastStream codec is just SBC codec with fixed parameters. For playback are
used following parameters: 48.0kHz or 44.1kHz, Blocks 16, Sub-bands 8,
Joint Stereo, Loudness, Bitpool = 29 (data rate = 212kbps, packet size =
(71+1)*3 <= DM5 = 220, with 3 SBC frames). SBC frame size is 71 bytes, but
padded with one zero byte due to rounding to 72 bytes. For microphone are
used following SBC parameters: 16kHz, Mono, Blocks 16, Sub-bands 8,
Loudness, Bitpool = 32 (data rate = 72kbps, packet size = 72*3 <= DM5 =
220, with 3 SBC frames).

So FastStream codec is slightly equivalent to SBC Low Quality settings
(which uses bitpool value 30). But the main benefit of FastStream codec is
support for microphone voice channel for audio calls. Compared to bluetooth
HSP profile (with CVSD codec), it provides better audio quality for both
playback and recording.
---
 src/Makefile.am   |   2 +
 src/modules/bluetooth/a2dp-codec-faststream.c | 453 ++
 src/modules/bluetooth/a2dp-codec-util.c   |   2 +
 3 files changed, 457 insertions(+)
 create mode 100644 src/modules/bluetooth/a2dp-codec-faststream.c

diff --git a/src/Makefile.am b/src/Makefile.am
index a303578bb..a08dd3090 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -2154,6 +2154,8 @@ libbluez5_util_la_SOURCES += 
modules/bluetooth/a2dp-codec-sbc.c
 libbluez5_util_la_LIBADD += $(SBC_LIBS)
 libbluez5_util_la_CFLAGS += $(SBC_CFLAGS)
 
+libbluez5_util_la_SOURCES += modules/bluetooth/a2dp-codec-faststream.c
+
 if HAVE_OPENAPTX
 libbluez5_util_la_SOURCES += modules/bluetooth/a2dp-codec-aptx.c
 libbluez5_util_la_CPPFLAGS += $(OPENAPTX_CPPFLAGS)
diff --git a/src/modules/bluetooth/a2dp-codec-faststream.c 
b/src/modules/bluetooth/a2dp-codec-faststream.c
new file mode 100644
index 0..6a4453e43
--- /dev/null
+++ b/src/modules/bluetooth/a2dp-codec-faststream.c
@@ -0,0 +1,453 @@
+/***
+  This file is part of PulseAudio.
+
+  Copyright 2018-2019 Pali Rohár 
+
+  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, see .
+***/
+
+#ifdef HAVE_CONFIG_H
+#include 
+#endif
+
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+
+#include 
+
+#include "a2dp-codecs.h"
+#include "a2dp-codec-api.h"
+
+struct faststream_info {
+sbc_t sbc;   /* Codec data */
+size_t codesize, frame_length;   /* SBC Codesize, frame_length. We 
simply cache those values here */
+bool is_backchannel;
+uint8_t frequency;
+};
+
+static bool can_accept_capabilities(const uint8_t *capabilities_buffer, 
uint8_t capabilities_size, bool for_encoding) {
+const a2dp_faststream_t *capabilities = (const a2dp_faststream_t *) 
capabilities_buffer;
+
+if (A2DP_GET_VENDOR_ID(capabilities->info) != FASTSTREAM_VENDOR_ID || 
A2DP_GET_CODEC_ID(capabilities->info) != FASTSTREAM_CODEC_ID)
+return false;
+
+if (!(capabilities->direction & FASTSTREAM_DIRECTION_SINK) || 
!(capabilities->direction & FASTSTREAM_DIRECTION_SOURCE))
+return false;
+
+if (!(capabilities->sink_frequency & (FASTSTREAM_SINK_SAMPLING_FREQ_44100 
| FASTSTREAM_SINK_SAMPLING_FREQ_48000)))
+return false;
+
+if (!(capabilities->source_frequency & 
FASTSTREAM_SOURCE_SAMPLING_FREQ_16000))
+return false;
+
+return true;
+}
+
+static const char *choose_remote_endpoint(const pa_hashmap 
*capabilities_hashmap, const pa_sample_spec *default_sample_spec, bool 
for_encoding) {
+const pa_a2dp_codec_capabilities *a2dp_capabilities;
+const char *key;
+void *state;
+
+/* There is no preference, just choose random valid entry */
+PA_HASHMAP_FOREACH_KV(key, a2dp_capabilities, capabilities_hashmap, state) 
{
+if (can_accept_capabilities(a2dp_capabilities->buffer, 
a2dp_capabilities->size, for_encoding))
+return key;
+}
+
+return NULL;
+}
+
+static uint8_t fill_capabilities(uint8_t 
capabilities_buffer[MAX_A2DP_CAPS_SIZE]) {
+a2dp_faststream_t *capabilities = (a2dp_faststream_t *) 
capabilities_buffer;
+
+pa_zero(*capabilities);
+
+capabilities->info = A2DP_SET_VENDOR_ID_CODEC_ID(FASTSTREAM_VENDOR_ID, 
FASTSTREAM_CODEC_ID);
+capabilities->direction = FASTSTREAM_DIRECTION_SINK 

Re: [pulseaudio-discuss] configure a soundcard?

2019-04-22 Thread Matt Zagrabelny
On Mon, Apr 22, 2019 at 3:06 AM Tanu Kaskinen  wrote:

> On Sat, 2019-04-20 at 12:11 -0500, Matt Zagrabelny wrote:
> > Greetings,
> >
> > I'm running Debian Buster and I have a 1/8" audio jack. I need the sink
> to
> > be an analog output to send off to some other device. Things work great,
> > except for when the system reboots, it comes up configured as a digital
> > soundcard:
> >
> > Digital Stereo (IEC958)
> >
> > Here is a diff between a "pactl list" when the computer reboots and when
> > I've configured it to be an analog sink:
> >
> > -Sink #1
> > -   State: SUSPENDED
> > -   Name: alsa_output.pci-_00_14.2.iec958-stereo
> > -   Description: Built-in Audio Digital Stereo (IEC958)
> > +Sink #2
> > +   State: RUNNING
> > +   Name: alsa_output.pci-_00_14.2.analog-stereo
> > +   Description: Built-in Audio Analog Stereo
> >
> > What is the best way to have the configuration saved between reboots?
> >
> > I can provide further info if needed.
> >
> > Thanks for any help!
>

Hey Tanu!

Thanks for the assistance. Below is the output of what you asked for.


> What does "pactl list cards" print, and what does this little script
> print?
>

Card #0
Name: alsa_card.pci-_00_01.1
Driver: module-alsa-card.c
Owner Module: 6
Properties:
alsa.card = "0"
alsa.card_name = "HDA ATI HDMI"
alsa.long_card_name = "HDA ATI HDMI at 0xc0d4 irq 48"
alsa.driver_name = "snd_hda_intel"
device.bus_path = "pci-:00:01.1"
sysfs.path = "/devices/pci:00/:00:01.1/sound/card0"
device.bus = "pci"
device.vendor.id = "1002"
device.vendor.name = "Advanced Micro Devices, Inc.
[AMD/ATI]"
device.product.id = "9840"
device.product.name = "Kabini HDMI/DP Audio"
device.form_factor = "internal"
device.string = "0"
device.description = "Built-in Audio"
module-udev-detect.discovered = "1"
device.icon_name = "audio-card-pci"
Profiles:
output:hdmi-stereo: Digital Stereo (HDMI) Output (sinks: 1,
sources: 0, priority: 5900, available: yes)
output:hdmi-stereo-extra1: Digital Stereo (HDMI 2) Output
(sinks: 1, sources: 0, priority: 5700, available: no)
output:hdmi-surround-extra1: Digital Surround 5.1 (HDMI 2)
Output (sinks: 1, sources: 0, priority: 600, available: no)
output:hdmi-surround71-extra1: Digital Surround 7.1 (HDMI
2) Output (sinks: 1, sources: 0, priority: 600, available: no)
off: Off (sinks: 0, sources: 0, priority: 0, available: yes)
Active Profile: output:hdmi-stereo
Ports:
hdmi-output-0: HDMI / DisplayPort (priority: 5900, latency
offset: 0 usec, available)
Properties:
device.icon_name = "video-display"
Part of profile(s): output:hdmi-stereo
hdmi-output-1: HDMI / DisplayPort 2 (priority: 5800,
latency offset: 0 usec, not available)
Properties:
device.icon_name = "video-display"
Part of profile(s): output:hdmi-stereo-extra1,
output:hdmi-surround-extra1, output:hdmi-surround71-extra1

Card #1
Name: alsa_card.pci-_00_14.2
Driver: module-alsa-card.c
Owner Module: 7
Properties:
alsa.card = "1"
alsa.card_name = "HD-Audio Generic"
alsa.long_card_name = "HD-Audio Generic at 0xc0d44000 irq
16"
alsa.driver_name = "snd_hda_intel"
device.bus_path = "pci-:00:14.2"
sysfs.path = "/devices/pci:00/:00:14.2/sound/card1"
device.bus = "pci"
device.vendor.id = "1022"
device.vendor.name = "Advanced Micro Devices, Inc. [AMD]"
device.product.id = "780d"
device.product.name = "FCH Azalia Controller"
device.form_factor = "internal"
device.string = "1"
device.description = "Built-in Audio"
module-udev-detect.discovered = "1"
device.icon_name = "audio-card-pci"
Profiles:
input:analog-stereo: Analog Stereo Input (sinks: 0,
sources: 1, priority: 65, available: no)
output:analog-stereo: Analog Stereo Output (sinks: 1,
sources: 0, priority: 6500, available: no)
output:analog-stereo+input:analog-stereo: Analog Stereo
Duplex (sinks: 1, sources: 1, priority: 6565, available: no)
output:analog-surround-21: Analog Surround 2.1 Output
(sinks: 1, sources: 0, priority: 1300, available: no)
output:analog-surround-21+input:analog-stereo: Analog
Surround 2.1 Output + Analog 

Re: [pulseaudio-discuss] pulseaudio still running before shutdown

2019-04-22 Thread Christian
Hi Tanu,

thanks a lot for your answer and suggestion.

First of all I have to apologize for getting something wrong.
I wrote:

"I don´t know why I get this message because the shutdown works well
despite that error message. In fact it shuts down really fast."

That´s /incorrect/. In fact it´s like this:  the fact that pulseaudio is still 
running indeed *prevents the shutdown *.
I mixed it up with another project of mine. Sorry about that.

Now to your suggestion:

I looked  up _/etc/pulse/daemon.conf_. 

The "exit-idle-time"-value is currently set like so:

; exit-idle-time = 20

The man-pages say: "Terminate  the  daemon after the last client quit and this 
time in seconds passed."

Well, I think with the semicolon in front that value wasn´t set at all, right?
So I´d have to get rid of the semicolon and then set "exit-idle-time = 0".

Would that be the way to go?

Greetings.
Rosika

P.S.: 
I still don´t understand why there are *two *proceses running before shutdown:

ps -ax | grep -i pulseaudio
 1515 ?Sl 0:00 /usr/bin/pulseaudio --start --log-target=syslog
 2348 ?Sl 0:01 /usr/bin/pulseaudio --start --log-target=syslog
 3820 pts/2S+ 0:00 grep --color=auto -i pulseaudio

___
pulseaudio-discuss mailing list
pulseaudio-discuss@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/pulseaudio-discuss

Re: [pulseaudio-discuss] R: New equalizer module (module-eqpro-sink), some questions

2019-04-22 Thread Georg Chini

On 22.04.19 09:34, Tanu Kaskinen wrote:

On Sat, 2019-04-20 at 11:38 +0200, Georg Chini wrote:

PA uses malloc() in the IO-thread, so are we doing things wrong?
I think using malloc() when a parameter changes is not interfering
with real-time operation because the filter must be reset after
a parameter change anyway.

Where exactly is malloc() used? Sounds like a bug.


Well, for example pa_memblock_new() potentially uses malloc and
this is surely used from the I/O thread. I did not check, but I guess
there are also places where something like pa_xstrdup() or pa_xnew()
is used from the I/O thread. At least I was not aware that there
are any restrictions.
pa_rtpoll_item_new() also potentially uses malloc().

All in all there are many places where malloc() might be used.





Well, after evaluation of the feedback I have been getting so far,
I do not think I will make an attempt to create some plugin-sink.
The existing standards do not fit to what I have in mind and
if I read Alexander right they even intentionally do not support
those features.

Inventing a PA internal standard does not make sense, because
your main argument against implementing the equalizer as a module
was that you did not want to host the DSP code inside PA. If we
did our own standard, new filters would again be bound to PA.

New filters would be specific to PA, yes, but not maintained by us, and
new filters wouldn't have to go through the review process, so there
would still be some benefit in having a PA specific stable plugin API.


I don't understand. What is the difference between having DSP
code in a module or in a filter plugin? After consolidation of
the virtual sinks, there is nearly nothing left in the modules that
would need our attention. It is mostly pure DSP code. I think now
writing a module is the quickest way to get a filter working and
using another plugin format would only complicate things. So
from my point of view, there already is a PA specific plugin format
and I am not going to invent another one. When the messaging
API patches are reviewed, I will write an addition to the virtual
sink library which makes setting parameters easy.

___
pulseaudio-discuss mailing list
pulseaudio-discuss@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/pulseaudio-discuss

Re: [pulseaudio-discuss] [PATCH v8 08/12] bluetooth: Add A2DP FastStream codec support

2019-04-22 Thread Pali Rohár
On Monday 22 April 2019 11:01:01 Tanu Kaskinen wrote:
> On Sat, 2019-04-20 at 11:24 +0200, Pali Rohár wrote:
> > On Saturday 20 April 2019 11:37:56 Tanu Kaskinen wrote:
> > > On Sat, 2019-04-06 at 11:16 +0200, Pali Rohár wrote:
> > > > This patch provides support for FastStream codec in bluetooth A2DP 
> > > > profile.
> > > > FastStream codec is bi-directional, which means that support both music
> > > > playback and microphone voice at the same time.
> > > > 
> > > > FastStream codec is just SBC codec with fixed parameters. For playback 
> > > > are
> > > > used following parameters: 48.0kHz or 44.1kHz, Blocks 16, Sub-bands 8,
> > > > Joint Stereo, Loudness, Bitpool = 29 (data rate = 212kbps, packet size =
> > > > (71+1)*3+4 = 220 = DM5). SBC frame size is 71 bytes, but padded with one
> > > > zero byte due to rounding to 72 bytes. For microphone are used following
> > > > SBC parameters: 16kHz, Mono, Blocks 16, Sub-bands 8, Loudness, Bitpool 
> > > > = 32
> > > > (data rate = 72kbps, packet size = 3*72 + 4 = 220 <= DM5).
> > > > 
> > > > So FastStream codec is slightly equivalent to SBC Low Quality settings
> > > > (which uses bitpool value 30). But the main benefit of FastStream codec 
> > > > is
> > > > support for microphone voice channel for audio calls. Compared to 
> > > > bluetooth
> > > > HSP profile (with CVSD codec), it provides better audio quality for both
> > > > playback and recording.
> > > > ---
> > > >  src/Makefile.am   |   2 +
> > > >  src/modules/bluetooth/a2dp-codec-faststream.c | 436 
> > > > ++
> > > >  src/modules/bluetooth/a2dp-codec-util.c   |   2 +
> > > >  3 files changed, 440 insertions(+)
> > > >  create mode 100644 src/modules/bluetooth/a2dp-codec-faststream.c
> > > > +static bool is_configuration_valid(const uint8_t *config_buffer, 
> > > > uint8_t config_size) {
> > > > +const a2dp_faststream_t *config = (const a2dp_faststream_t *) 
> > > > config_buffer;
> > > > +
> > > > +if (config_size != sizeof(*config)) {
> > > > +pa_log_error("Invalid size of config buffer");
> > > > +return false;
> > > > +}
> > > > +
> > > > +if (A2DP_GET_VENDOR_ID(config->info) != FASTSTREAM_VENDOR_ID || 
> > > > A2DP_GET_CODEC_ID(config->info) != FASTSTREAM_CODEC_ID) {
> > > > +pa_log_error("Invalid vendor codec information in 
> > > > configuration");
> > > > +return false;
> > > > +}
> > > > +
> > > > +if (!(config->direction & FASTSTREAM_DIRECTION_SINK) || 
> > > > !(config->direction & FASTSTREAM_DIRECTION_SOURCE)) {
> > > > +pa_log_error("Invalid direction in configuration");
> > > > +return false;
> > > > +}
> > > > +
> > > > +/* Remote endpoint indicates list of frequences, not just one 
> > > > frequency */
> > > 
> > > Typo: "frequences" -> "frequencies".
> > 
> > Ok, I will fix all occurrences.
> > 
> > > > +if ((config->sink_frequency & 
> > > > ~(FASTSTREAM_SINK_SAMPLING_FREQ_44100|FASTSTREAM_SINK_SAMPLING_FREQ_48000))
> > > >  ||
> > > > +   (!(config->sink_frequency & 
> > > > (FASTSTREAM_SINK_SAMPLING_FREQ_44100|FASTSTREAM_SINK_SAMPLING_FREQ_48000
> > > >  {
> > > 
> > > Do we really need to be this strict?
> > 
> > Yes.
> > 
> > > The final sample rate is decided
> > > by us, so isn't it enough if the config contains just one of the rates
> > > that we support? If the sink supports some other rates, we don't need
> > > to care about that.
> > 
> > Normally in A2DP capabilities buffer device announces combination (list)
> > of supported features and configurations. In A2DP config buffer device
> > usually says one exact configuration which should be used.
> > 
> > But my testing headphones in A2DP FastStream config buffer sometimes
> > says that sink frequency is both 44100|48000 -- which does not make
> > sense. When pulseaudio started sending SBC data with 44.1kHz then sound
> > was obviously bad, there was periodically quiet period (should be for
> > 1.8 us). When pulseaudio started sending SBC data with 48kHz everything
> > was OK. So conclusion is that when headphones says that sampling
> > frequency is both 44100|48000 in config buffer they means it is 48kHz.
> > 
> > In function is_configuration_valid we need to ensure that pulseaudio and
> > remove device negotiate correctly all parameters, including sampling
> > frequency and both sides know how to interpret config buffer.
> > 
> > So strictness is needed to ensure that audio is correctly encoded to SBC
> > codec and then correctly decoded from SBC codec to RAW.
> 
> Ok, so this is a firmware bug. That should be documented as such, and I
> think it would be best to do the firmware bug fixup as a separate step,
> like this:
> 
> static bool is_configuration_valid(...) {
> uint8_t sink_frequency;
> 
> ...
> 
> sink_frequency = config->sink_frequency;
> 
> /* Some headsets are buggy and set both 48 kHz and 44.1 kHz in
>  * the config. In such situation 

Re: [pulseaudio-discuss] pulseaudio still running before shutdown

2019-04-22 Thread Tanu Kaskinen
On Sun, 2019-04-21 at 13:37 +0200, Christian wrote:
> Hi,
> 
> 
> INFO:
> my system: Linux/Lubuntu 18.04.2 LTS, 64 bit
> 
> 
> I shut down my system with the terminal-command "shutdown -H -P +0" or
> "poweroff". But the observed phenomenon may also be seen when
> shutting down from the panel.
> 
> I changed my grub-config from GRUB_CMDLINE_LINUX_DEFAULT="quiet splash"
> to GRUB_CMDLINE_LINUX_DEFAULT="noplymouth" in order to get screen output
> of the logs.
> 
> And here I see an entry reading "failed unmounting /home" (in red).
> After that came some more messages which all were O.K. Everything else
> was in green with an "O.K." in front.
> 
> I don´t know why I get this message because the shutdown works well
> despite that error message. In fact it shuts down really fast.
> 
> So I took alook at journalctl. It shows me the following:
> 
> [...]
> Apr 05 18:16:19 rosika-Lenovo-H520e umount[25556]: umount: /home: das
> Ziel wird gerade benutzt. # /home is currently in use
> Apr 05 18:16:19 rosika-Lenovo-H520e systemd[1]: Unmounting
> /media/rosika/28BC-DAFC...
> Apr 05 18:16:19 rosika-Lenovo-H520e systemd[1]: Unmounting
> /media/rosika/f14a27c2-0b49-4607-94ea-2e56bbf76fe1...
> Apr 05 18:16:19 rosika-Lenovo-H520e systemd[1]: home.mount: Mount
> process exited, code=exited status=32
> Apr 05 18:16:19 rosika-Lenovo-H520e systemd[1]: Failed unmounting /home.
> # <-
> [...]
> 
> I found out that a pulseaudio process seems to be the culprit.
> 
> So I looked up the proceses before shutdown:
> 
> ps -ax | grep -i pulseaudio
>  1515 ?Sl 0:00 /usr/bin/pulseaudio --start --log-target=syslog
>  2348 ?Sl 0:01 /usr/bin/pulseaudio --start --log-target=syslog
>  3820 pts/2S+ 0:00 grep --color=auto -i pulseaudio
> 
> There are two pulseaudio processes running (!). I don´t know why. This
> is the state immediately before shutdown. All programmes are closed
> and nothing should be running regarding pulseaudio.
> 
> So I perform " killall pulseaudio" immediately before shutdown. After
> that I get no error messages at all.
> 
> Does anybody know what can be done about this?
> 
> Tnx a lot in advance.

Does setting "exit-idle-time = 0" in /etc/pulse/daemon.conf help?

-- 
Tanu

https://www.patreon.com/tanuk
https://liberapay.com/tanuk

___
pulseaudio-discuss mailing list
pulseaudio-discuss@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/pulseaudio-discuss

Re: [pulseaudio-discuss] [PATCH] alsa: Fix inclusion of use-case.h

2019-04-22 Thread Tanu Kaskinen
On Sun, 2019-04-21 at 11:59 +0200, Takashi Iwai wrote:
> The recent change in ALSA upstream stripped -I$include/alsa path from
> pkgconfig.  We already fixed for this change in some places but still
> the code for UCM was overlooked, and this resulted in the unresolved
> symbols in alsa card module. Fix them as well.
> 
> Signed-off-by: Takashi Iwai 
> ---
>  configure.ac| 2 +-
>  src/modules/alsa/alsa-ucm.h | 2 +-
>  2 files changed, 2 insertions(+), 2 deletions(-)
> 
> diff --git a/configure.ac b/configure.ac
> index c004bd70d1b2..b44ed1595af3 100644
> --- a/configure.ac
> +++ b/configure.ac
> @@ -826,7 +826,7 @@ AS_IF([test "x$enable_alsa" = "xyes" && test 
> "x$HAVE_ALSA" = "x0"],
>  AS_IF([test "x$HAVE_ALSA" = "x1"],
>  [
>  save_CPPFLAGS="$CPPFLAGS"; CPPFLAGS="$CPPFLAGS $ASOUNDLIB_CFLAGS"
> -AC_CHECK_HEADERS([use-case.h], HAVE_ALSA_UCM=1, HAVE_ALSA_UCM=0)
> +AC_CHECK_HEADERS([alsa/use-case.h], HAVE_ALSA_UCM=1, HAVE_ALSA_UCM=0)
>  CPPFLAGS="$save_CPPFLAGS"
>  ],
>  HAVE_ALSA_UCM=0)
> diff --git a/src/modules/alsa/alsa-ucm.h b/src/modules/alsa/alsa-ucm.h
> index 53abf3f90845..c926f3cc39a6 100644
> --- a/src/modules/alsa/alsa-ucm.h
> +++ b/src/modules/alsa/alsa-ucm.h
> @@ -23,7 +23,7 @@
>  ***/
>  
>  #ifdef HAVE_ALSA_UCM
> -#include 
> +#include 
>  #else
>  typedef void snd_use_case_mgr_t;
>  #endif

Thanks! Applied.

-- 
Tanu

https://www.patreon.com/tanuk
https://liberapay.com/tanuk

___
pulseaudio-discuss mailing list
pulseaudio-discuss@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/pulseaudio-discuss

Re: [pulseaudio-discuss] configure a soundcard?

2019-04-22 Thread Tanu Kaskinen
On Sat, 2019-04-20 at 12:11 -0500, Matt Zagrabelny wrote:
> Greetings,
> 
> I'm running Debian Buster and I have a 1/8" audio jack. I need the sink to
> be an analog output to send off to some other device. Things work great,
> except for when the system reboots, it comes up configured as a digital
> soundcard:
> 
> Digital Stereo (IEC958)
> 
> Here is a diff between a "pactl list" when the computer reboots and when
> I've configured it to be an analog sink:
> 
> -Sink #1
> -   State: SUSPENDED
> -   Name: alsa_output.pci-_00_14.2.iec958-stereo
> -   Description: Built-in Audio Digital Stereo (IEC958)
> +Sink #2
> +   State: RUNNING
> +   Name: alsa_output.pci-_00_14.2.analog-stereo
> +   Description: Built-in Audio Analog Stereo
> 
> What is the best way to have the configuration saved between reboots?
> 
> I can provide further info if needed.
> 
> Thanks for any help!

What does "pactl list cards" print, and what does this little script
print?

while read -r line; do amixer -c0 cget "$line"; done <<< $(amixer -c0 
controls | grep Jack)

-- 
Tanu

https://www.patreon.com/tanuk
https://liberapay.com/tanuk

___
pulseaudio-discuss mailing list
pulseaudio-discuss@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/pulseaudio-discuss

Re: [pulseaudio-discuss] [PATCH v8 08/12] bluetooth: Add A2DP FastStream codec support

2019-04-22 Thread Tanu Kaskinen
On Sat, 2019-04-20 at 11:24 +0200, Pali Rohár wrote:
> On Saturday 20 April 2019 11:37:56 Tanu Kaskinen wrote:
> > On Sat, 2019-04-06 at 11:16 +0200, Pali Rohár wrote:
> > > This patch provides support for FastStream codec in bluetooth A2DP 
> > > profile.
> > > FastStream codec is bi-directional, which means that support both music
> > > playback and microphone voice at the same time.
> > > 
> > > FastStream codec is just SBC codec with fixed parameters. For playback are
> > > used following parameters: 48.0kHz or 44.1kHz, Blocks 16, Sub-bands 8,
> > > Joint Stereo, Loudness, Bitpool = 29 (data rate = 212kbps, packet size =
> > > (71+1)*3+4 = 220 = DM5). SBC frame size is 71 bytes, but padded with one
> > > zero byte due to rounding to 72 bytes. For microphone are used following
> > > SBC parameters: 16kHz, Mono, Blocks 16, Sub-bands 8, Loudness, Bitpool = 
> > > 32
> > > (data rate = 72kbps, packet size = 3*72 + 4 = 220 <= DM5).
> > > 
> > > So FastStream codec is slightly equivalent to SBC Low Quality settings
> > > (which uses bitpool value 30). But the main benefit of FastStream codec is
> > > support for microphone voice channel for audio calls. Compared to 
> > > bluetooth
> > > HSP profile (with CVSD codec), it provides better audio quality for both
> > > playback and recording.
> > > ---
> > >  src/Makefile.am   |   2 +
> > >  src/modules/bluetooth/a2dp-codec-faststream.c | 436 
> > > ++
> > >  src/modules/bluetooth/a2dp-codec-util.c   |   2 +
> > >  3 files changed, 440 insertions(+)
> > >  create mode 100644 src/modules/bluetooth/a2dp-codec-faststream.c
> > > +static bool is_configuration_valid(const uint8_t *config_buffer, uint8_t 
> > > config_size) {
> > > +const a2dp_faststream_t *config = (const a2dp_faststream_t *) 
> > > config_buffer;
> > > +
> > > +if (config_size != sizeof(*config)) {
> > > +pa_log_error("Invalid size of config buffer");
> > > +return false;
> > > +}
> > > +
> > > +if (A2DP_GET_VENDOR_ID(config->info) != FASTSTREAM_VENDOR_ID || 
> > > A2DP_GET_CODEC_ID(config->info) != FASTSTREAM_CODEC_ID) {
> > > +pa_log_error("Invalid vendor codec information in 
> > > configuration");
> > > +return false;
> > > +}
> > > +
> > > +if (!(config->direction & FASTSTREAM_DIRECTION_SINK) || 
> > > !(config->direction & FASTSTREAM_DIRECTION_SOURCE)) {
> > > +pa_log_error("Invalid direction in configuration");
> > > +return false;
> > > +}
> > > +
> > > +/* Remote endpoint indicates list of frequences, not just one 
> > > frequency */
> > 
> > Typo: "frequences" -> "frequencies".
> 
> Ok, I will fix all occurrences.
> 
> > > +if ((config->sink_frequency & 
> > > ~(FASTSTREAM_SINK_SAMPLING_FREQ_44100|FASTSTREAM_SINK_SAMPLING_FREQ_48000))
> > >  ||
> > > +   (!(config->sink_frequency & 
> > > (FASTSTREAM_SINK_SAMPLING_FREQ_44100|FASTSTREAM_SINK_SAMPLING_FREQ_48000
> > >  {
> > 
> > Do we really need to be this strict?
> 
> Yes.
> 
> > The final sample rate is decided
> > by us, so isn't it enough if the config contains just one of the rates
> > that we support? If the sink supports some other rates, we don't need
> > to care about that.
> 
> Normally in A2DP capabilities buffer device announces combination (list)
> of supported features and configurations. In A2DP config buffer device
> usually says one exact configuration which should be used.
> 
> But my testing headphones in A2DP FastStream config buffer sometimes
> says that sink frequency is both 44100|48000 -- which does not make
> sense. When pulseaudio started sending SBC data with 44.1kHz then sound
> was obviously bad, there was periodically quiet period (should be for
> 1.8 us). When pulseaudio started sending SBC data with 48kHz everything
> was OK. So conclusion is that when headphones says that sampling
> frequency is both 44100|48000 in config buffer they means it is 48kHz.
> 
> In function is_configuration_valid we need to ensure that pulseaudio and
> remove device negotiate correctly all parameters, including sampling
> frequency and both sides know how to interpret config buffer.
> 
> So strictness is needed to ensure that audio is correctly encoded to SBC
> codec and then correctly decoded from SBC codec to RAW.

Ok, so this is a firmware bug. That should be documented as such, and I
think it would be best to do the firmware bug fixup as a separate step,
like this:

static bool is_configuration_valid(...) {
uint8_t sink_frequency;

...

sink_frequency = config->sink_frequency;

/* Some headsets are buggy and set both 48 kHz and 44.1 kHz in
 * the config. In such situation trying to send audio at 44.1 kHz
 * results in choppy audio, so we have to assume that the headset
 * actually wants 48 kHz audio. */
if (sink_frequency == (FASTSTREAM_SINK_SAMPLING_FREQ_44100 | 
FASTSTREAM_SINK_SAMPLING_FREQ_48000))
sink_frequency = 

Re: [pulseaudio-discuss] R: New equalizer module (module-eqpro-sink), some questions

2019-04-22 Thread Tanu Kaskinen
On Sat, 2019-04-20 at 11:38 +0200, Georg Chini wrote:
> On 20.04.19 11:06, Tanu Kaskinen wrote:
> > On Fri, 2019-04-19 at 17:52 +0200, Georg Chini wrote:
> > > On 19.04.19 16:56, Tanu Kaskinen wrote:
> > > > Changing the number of eq bands isn't quite like changing regular
> > > > control values. The plugin probably has some per-band data, which has
> > > > to be reallocated when the number of bands changes. malloc() isn't
> > > > allowed in the IO thread. Also, all gain values assigned to the bands
> > > > previously are likely useless, because the band frequencies change. The
> > > > host will likely have to set all bands to the default gain value, so in
> > > > effect changing the band count is like starting from scratch, which is
> > > > very different from changing a regular control value.
> > > Yes, you are right, it would be like starting from scratch. It
> > > would however be not the primary goal to change the number
> > > of bands at run-time, but to be able to define the number of
> > > bands dynamically when the instance is created. Because this
> > > would affect the number of necessary ports (per band gains)
> > > it is not possible with the current definition unless you have
> > > a control port that can be an array. As a side effect, the band
> > > count could also be changed dynamically at run-time.
> > > 
> > > Why would malloc() not be allowed in the IO-thread? It's not
> > > allowed within the run() function, but that's a different thing.
> > Why is it a different thing? malloc() is not allowed in the run()
> > function, because the function is expected to be run in a realtime
> > thread, and malloc() is not realtime-safe. The IO thread is a realtime
> > thread, so the same limitations apply also outside the run() function.
> 
> PA uses malloc() in the IO-thread, so are we doing things wrong?
> I think using malloc() when a parameter changes is not interfering
> with real-time operation because the filter must be reset after
> a parameter change anyway.

Where exactly is malloc() used? Sounds like a bug.

Using malloc() when changing parameters does interfere with realtime
operation, because there may be more audio paths to the hardware sink
than just the ladspa filter. There may be streams that aren't filtered.

> > > > If the eq band count was an initialization parameter rather than a
> > > > control port, the IO thread limitations wouldn't become an issue, and
> > > > it would be explicit that changing the eq band count means starting
> > > > from scratch. It should still be possible to change initialization
> > > > parameters at runtime, that would just mean that a new plugin instance
> > > > is created and the old instance is removed.
> > > > 
> > > It is not possible to have that kind of initialization parameter.
> > > That is the main problem. As explained above, changing the
> > > number of bands would require changing the number of control
> > > ports.
> > If we're adding new stuff to the LADSPA interface anyway, we can surely
> > add a function that sets initialization parameters (and a function for
> > querying what initialization parameters the plugin has). We can then
> > specify that the control ports are to be created only after the
> > initialization parameters have been set.
> > 
> Well, after evaluation of the feedback I have been getting so far,
> I do not think I will make an attempt to create some plugin-sink.
> The existing standards do not fit to what I have in mind and
> if I read Alexander right they even intentionally do not support
> those features.
> 
> Inventing a PA internal standard does not make sense, because
> your main argument against implementing the equalizer as a module
> was that you did not want to host the DSP code inside PA. If we
> did our own standard, new filters would again be bound to PA.

New filters would be specific to PA, yes, but not maintained by us, and
new filters wouldn't have to go through the review process, so there
would still be some benefit in having a PA specific stable plugin API.

-- 
Tanu

https://www.patreon.com/tanuk
https://liberapay.com/tanuk

___
pulseaudio-discuss mailing list
pulseaudio-discuss@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/pulseaudio-discuss