Skip to content

Commit

Permalink
Allow user to provide extra PCM delay component
Browse files Browse the repository at this point in the history
If everything fails, user will be able to adjust PCM delay. Additionally,
this feature will allow to specify different delay for every configured
(in the ALSA configuration file) Bluetooth device, as follows:

$ cat .asoundrc
pcm.device-1 {
	type bluealsa
	device "AB:CD:EF:01:23:45"
	profile "a2dp"
	delay 30000
}
pcm.device-2 {
	type bluealsa
	device "AB:CD:EF:45:67:89"
	profile "a2dp"
	delay 15000
}
  • Loading branch information
arkq committed Feb 26, 2017
1 parent 81fde85 commit e7a4c40
Show file tree
Hide file tree
Showing 3 changed files with 27 additions and 3 deletions.
3 changes: 2 additions & 1 deletion README.md
Expand Up @@ -60,6 +60,7 @@ like this:
defaults.bluealsa.interface "hci0"
defaults.bluealsa.device "XX:XX:XX:XX:XX:XX"
defaults.bluealsa.profile "a2dp"
defaults.bluealsa.delay 10000

BlueALSA also allows to capture audio from the connected Bluetooth device. To do so, one has to
use the capture PCM device, e.g.:
Expand Down Expand Up @@ -118,7 +119,7 @@ Troubleshooting

If connected Bluetooth headset supports AAC and BlueALSA was compiled with AAC (`./configure
--enable-aac`) such an encoder will be used for A2DP profile. However, AAC encoding is
buggious - sorry for that. If the encoded packet size exceeds writing MTU, fragmentation occurs,
buggy - sorry for that. If the encoded packet size exceeds writing MTU, fragmentation occurs,
which is not handled correctly. As a workaround, it is possible to decrease packet size by
degrading audio quality via the `--aac-vbr-mode=NB` option.

Expand Down
14 changes: 13 additions & 1 deletion src/asound/20-bluealsa.conf
@@ -1,5 +1,9 @@
# BlueALSA integration setup

defaults.bluealsa.interface "hci0"
defaults.bluealsa.profile "a2dp"
defaults.bluealsa.delay 20000

ctl.bluealsa {
@args [ HCI ]
@args.HCI {
Expand All @@ -14,7 +18,7 @@ ctl.bluealsa {
}

pcm.bluealsa {
@args [ HCI DEV PROFILE ]
@args [ HCI DEV PROFILE DELAY ]
@args.HCI {
type string
default {
Expand All @@ -36,12 +40,20 @@ pcm.bluealsa {
name defaults.bluealsa.profile
}
}
@args.DELAY {
type integer
default {
@func refer
name defaults.bluealsa.delay
}
}
type plug
slave.pcm {
type bluealsa
interface $HCI
device $DEV
profile $PROFILE
delay $DELAY
}
hint {
show {
Expand Down
13 changes: 12 additions & 1 deletion src/asound/bluealsa-pcm.c
Expand Up @@ -52,6 +52,8 @@ struct bluealsa_pcm {

/* communication and encoding/decoding delay */
snd_pcm_sframes_t delay;
/* user provided extra delay component */
snd_pcm_sframes_t delay_ex;

/* ALSA operates on frames, we on bytes */
size_t frame_size;
Expand Down Expand Up @@ -336,7 +338,7 @@ static int bluealsa_delay(snd_pcm_ioplug_t *io, snd_pcm_sframes_t *delayp) {

}

*delayp = delay + pcm->delay;
*delayp = delay + pcm->delay + pcm->delay_ex;
return 0;
}

Expand Down Expand Up @@ -480,6 +482,7 @@ SND_PCM_PLUGIN_DEFINE_FUNC(bluealsa) {
const char *device = NULL;
const char *profile = NULL;
struct bluealsa_pcm *pcm;
long delay = 0;
int ret;

snd_config_for_each(i, next, conf) {
Expand Down Expand Up @@ -515,6 +518,13 @@ SND_PCM_PLUGIN_DEFINE_FUNC(bluealsa) {
}
continue;
}
if (strcmp(id, "delay") == 0) {
if (snd_config_get_integer(n, &delay) < 0) {
SNDERR("Invalid type for %s", id);
return -EINVAL;
}
continue;
}

SNDERR("Unknown field %s", id);
return -EINVAL;
Expand All @@ -541,6 +551,7 @@ SND_PCM_PLUGIN_DEFINE_FUNC(bluealsa) {
pcm->fd = -1;
pcm->event_fd = -1;
pcm->pcm_fd = -1;
pcm->delay_ex = delay;

if ((pcm->fd = bluealsa_open(interface)) == -1) {
SNDERR("BlueALSA connection failed: %s", strerror(errno));
Expand Down

0 comments on commit e7a4c40

Please sign in to comment.