Skip to content

Commit

Permalink
A2DP LHDC codec IO test and proper delay setup
Browse files Browse the repository at this point in the history
  • Loading branch information
arkq committed Nov 14, 2024
1 parent ddfa790 commit 1002906
Show file tree
Hide file tree
Showing 8 changed files with 90 additions and 10 deletions.
3 changes: 2 additions & 1 deletion configure.ac
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
# BlueALSA - configure.ac
# Copyright (c) 2016-2024 Arkadiusz Bokowy

AC_PREREQ([2.60])
AC_PREREQ([2.62])
AC_INIT([BlueALSA],
[m4_normalize(esyscmd([test -d .git && git describe --always --dirty || echo v4.3.1]))],
[arkadiusz.bokowy@gmail.com], [bluez-alsa], [https://github.com/arkq/bluez-alsa])
Expand All @@ -13,6 +13,7 @@ AC_CONFIG_MACRO_DIR([m4])

AC_USE_SYSTEM_EXTENSIONS
m4_version_prereq(2.70, [AC_PROG_CC], [AC_PROG_CC_C99])
AC_OPENMP
AC_PROG_INSTALL
AC_PROG_LN_S
AC_PROG_MKDIR_P
Expand Down
5 changes: 5 additions & 0 deletions src/a2dp-lhdc.c
Original file line number Diff line number Diff line change
Expand Up @@ -198,6 +198,10 @@ void *a2dp_lhdc_enc_thread(struct ba_transport_pcm *t_pcm) {
goto fail_ffb;
}

const unsigned int ldac_delay_frames = 1024;
/* Get the total delay introduced by the codec. */
t_pcm->codec_delay_dms = ldac_delay_frames * 10000 / rate;

rtp_header_t *rtp_header;
rtp_lhdc_media_header_t *rtp_lhdc_media_header;
/* initialize RTP headers and get anchor for payload */
Expand All @@ -216,6 +220,7 @@ void *a2dp_lhdc_enc_thread(struct ba_transport_pcm *t_pcm) {
switch (io_poll_and_read_pcm(&io, t_pcm, &pcm)) {
case -1:
if (errno == ESTALE) {
/* TODO: flush encoder internal buffers */
ffb_rewind(&pcm);
continue;
}
Expand Down
2 changes: 1 addition & 1 deletion src/shared/a2dp-codecs.h
Original file line number Diff line number Diff line change
Expand Up @@ -571,7 +571,7 @@ typedef struct a2dp_ldac {

#define LHDC_MAX_BITRATE_400K (1 << 1)
#define LHDC_MAX_BITRATE_500K (1 << 0)
#define LHDC_MAX_BITRATE_900K 0x00
#define LHDC_MAX_BITRATE_900K (0)

#define LHDC_CH_SPLIT_MODE_NONE (1 << 0)
#define LHDC_CH_SPLIT_MODE_TWS (1 << 1)
Expand Down
10 changes: 10 additions & 0 deletions test/Makefile.am
Original file line number Diff line number Diff line change
Expand Up @@ -282,6 +282,11 @@ test_a2dp_SOURCES += ../src/a2dp-ldac.c
test_io_SOURCES += ../src/a2dp-ldac.c
endif

if ENABLE_LHDC
test_a2dp_SOURCES += ../src/a2dp-lhdc.c
test_io_SOURCES += ../src/a2dp-lhdc.c
endif

if ENABLE_MPEG
test_a2dp_SOURCES += ../src/a2dp-mpeg.c
test_io_SOURCES += ../src/a2dp-mpeg.c
Expand Down Expand Up @@ -322,10 +327,13 @@ AM_CFLAGS = \
@LDAC_ABR_CFLAGS@ \
@LDAC_DEC_CFLAGS@ \
@LDAC_ENC_CFLAGS@ \
@LHDC_DEC_CFLAGS@ \
@LHDC_ENC_CFLAGS@ \
@LIBBSD_CFLAGS@ \
@LIBUNWIND_CFLAGS@ \
@MP3LAME_CFLAGS@ \
@MPG123_CFLAGS@ \
@OPENMP_CFLAGS@ \
@OPUS_CFLAGS@ \
@SBC_CFLAGS@ \
@SNDFILE_CFLAGS@ \
Expand All @@ -345,6 +353,8 @@ LDADD = \
@LDAC_ABR_LIBS@ \
@LDAC_DEC_LIBS@ \
@LDAC_ENC_LIBS@ \
@LHDC_DEC_LIBS@ \
@LHDC_ENC_LIBS@ \
@LIBUNWIND_LIBS@ \
@MP3LAME_LIBS@ \
@MPG123_LIBS@ \
Expand Down
2 changes: 1 addition & 1 deletion test/inc/btd.inc
Original file line number Diff line number Diff line change
Expand Up @@ -174,7 +174,7 @@ struct bt_dump *bt_dump_open(const char *path) {
goto fail;
}

uint16_t id;
uint32_t id;
if (bt_dump_read(btd, &id, sizeof(id)) == -1)
goto fail;
btd->transport_codec_id = be32toh(id);
Expand Down
8 changes: 8 additions & 0 deletions test/mock/Makefile.am
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,8 @@ bluealsad_mock_CFLAGS = \
@LDAC_ABR_CFLAGS@ \
@LDAC_DEC_CFLAGS@ \
@LDAC_ENC_CFLAGS@ \
@LHDC_DEC_CFLAGS@ \
@LHDC_ENC_CFLAGS@ \
@LIBBSD_CFLAGS@ \
@LIBUNWIND_CFLAGS@ \
@MP3LAME_CFLAGS@ \
Expand All @@ -83,6 +85,8 @@ bluealsad_mock_LDADD = \
@LDAC_ABR_LIBS@ \
@LDAC_DEC_LIBS@ \
@LDAC_ENC_LIBS@ \
@LHDC_DEC_LIBS@ \
@LHDC_ENC_LIBS@ \
@LIBUNWIND_LIBS@ \
@MP3LAME_LIBS@ \
@MPG123_LIBS@ \
Expand Down Expand Up @@ -124,6 +128,10 @@ if ENABLE_LDAC
bluealsad_mock_SOURCES += ../../src/a2dp-ldac.c
endif

if ENABLE_LHDC
bluealsad_mock_SOURCES += ../../src/a2dp-lhdc.c
endif

if ENABLE_MIDI
bluealsad_mock_SOURCES += \
../../src/ble-midi.c \
Expand Down
14 changes: 8 additions & 6 deletions test/sndalign.c
Original file line number Diff line number Diff line change
Expand Up @@ -92,26 +92,28 @@ int main(int argc, char *argv[]) {
const size_t channels = sf1_info.channels;
const size_t sf1_frames = sf1_info.frames;
const size_t sf2_frames = sf2_info.frames;
const size_t cross_correlation_frames = sf1_frames + sf2_frames;
const size_t min_overlap = MIN(512, MIN(sf1_frames, sf2_frames));
const size_t cross_correlation_frames = sf1_frames + sf2_frames - min_overlap;
long long *cross_correlation = calloc(cross_correlation_frames, sizeof(long long));
size_t min_overlap = MIN(512, MIN(sf1_frames, sf2_frames));

#pragma omp parallel for schedule(dynamic)
for (size_t i = min_overlap; i < cross_correlation_frames; i++) {

size_t sf1_begin = i < sf2_frames ? 0 : i - sf2_frames;
size_t sf2_begin = i < sf2_frames ? sf2_frames - i : 0;
size_t sf1_end = i < sf1_frames ? i : sf1_frames;

const size_t overlap = sf1_end - sf1_begin;
if (overlap < min_overlap)
break;

long long cc_v = 0;
for (size_t j = 0; j < overlap; j++)
for (size_t k = 0; k < channels; k++)
cross_correlation[i] +=
cc_v +=
sf1_data[(sf1_begin + j) * channels + k] *
sf2_data[(sf2_begin + j) * channels + k];

#pragma omp atomic
cross_correlation[i] += cc_v;

}

ssize_t max_i = 0;
Expand Down
56 changes: 55 additions & 1 deletion test/test-io.c
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,9 @@
#if ENABLE_LDAC_IO_TEST
# include <ldacBT.h>
#endif
#if ENABLE_LHDC
# include <lhdcBT.h>
#endif
#if HAVE_SNDFILE
# include <sndfile.h>
#endif
Expand All @@ -60,6 +63,9 @@
#if ENABLE_LDAC_IO_TEST
# include "a2dp-ldac.h"
#endif
#if ENABLE_LHDC
# include "a2dp-lhdc.h"
#endif
#if ENABLE_MPEG
# include "a2dp-mpeg.h"
#endif
Expand All @@ -81,7 +87,7 @@
#if ENABLE_OFONO
# include "ofono.h"
#endif
#if ENABLE_LC3PLUS || ENABLE_LDAC_IO_TEST
#if ENABLE_LC3PLUS || ENABLE_LDAC_IO_TEST || ENABLE_LHDC
# include "rtp.h"
#endif
#include "storage.h"
Expand Down Expand Up @@ -112,6 +118,8 @@ void *a2dp_lc3plus_dec_thread(struct ba_transport_pcm *t_pcm);
void *a2dp_lc3plus_enc_thread(struct ba_transport_pcm *t_pcm);
void *a2dp_ldac_dec_thread(struct ba_transport_pcm *t_pcm);
void *a2dp_ldac_enc_thread(struct ba_transport_pcm *t_pcm);
void *a2dp_lhdc_dec_thread(struct ba_transport_pcm *t_pcm);
void *a2dp_lhdc_enc_thread(struct ba_transport_pcm *t_pcm);
void *a2dp_mp3_enc_thread(struct ba_transport_pcm *t_pcm);
void *a2dp_mpeg_dec_thread(struct ba_transport_pcm *t_pcm);
void *a2dp_opus_dec_thread(struct ba_transport_pcm *t_pcm);
Expand Down Expand Up @@ -212,6 +220,13 @@ static const a2dp_ldac_t config_ldac_48000_stereo = {
.channel_mode = LDAC_CHANNEL_MODE_STEREO,
};

__attribute__ ((unused))
static const a2dp_lhdc_v3_t config_lhdc_44100_stereo = {
.info = A2DP_VENDOR_INFO_INIT(LHDC_V3_VENDOR_ID, LHDC_V3_CODEC_ID),
.sampling_freq = LHDC_SAMPLING_FREQ_44100,
.bit_depth = LHDC_BIT_DEPTH_24,
};

__attribute__ ((unused))
static const a2dp_opus_t config_opus_48000_stereo = {
.sampling_freq = OPUS_SAMPLING_FREQ_48000,
Expand Down Expand Up @@ -1301,6 +1316,39 @@ CK_START_TEST(test_a2dp_ldac) {
} CK_END_TEST
#endif

#if ENABLE_LHDC
CK_START_TEST(test_a2dp_lhdc) {

config.lhdc_eqmid = LHDCBT_QUALITY_HIGH;

struct ba_transport *t1 = test_transport_new_a2dp(device1,
BA_TRANSPORT_PROFILE_A2DP_SOURCE, "/path/lhdc", &a2dp_lhdc_source,
&config_lhdc_44100_stereo);
struct ba_transport *t2 = test_transport_new_a2dp(device2,
BA_TRANSPORT_PROFILE_A2DP_SINK, "/path/lhdc", &a2dp_lhdc_sink,
&config_lhdc_44100_stereo);

struct ba_transport_pcm *t1_pcm = &t1->a2dp.pcm;
struct ba_transport_pcm *t2_pcm = &t2->a2dp.pcm;

if (aging_duration) {
t1->mtu_read = t1->mtu_write = t2->mtu_read = t2->mtu_write =
RTP_HEADER_LEN + sizeof(rtp_media_header_t) + 990;
test_io(t1_pcm, t2_pcm, a2dp_lhdc_enc_thread, a2dp_lhdc_dec_thread, 4 * 1024);
}
else {
t1->mtu_read = t1->mtu_write = t2->mtu_read = t2->mtu_write =
RTP_HEADER_LEN + sizeof(rtp_media_header_t) + 990;
test_io(t1_pcm, t2_pcm, a2dp_lhdc_enc_thread, test_io_thread_dump_bt, 2 * 1024);
test_io(t1_pcm, t2_pcm, test_io_thread_dump_pcm, a2dp_lhdc_dec_thread, 2 * 1024);
}

ba_transport_destroy(t1);
ba_transport_destroy(t2);

} CK_END_TEST
#endif

#if ENABLE_OPUS
CK_START_TEST(test_a2dp_opus) {

Expand All @@ -1324,6 +1372,9 @@ CK_START_TEST(test_a2dp_opus) {
test_io(t1_pcm, t2_pcm, test_io_thread_dump_pcm, a2dp_opus_dec_thread, 2 * 1024);
}

ba_transport_destroy(t1);
ba_transport_destroy(t2);

} CK_END_TEST
#endif

Expand Down Expand Up @@ -1437,6 +1488,9 @@ int main(int argc, char *argv[]) {
#if ENABLE_LDAC_IO_TEST
{ a2dp_codecs_codec_id_to_string(A2DP_CODEC_VENDOR_ID(LDAC_VENDOR_ID, LDAC_CODEC_ID)), test_a2dp_ldac },
#endif
#if ENABLE_LHDC
{ a2dp_codecs_codec_id_to_string(A2DP_CODEC_VENDOR_ID(LHDC_V3_VENDOR_ID, LHDC_V3_CODEC_ID)), test_a2dp_lhdc },
#endif
#if ENABLE_OPUS
{ a2dp_codecs_codec_id_to_string(A2DP_CODEC_VENDOR_ID(OPUS_VENDOR_ID, OPUS_CODEC_ID)), test_a2dp_opus },
#endif
Expand Down

0 comments on commit 1002906

Please sign in to comment.