Skip to content

Commit

Permalink
Enable dbus delay signals for internal processing delay.
Browse files Browse the repository at this point in the history
The `bluealsad` daemon currently keeps track of its own internal
processing delay, but only presents that to a client when the
'Delay' property is explicitly queried by the client. This means
that any client which relies on D-Bus signals to obtain Delay
updates may never see this internal processing delay (for example
the `bluealsa` ALSA plugin).

The purpose of this commit is to have `bluealsad` emit a D-Bus
PropertiesChanged signal whenever a "significant" change to the
internal processing delay occurs. Not every change is reported
because that might generate thousands of signals per second.
  • Loading branch information
borine committed Oct 29, 2024
1 parent f93a6e8 commit 79c4b9c
Show file tree
Hide file tree
Showing 16 changed files with 39 additions and 12 deletions.
2 changes: 1 addition & 1 deletion src/a2dp-aac.c
Original file line number Diff line number Diff line change
Expand Up @@ -419,7 +419,7 @@ void *a2dp_aac_enc_thread(struct ba_transport_pcm *t_pcm) {
rtp_state_update(&rtp, pcm_frames);

/* update busy delay (encoding overhead) */
t_pcm->processing_delay_dms = asrsync_get_busy_usec(&io.asrs) / 100;
ba_transport_pcm_update_processing_delay(t_pcm, asrsync_get_busy_usec(&io.asrs) / 100);

/* If the input buffer was not consumed, we have to append new data to
* the existing one. Since we do not use ring buffer, we will simply
Expand Down
2 changes: 1 addition & 1 deletion src/a2dp-aptx-hd.c
Original file line number Diff line number Diff line change
Expand Up @@ -220,7 +220,7 @@ void *a2dp_aptx_hd_enc_thread(struct ba_transport_pcm *t_pcm) {
rtp.ts_pcm_frames += pcm_frames;

/* update busy delay (encoding overhead) */
t_pcm->processing_delay_dms = asrsync_get_busy_usec(&io.asrs) / 100;
ba_transport_pcm_update_processing_delay(t_pcm, asrsync_get_busy_usec(&io.asrs) / 100);

/* reinitialize output buffer */
ffb_rewind(&bt);
Expand Down
2 changes: 1 addition & 1 deletion src/a2dp-aptx.c
Original file line number Diff line number Diff line change
Expand Up @@ -201,7 +201,7 @@ void *a2dp_aptx_enc_thread(struct ba_transport_pcm *t_pcm) {
asrsync_sync(&io.asrs, pcm_samples / channels);

/* update busy delay (encoding overhead) */
t_pcm->processing_delay_dms = asrsync_get_busy_usec(&io.asrs) / 100;
ba_transport_pcm_update_processing_delay(t_pcm, asrsync_get_busy_usec(&io.asrs) / 100);

/* reinitialize output buffer */
ffb_rewind(&bt);
Expand Down
2 changes: 1 addition & 1 deletion src/a2dp-faststream.c
Original file line number Diff line number Diff line change
Expand Up @@ -228,7 +228,7 @@ void *a2dp_fs_enc_thread(struct ba_transport_pcm *t_pcm) {
asrsync_sync(&io.asrs, pcm_frames);

/* update busy delay (encoding overhead) */
t_pcm->processing_delay_dms = asrsync_get_busy_usec(&io.asrs) / 100;
ba_transport_pcm_update_processing_delay(t_pcm, asrsync_get_busy_usec(&io.asrs) / 100);

/* If the input buffer was not consumed (due to codesize limit), we
* have to append new data to the existing one. Since we do not use
Expand Down
2 changes: 1 addition & 1 deletion src/a2dp-lc3plus.c
Original file line number Diff line number Diff line change
Expand Up @@ -384,7 +384,7 @@ void *a2dp_lc3plus_enc_thread(struct ba_transport_pcm *t_pcm) {
rtp_state_update(&rtp, pcm_frames);

/* update busy delay (encoding overhead) */
t_pcm->processing_delay_dms = asrsync_get_busy_usec(&io.asrs) / 100;
ba_transport_pcm_update_processing_delay(t_pcm, asrsync_get_busy_usec(&io.asrs) / 100);

/* If the input buffer was not consumed (due to codesize limit), we
* have to append new data to the existing one. Since we do not use
Expand Down
2 changes: 1 addition & 1 deletion src/a2dp-ldac.c
Original file line number Diff line number Diff line change
Expand Up @@ -270,7 +270,7 @@ void *a2dp_ldac_enc_thread(struct ba_transport_pcm *t_pcm) {
rtp_state_update(&rtp, pcm_frames);

/* update busy delay (encoding overhead) */
t_pcm->processing_delay_dms = asrsync_get_busy_usec(&io.asrs) / 100;
ba_transport_pcm_update_processing_delay(t_pcm, asrsync_get_busy_usec(&io.asrs) / 100);

}

Expand Down
2 changes: 1 addition & 1 deletion src/a2dp-mpeg.c
Original file line number Diff line number Diff line change
Expand Up @@ -323,7 +323,7 @@ void *a2dp_mp3_enc_thread(struct ba_transport_pcm *t_pcm) {
rtp_state_update(&rtp, pcm_frames);

/* update busy delay (encoding overhead) */
t_pcm->processing_delay_dms = asrsync_get_busy_usec(&io.asrs) / 100;
ba_transport_pcm_update_processing_delay(t_pcm, asrsync_get_busy_usec(&io.asrs) / 100);

/* If the input buffer was not consumed (due to frame alignment), we
* have to append new data to the existing one. Since we do not use
Expand Down
2 changes: 1 addition & 1 deletion src/a2dp-opus.c
Original file line number Diff line number Diff line change
Expand Up @@ -244,7 +244,7 @@ void *a2dp_opus_enc_thread(struct ba_transport_pcm *t_pcm) {
rtp_state_update(&rtp, opus_frame_pcm_frames);

/* update busy delay (encoding overhead) */
t_pcm->processing_delay_dms = asrsync_get_busy_usec(&io.asrs) / 100;
ba_transport_pcm_update_processing_delay(t_pcm, asrsync_get_busy_usec(&io.asrs) / 100);

/* If the input buffer was not consumed (due to encoder frame
* constraint), we have to append new data to the existing one.
Expand Down
2 changes: 1 addition & 1 deletion src/a2dp-sbc.c
Original file line number Diff line number Diff line change
Expand Up @@ -273,7 +273,7 @@ void *a2dp_sbc_enc_thread(struct ba_transport_pcm *t_pcm) {
rtp_state_update(&rtp, pcm_frames);

/* update busy delay (encoding overhead) */
t_pcm->processing_delay_dms = asrsync_get_busy_usec(&io.asrs) / 100;
ba_transport_pcm_update_processing_delay(t_pcm, asrsync_get_busy_usec(&io.asrs) / 100);

/* If the input buffer was not consumed (due to codesize limit), we
* have to append new data to the existing one. Since we do not use
Expand Down
16 changes: 16 additions & 0 deletions src/ba-transport-pcm.c
Original file line number Diff line number Diff line change
Expand Up @@ -716,6 +716,22 @@ int ba_transport_pcm_get_hardware_volume(
return 0;
}

void ba_transport_pcm_update_processing_delay(struct ba_transport_pcm *pcm, unsigned int delay) {
if (delay == pcm->processing_delay_dms)
return;
unsigned int diff = delay > pcm->reported_processing_delay_dms ?
delay - pcm->reported_processing_delay_dms :
pcm->reported_processing_delay_dms - delay;
pcm->processing_delay_dms = delay;

/* To avoid creating a flood of dbus signals, we only notify clients when
* the value changes by more than 10ms */
if (diff > 100 || pcm->reported_processing_delay_dms == 0) {
pcm->reported_processing_delay_dms = delay;
bluealsa_dbus_pcm_update(pcm, BA_DBUS_PCM_UPDATE_DELAY);
}
}

int ba_transport_pcm_get_delay(const struct ba_transport_pcm *pcm) {

const struct ba_transport *t = pcm->t;
Expand Down
5 changes: 5 additions & 0 deletions src/ba-transport-pcm.h
Original file line number Diff line number Diff line change
Expand Up @@ -129,6 +129,7 @@ struct ba_transport_pcm {
* the host computational power. It is used to compensate for the time
* required to encode or decode audio. */
unsigned int processing_delay_dms;
unsigned int reported_processing_delay_dms;
/* Positive (or negative) delay reported by the client. */
int client_delay_dms;

Expand Down Expand Up @@ -253,6 +254,10 @@ int ba_transport_pcm_volume_update(
int ba_transport_pcm_get_hardware_volume(
const struct ba_transport_pcm *pcm);

void ba_transport_pcm_update_processing_delay(
struct ba_transport_pcm *pcm,
unsigned int delay);

int ba_transport_pcm_get_delay(
const struct ba_transport_pcm *pcm);

Expand Down
4 changes: 4 additions & 0 deletions src/bluealsa-dbus.c
Original file line number Diff line number Diff line change
Expand Up @@ -538,6 +538,10 @@ static void bluealsa_pcm_open(GDBusMethodInvocation *inv, void *userdata) {
goto fail;
}

/* It the transport thread has updated its codec_delay value during its
* start procedure then we inform clients that the delay has changed */
if (pcm->codec_delay_dms > 0)
bluealsa_dbus_pcm_update(pcm, BA_DBUS_PCM_UPDATE_DELAY);
}

pthread_mutex_lock(&pcm->mutex);
Expand Down
2 changes: 1 addition & 1 deletion src/sco-cvsd.c
Original file line number Diff line number Diff line change
Expand Up @@ -79,7 +79,7 @@ void *sco_cvsd_enc_thread(struct ba_transport_pcm *t_pcm) {
/* keep data transfer at a constant bit rate */
asrsync_sync(&io.asrs, mtu_samples);
/* update busy delay (encoding overhead) */
t_pcm->processing_delay_dms = asrsync_get_busy_usec(&io.asrs) / 100;
ba_transport_pcm_update_processing_delay(t_pcm, asrsync_get_busy_usec(&io.asrs) / 100);

}

Expand Down
2 changes: 1 addition & 1 deletion src/sco-lc3-swb.c
Original file line number Diff line number Diff line change
Expand Up @@ -85,7 +85,7 @@ void *sco_lc3_swb_enc_thread(struct ba_transport_pcm *t_pcm) {
/* keep data transfer at a constant bit rate */
asrsync_sync(&io.asrs, codec.frames * LC3_SWB_CODESAMPLES);
/* update busy delay (encoding overhead) */
t_pcm->processing_delay_dms = asrsync_get_busy_usec(&io.asrs) / 100;
ba_transport_pcm_update_processing_delay(t_pcm, asrsync_get_busy_usec(&io.asrs) / 100);

/* Move unprocessed data to the front of our linear
* buffer and clear the LC3-SWB frame counter. */
Expand Down
2 changes: 1 addition & 1 deletion src/sco-msbc.c
Original file line number Diff line number Diff line change
Expand Up @@ -92,7 +92,7 @@ void *sco_msbc_enc_thread(struct ba_transport_pcm *t_pcm) {
/* keep data transfer at a constant bit rate */
asrsync_sync(&io.asrs, msbc.frames * MSBC_CODESAMPLES);
/* update busy delay (encoding overhead) */
t_pcm->processing_delay_dms = asrsync_get_busy_usec(&io.asrs) / 100;
ba_transport_pcm_update_processing_delay(t_pcm, asrsync_get_busy_usec(&io.asrs) / 100);

/* Move unprocessed data to the front of our linear
* buffer and clear the mSBC frame counter. */
Expand Down
2 changes: 2 additions & 0 deletions test/test-a2dp.c
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,8 @@ int ba_transport_pcm_state_set(struct ba_transport_pcm *pcm,
enum ba_transport_pcm_signal ba_transport_pcm_signal_recv(struct ba_transport_pcm *pcm) {
(void)pcm; return -1; }
void ba_transport_pcm_thread_cleanup(struct ba_transport_pcm *pcm) { (void)pcm; }
void ba_transport_pcm_update_processing_delay(struct ba_transport_pcm *pcm, unsigned int delay) {
(void)pcm; (void)delay;}

CK_START_TEST(test_a2dp_codecs_codec_id_from_string) {
ck_assert_uint_eq(a2dp_codecs_codec_id_from_string("SBC"), A2DP_CODEC_SBC);
Expand Down

0 comments on commit 79c4b9c

Please sign in to comment.