diff --git a/.github/workflows/build-and-test.yaml b/.github/workflows/build-and-test.yaml index e6124fa84..ac969ea3c 100644 --- a/.github/workflows/build-and-test.yaml +++ b/.github/workflows/build-and-test.yaml @@ -21,6 +21,7 @@ jobs: - --enable-faststream --enable-mp3lame - --enable-aplay --enable-ofono --enable-upower - --enable-cli --enable-rfcomm --enable-manpages + - --enable-aptx --enable-aptx-hd --with-libopenaptx fail-fast: false runs-on: ubuntu-22.04 steps: @@ -36,6 +37,7 @@ jobs: libglib2.0-dev libmp3lame-dev libmpg123-dev + libopenaptx-dev libreadline-dev libsbc-dev libspandsp-dev @@ -120,6 +122,7 @@ jobs: libglib2.0-dev libmp3lame-dev libmpg123-dev + libopenaptx-dev libsbc-dev libspandsp-dev - uses: actions/checkout@v4 @@ -132,6 +135,9 @@ jobs: run: | ${{ github.workspace }}/configure \ --enable-aac \ + --enable-aptx \ + --enable-aptx-hd \ + --with-libopenaptx \ --enable-faststream \ --enable-mp3lame \ --enable-mpg123 \ diff --git a/.github/workflows/code-scanning.yaml b/.github/workflows/code-scanning.yaml index 496faa658..b6fb4c749 100644 --- a/.github/workflows/code-scanning.yaml +++ b/.github/workflows/code-scanning.yaml @@ -41,6 +41,7 @@ jobs: libglib2.0-dev libmp3lame-dev libmpg123-dev + libopenaptx-dev libncurses5-dev libreadline-dev libsbc-dev @@ -60,6 +61,9 @@ jobs: run: | ${{ github.workspace }}/configure \ --enable-aac \ + --enable-aptx \ + --enable-aptx-hd \ + --with-libopenaptx \ --enable-faststream \ --enable-mp3lame \ --enable-mpg123 \ @@ -106,6 +110,7 @@ jobs: libglib2.0-dev libmp3lame-dev libmpg123-dev + libopenaptx-dev libncurses5-dev libreadline-dev libsbc-dev @@ -119,9 +124,12 @@ jobs: working-directory: ${{ github.workspace }}/build run: | ${{ github.workspace }}/configure \ - --enable-aac \ --enable-debug \ --enable-debug-time \ + --enable-aac \ + --enable-aptx \ + --enable-aptx-hd \ + --with-libopenaptx \ --enable-faststream \ --enable-mp3lame \ --enable-mpg123 \ diff --git a/.github/workflows/codecov-report.yaml b/.github/workflows/codecov-report.yaml index 2125416a7..ff56bd607 100644 --- a/.github/workflows/codecov-report.yaml +++ b/.github/workflows/codecov-report.yaml @@ -27,6 +27,7 @@ jobs: libglib2.0-dev libmp3lame-dev libmpg123-dev + libopenaptx-dev libsbc-dev libspandsp-dev - uses: actions/checkout@v4 @@ -39,6 +40,9 @@ jobs: run: | ${{ github.workspace }}/configure \ --enable-aac \ + --enable-aptx \ + --enable-aptx-hd \ + --with-libopenaptx \ --enable-faststream \ --enable-mp3lame \ --enable-mpg123 \ diff --git a/NEWS b/NEWS index b7883c070..53238f6a4 100644 --- a/NEWS +++ b/NEWS @@ -7,6 +7,7 @@ unreleased - fix for SBC codec and audio scaling on big-endian platforms - fix mSBC decode for MTU > 60 bytes (e.g. Realtek USB adapters) - bluealsa-aplay: option to auto-select volume mode for used PCM +- support use of libfreeaptx for apt-X and apt-X HD codecs bluez-alsa v4.1.1 (2023-06-24) ============================== diff --git a/configure.ac b/configure.ac index 99be7217b..d3ae83a99 100644 --- a/configure.ac +++ b/configure.ac @@ -113,6 +113,20 @@ AC_ARG_WITH([libopenaptx], [AS_HELP_STRING([--with-libopenaptx], [use libopenaptx by pali.rohar for apt-X (HD)])]) AM_CONDITIONAL([WITH_LIBOPENAPTX], [test "x$with_libopenaptx" = "xyes"]) +AC_ARG_WITH([libfreeaptx], + [AS_HELP_STRING([--with-libfreeaptx], [use libfreeaptx for apt-X (HD)])]) +AM_CONDITIONAL([WITH_LIBFREEAPTX], [test "x$with_libfreeaptx" = "xyes"]) + +# one of libopenaptx or libfreeaptx have been selected +AM_CONDITIONAL([WITH_lIBOPENAPTX_OR_WITH_LIBFREEAPTX], + [test "x$with_libopenaptx" = "xyes" -o "x$with_libfreeaptx" = "xyes"]) + +# both libopenaptx and libfreeaptx have been selected +AM_CONDITIONAL([WITH_lIBOPENAPTX_AND_WITH_LIBFREEAPTX], + [test "x$with_libopenaptx" = "xyes" -a "x$with_libfreeaptx" = "xyes"]) +AM_COND_IF([WITH_lIBOPENAPTX_AND_WITH_LIBFREEAPTX], + [AC_MSG_ERROR([select at most one of libopenaptx or libfreeaptx])]) + AC_ARG_ENABLE([aptx], [AS_HELP_STRING([--enable-aptx], [enable apt-X support])]) AM_CONDITIONAL([ENABLE_APTX], [test "x$enable_aptx" = "xyes"]) @@ -122,10 +136,16 @@ AM_COND_IF([ENABLE_APTX], [ AC_DEFINE([HAVE_APTX_DECODE], [1], [Define to 1 if you have apt-X decode library.]) AC_DEFINE([WITH_LIBOPENAPTX], [1], [Define to 1 if libopenaptx shall be used.]) ], [ - PKG_CHECK_MODULES([APTX], [openaptx >= 1.2.0]) - if test "$($PKG_CONFIG --variable=aptxdecoder openaptx)" = "true"; then + AM_COND_IF([WITH_LIBFREEAPTX], [ + PKG_CHECK_MODULES([APTX], [libfreeaptx >= 0.1.1]) AC_DEFINE([HAVE_APTX_DECODE], [1], [Define to 1 if you have apt-X decode library.]) - fi + AC_DEFINE([WITH_LIBFREEAPTX], [1], [Define to 1 if libfreeaptx shall be used.]) + ], [ + PKG_CHECK_MODULES([APTX], [openaptx >= 1.2.0]) + if test "$($PKG_CONFIG --variable=aptxdecoder openaptx)" = "true"; then + AC_DEFINE([HAVE_APTX_DECODE], [1], [Define to 1 if you have apt-X decode library.]) + fi + ]) ]) AC_DEFINE([ENABLE_APTX], [1], [Define to 1 if apt-X is enabled.]) ]) @@ -139,10 +159,16 @@ AM_COND_IF([ENABLE_APTX_HD], [ AC_DEFINE([HAVE_APTX_HD_DECODE], [1], [Define to 1 if you have apt-X HD decode library.]) AC_DEFINE([WITH_LIBOPENAPTX], [1], [Define to 1 if libopenaptx shall be used.]) ], [ - PKG_CHECK_MODULES([APTX_HD], [openaptxhd >= 1.2.0]) - if test "$($PKG_CONFIG --variable=aptxdecoder openaptxhd)" = "true"; then + AM_COND_IF([WITH_LIBFREEAPTX], [ + PKG_CHECK_MODULES([APTX_HD], [libfreeaptx >= 0.1.1]) AC_DEFINE([HAVE_APTX_HD_DECODE], [1], [Define to 1 if you have apt-X HD decode library.]) - fi + AC_DEFINE([WITH_LIBFREEAPTX], [1], [Define to 1 if libfreeaptx shall be used.]) + ], [ + PKG_CHECK_MODULES([APTX], [openaptx >= 1.2.0]) + if test "$($PKG_CONFIG --variable=aptxdecoder openaptxhd)" = "true"; then + AC_DEFINE([HAVE_APTX_HD_DECODE], [1], [Define to 1 if you have apt-X HD decode library.]) + fi + ]) ]) AC_DEFINE([ENABLE_APTX_HD], [1], [Define to 1 if apt-X HD is enabled.]) ]) @@ -407,12 +433,13 @@ AM_COND_IF([ALSA_1_1_2__1_1_3], [ AC_MSG_WARN([LIBASOUND_THREAD_SAFE=0 while using bluealsa PCM.]) ]) -# notify user that using libopenaptx might be a good idea +# notify user that using libopenaptx or libfreeaptx might be a good idea AM_COND_IF([ENABLE_APTX_OR_APTX_HD], [ -AM_COND_IF([WITH_LIBOPENAPTX], [], [ +AM_COND_IF([WITH_lIBOPENAPTX_OR_WITH_LIBFREEAPTX], [], [ AC_MSG_NOTICE([ *** using apt-X (HD) via Qualcomm API ***]) AC_MSG_NOTICE([Enabled apt-X (HD) support requires encoder (and decoder)]) AC_MSG_NOTICE([library with a proprietary Qualcomm API. Please consider]) - AC_MSG_NOTICE([using --with-libopenaptx option which will use a library]) - AC_MSG_NOTICE([based on FFmpeg project with better decoding support.]) + AC_MSG_NOTICE([using --with-libopenaptx or --with-libfreeaptx option]) + AC_MSG_NOTICE([which will use a library based on FFmpeg project with]) + AC_MSG_NOTICE([better decoding support.]) ])]) diff --git a/src/a2dp-aptx.c b/src/a2dp-aptx.c index 0d0445475..d2c463b2c 100644 --- a/src/a2dp-aptx.c +++ b/src/a2dp-aptx.c @@ -16,7 +16,6 @@ #include #include -#include #include #include #include diff --git a/src/codec-aptx.c b/src/codec-aptx.c index bb991b8e3..a3f056fb9 100644 --- a/src/codec-aptx.c +++ b/src/codec-aptx.c @@ -1,6 +1,6 @@ /* * BlueALSA - codec-aptx.c - * Copyright (c) 2016-2021 Arkadiusz Bokowy + * Copyright (c) 2016-2024 Arkadiusz Bokowy * * This file is a part of bluez-alsa. * @@ -9,18 +9,20 @@ */ #include "codec-aptx.h" -/* IWYU pragma: no_include "config.h" */ -#include +#if HAVE_CONFIG_H +# include +#endif + #include -#include -#include #include -#include +#if !(WITH_LIBOPENAPTX || WITH_LIBFREEAPTX) +# include +# include +#endif #include -#include "shared/defs.h" #include "shared/log.h" #if ENABLE_APTX @@ -30,7 +32,7 @@ * @returns On success, this function returns initialized apt-X encoder * handler. On error, NULL is returned. */ HANDLE_APTX aptxenc_init(void) { -#if WITH_LIBOPENAPTX +#if WITH_LIBOPENAPTX || WITH_LIBFREEAPTX return aptx_init(0); #else APTXENC handle; @@ -51,7 +53,7 @@ HANDLE_APTX aptxenc_init(void) { * @returns On success, this function returns initialized apt-X decoder * handler. On error, NULL is returned. */ HANDLE_APTX aptxdec_init(void) { -#if WITH_LIBOPENAPTX +#if WITH_LIBOPENAPTX || WITH_LIBFREEAPTX return aptx_init(0); #else APTXDEC handle; @@ -72,7 +74,7 @@ HANDLE_APTX aptxdec_init(void) { * @returns On success, this function returns initialized apt-X encoder * handler. On error, NULL is returned. */ HANDLE_APTX aptxhdenc_init(void) { -#if WITH_LIBOPENAPTX +#if WITH_LIBOPENAPTX || WITH_LIBFREEAPTX return aptx_init(1); #else APTXENC handle; @@ -93,7 +95,7 @@ HANDLE_APTX aptxhdenc_init(void) { * @returns On success, this function returns initialized apt-X decoder * handler. On error, NULL is returned. */ HANDLE_APTX aptxhddec_init(void) { -#if WITH_LIBOPENAPTX +#if WITH_LIBOPENAPTX || WITH_LIBFREEAPTX return aptx_init(1); #else APTXDEC handle; @@ -119,7 +121,7 @@ ssize_t aptxenc_encode(HANDLE_APTX handle, const int16_t *input, size_t samples, if (samples < 8 || *len < 4) return errno = EINVAL, -1; -#if WITH_LIBOPENAPTX +#if WITH_LIBOPENAPTX || WITH_LIBFREEAPTX const uint8_t pcm[3 /* 24bit */ * 8 /* 4 samples * 2 channels */] = { 0, input[0], input[0] >> 8, 0, input[1], input[1] >> 8, @@ -161,7 +163,7 @@ ssize_t aptxdec_decode(HANDLE_APTX handle, const void *input, size_t len, if (len < 4 || *samples < 8) return errno = EINVAL, -1; -#if WITH_LIBOPENAPTX +#if WITH_LIBOPENAPTX || WITH_LIBFREEAPTX uint8_t pcm[3 /* 24bit */ * 8 /* 4 samples * 2 channels */ * 2]; size_t written, dropped; @@ -190,7 +192,7 @@ ssize_t aptxdec_decode(HANDLE_APTX handle, const void *input, size_t len, return -1; size_t i; - for (i = 0; i < ARRAYSIZE(pcm_l); i++) { + for (i = 0; i < 4; i++) { *output++ = pcm_l[i]; *output++ = pcm_r[i]; } @@ -214,7 +216,7 @@ ssize_t aptxhdenc_encode(HANDLE_APTX handle, const int32_t *input, size_t sample if (samples < 8 || *len < 6) return errno = EINVAL, -1; -#if WITH_LIBOPENAPTX +#if WITH_LIBOPENAPTX || WITH_LIBFREEAPTX const uint8_t pcm[3 /* 24bit */ * 8 /* 4 samples * 2 channels */] = { input[0], input[0] >> 8, input[0] >> 16, input[1], input[1] >> 8, input[1] >> 16, @@ -264,7 +266,7 @@ ssize_t aptxhddec_decode(HANDLE_APTX handle, const void *input, size_t len, if (len < 6 || *samples < 8) return errno = EINVAL, -1; -#if WITH_LIBOPENAPTX +#if WITH_LIBOPENAPTX || WITH_LIBFREEAPTX uint8_t pcm[3 /* 24bit */ * 8 /* 4 samples * 2 channels */ * 2]; size_t written, dropped; @@ -300,7 +302,7 @@ ssize_t aptxhddec_decode(HANDLE_APTX handle, const void *input, size_t len, return -1; size_t i; - for (i = 0; i < ARRAYSIZE(pcm_l); i++) { + for (i = 0; i < 4; i++) { *output++ = pcm_l[i]; *output++ = pcm_r[i]; } @@ -318,7 +320,7 @@ ssize_t aptxhddec_decode(HANDLE_APTX handle, const void *input, size_t len, * * @param handle Initialized encoder handler. */ void aptxenc_destroy(HANDLE_APTX handle) { -#if WITH_LIBOPENAPTX +#if WITH_LIBOPENAPTX || WITH_LIBFREEAPTX aptx_finish(handle); #else if (aptxbtenc_destroy != NULL) @@ -334,7 +336,7 @@ void aptxenc_destroy(HANDLE_APTX handle) { * * @param handle Initialized decoder handler. */ void aptxdec_destroy(HANDLE_APTX handle) { -#if WITH_LIBOPENAPTX +#if WITH_LIBOPENAPTX || WITH_LIBFREEAPTX aptx_finish(handle); #else aptxbtdec_destroy(handle); @@ -349,7 +351,7 @@ void aptxdec_destroy(HANDLE_APTX handle) { * * @param handle Initialized encoder handler. */ void aptxhdenc_destroy(HANDLE_APTX handle) { -#if WITH_LIBOPENAPTX +#if WITH_LIBOPENAPTX || WITH_LIBFREEAPTX aptx_finish(handle); #else if (aptxhdbtenc_destroy != NULL) @@ -365,7 +367,7 @@ void aptxhdenc_destroy(HANDLE_APTX handle) { * * @param handle Initialized decoder handler. */ void aptxhddec_destroy(HANDLE_APTX handle) { -#if WITH_LIBOPENAPTX +#if WITH_LIBOPENAPTX || WITH_LIBFREEAPTX aptx_finish(handle); #else aptxhdbtdec_destroy(handle);