ref: 867e2c23d814b664cea10acae920a3fb698c3656
parent: 4428da8ac391ce16d34bff8d9e685fee7ab8983e
author: cbagwell <cbagwell>
date: Sun Nov 29 15:55:56 EST 2009
Add support for dlopen() of amr-nb and amr-wb libraries.
--- a/ChangeLog
+++ b/ChangeLog
@@ -52,6 +52,8 @@
based formats). (cbagwell)
o Allow libsndfile to be dlopen()'ed at runtime if --enable-dl-sndfile
is used. (Doug Cook)
+ o Allow amr-nb/amr-wb to be dlopen()'ed at runtime if
+ --enable-dl-amrwb or --enable-dl-amrnb is used. (Doug Cook)
o amrnb and amrwb formats can optionally use opencore-amr libraries.
(cbagwell)
--- a/INSTALL
+++ b/INSTALL
@@ -156,6 +156,8 @@
--enable-dl-lame
--enable-dl-mad
--enable-dl-sndfile
+--enable-dl-amrnb
+--enable-dl-amrwb
Testing
-------
--- a/configure.ac
+++ b/configure.ac
@@ -408,18 +408,33 @@
AC_OPTIONAL_FORMAT(flac, FLAC, [AC_CHECK_HEADER(FLAC/all.h, [AC_CHECK_LIB(FLAC, FLAC__stream_encoder_new, FLAC_LIBS="-lFLAC $FLAC_LIBS $OGG_VORBIS_LIBS",using_flac=no, $FLAC_LIBS $OGG_VORBIS_LIBS)], using_flac=no)])
-
+dnl When enable_dl_amrbw, do not let add libraries to be linked in
+dnl since they will be dlopen()'ed instead.
+ac_sox_save_AMRWB_LIBS="$AMRWB_LIBS"
AC_OPTIONAL_FORMAT(amrwb, AMRWB,
[AC_CHECK_HEADERS(opencore-amrwb/dec_if.h,
[AC_CHECK_LIB(opencore-amrwb, D_IF_init,
- AMRNB_LIBS="$AMRWB_LIBS -lopencore-amrwb", using_amrwb=no)],
+ AMRWB_LIBS="$AMRWB_LIBS -lopencore-amrwb", using_amrwb=no)],
[AC_CHECK_HEADERS(amrwb/dec.h,
[AC_CHECK_LIB(amrwb, D_IF_init,
AMRWB_LIBS="$AMRWB_LIBS -lamrwb",using_amrwb=no)],
using_amrwb=no)])])
+AC_ARG_ENABLE(dl_amrwb,
+ AC_HELP_STRING([--enable-dl-amrwb],
+ [Dlopen amrbw instead of linking in.]),
+ enable_dl_amrwb=$enableval, enable_dl_amrwb=no)
+if test "x$using_amrwb" = "xyes"; then
+ if test "x$using_libltdl" = "xyes" -a "x$enable_dl_amrwb" = "xyes"; then
+ AC_DEFINE(DL_AMRWB, 1, [Define to dlopen() amrwb.])
+ dnl When enable_dl_amrwb, do not let SOX_PATH_AMRWB add libraries
+ dnl to be linked in (since they will be dlopen()'ed instead).
+ AMRWB_LIBS="$ac_sox_save_AMRWB_LIBS"
+ fi
+fi
-
-
+dnl When enable_dl_amrnb, do not let add libraries to be linked in
+dnl since they will be dlopen()'ed instead.
+ac_sox_save_AMRNB_LIBS="$AMRNB_LIBS"
AC_OPTIONAL_FORMAT(amrnb, AMRNB,
[AC_CHECK_HEADERS(opencore-amrnb/interf_dec.h,
[AC_CHECK_LIB(opencore-amrnb, Decoder_Interface_init,
@@ -428,6 +443,18 @@
[AC_CHECK_LIB(amrnb, Decoder_Interface_init,
AMRNB_LIBS="$AMRNB_LIBS -lamrnb", using_amrnb=no)],
using_amrnb=no)])])
+AC_ARG_ENABLE(dl_amrnb,
+ AC_HELP_STRING([--enable-dl-amrnb],
+ [Dlopen amrnb instead of linking in.]),
+ enable_dl_amrnb=$enableval, enable_dl_amrnb=no)
+if test "x$using_amrnb" = "xyes"; then
+ if test "x$using_libltdl" = "xyes" -a "x$enable_dl_amrnb" = "xyes"; then
+ AC_DEFINE(DL_AMRNB, 1, [Define to dlopen() amrnb.])
+ dnl When enable_dl_amrnb, do not let SOX_PATH_AMRNB add libraries
+ dnl to be linked in (since they will be dlopen()'ed instead).
+ AMRNB_LIBS="$ac_sox_save_AMRNB_LIBS"
+ fi
+fi
AC_OPTIONAL_FORMAT(wavpack, WAVPACK, [AC_CHECK_HEADER(wavpack/wavpack.h, [AC_CHECK_LIB(wavpack, WavpackGetSampleRate, WAVPACK_LIBS="$WAVPACK_LIBS -lwavpack",using_wavpack=no)], using_wavpack=no)])
@@ -586,7 +613,13 @@
echo
echo "OPTIONAL FILE FORMATS"
echo "amrnb......................$using_amrnb"
+if test "x$using_amrnb" = "xyes"; then
+echo " dlopen amrnb..............$enable_dl_amrnb"
+fi
echo "amrwb......................$using_amrwb"
+if test "x$using_amrwb" = "xyes"; then
+echo " dlopen amrwb..............$enable_dl_amrwb"
+fi
echo "ffmpeg.....................$using_ffmpeg"
echo "flac.......................$using_flac"
echo "gsm........................$using_gsm $gsm_option"
--- a/src/amr-nb.c
+++ b/src/amr-nb.c
@@ -22,29 +22,66 @@
#include "sox_i.h"
+#ifdef HAVE_AMRNB
+
#ifdef HAVE_OPENCORE_AMRNB_INTERF_DEC_H
-#include "opencore-amrnb/interf_dec.h"
-#else
-#include "amrnb/typedef.h"
-#include "amrnb/interf_dec.h"
-#include "amrnb/sp_dec.h"
-#endif
-#define Mode _Mode
-#define MR102 _MR102
-#define MR122 _MR122
-#define MR475 _MR475
-#define MR515 _MR515
-#define MR59 _MR59
-#define MR67 _MR67
-#define MR74 _MR74
-#define MR795 _MR795
-#define MRDTX _MRDTX
-#ifdef HAVE_OPENCORE_AMRNB_INTERF_DEC_H
-#include "opencore-amrnb/interf_enc.h"
-#else
-#include "amrnb/interf_enc.h"
-#endif
+ enum Mode { amrnb_mode_dummy };
+
+ int Encoder_Interface_Encode(void* state, enum Mode mode, const short* speech, unsigned char* out, int forceSpeech);
+ void* Encoder_Interface_init(int dtx);
+ void Encoder_Interface_exit(void* state);
+ void Decoder_Interface_Decode(void* state, const unsigned char* in, short* out, int bfi);
+ void* Decoder_Interface_init(void);
+ void Decoder_Interface_exit(void* state);
+
+#define AMR_FUNC_ENTRIES(f,x) \
+ AMR_FUNC(f,x, int, Encoder_Interface_Encode, (void* state, enum Mode mode, const short* speech, unsigned char* out, int forceSpeech)) \
+ AMR_FUNC(f,x, void*, Encoder_Interface_init, (int dtx)) \
+ AMR_FUNC(f,x, void, Encoder_Interface_exit, (void* state)) \
+ AMR_FUNC(f,x, void, Decoder_Interface_Decode, (void* state, const unsigned char* in, short* out, int bfi)) \
+ AMR_FUNC(f,x, void*, Decoder_Interface_init, (void)) \
+ AMR_FUNC(f,x, void, Decoder_Interface_exit, (void* state))
+
+#define D_IF_decode Decoder_Interface_Decode
+#define D_IF_exit Decoder_Interface_exit
+#define D_IF_init Decoder_Interface_init
+#define E_IF_encode Encoder_Interface_Encode
+#define E_IF_exit Encoder_Interface_exit
+#define E_IF_init() Encoder_Interface_init(1)
+
+#else /* HAVE_OPENCORE_AMRNB_INTERF_DEC_H */
+
+enum amrnb_mode { amrnb_mode_dummy };
+
+int GP3VADxEncoder_Interface_Encode(void *st, enum amrnb_mode mode, short *speech, unsigned char *serial, int forceSpeech, char vad2_code);
+void *VADxEncoder_Interface_init(int dtx, char vad2_code);
+void Encoder_Interface_exit(void *state);
+void GP3Decoder_Interface_Decode(void *st, unsigned char *bits, short *synth, int bfi);
+void *Decoder_Interface_init(void);
+void Decoder_Interface_exit(void *state);
+
+#define AMR_FUNC_ENTRIES(f,x) \
+ AMR_FUNC(f,x, int, GP3VADxEncoder_Interface_Encode, (void *st, enum amrnb_mode mode, short *speech, unsigned char *serial, int forceSpeech, char vad2_code)) \
+ AMR_FUNC(f,x, void*, VADxEncoder_Interface_init, (int dtx, char vad2_code)) \
+ AMR_FUNC(f,x, void, Encoder_Interface_exit, (void *state)) \
+ AMR_FUNC(f,x, void, GP3Decoder_Interface_Decode, (void *st, unsigned char *bits, short *synth, int bfi)) \
+ AMR_FUNC(f,x, void*, Decoder_Interface_init, (void)) \
+ AMR_FUNC(f,x, void, Decoder_Interface_exit, (void *state))
+
+#define E_IF_encode(st,m,sp,ser,fs) \
+ GP3VADxEncoder_Interface_Encode(st,m,sp,ser,fs,0)
+#define E_IF_init() VADxEncoder_Interface_init(1,0)
+#define E_IF_exit Encoder_Interface_exit
+#define D_IF_decode GP3Decoder_Interface_Decode
+#define D_IF_init Decoder_Interface_init
+#define D_IF_exit Decoder_Interface_exit
+
+#endif /* HAVE_OPENCORE_AMRNB_INTERF_DEC_H */
+
+static const unsigned amrnb_block_size[] = {13,14,16,18,20,21,27,32,6,0,0,0,0,0,0,1};
+#define block_size amrnb_block_size
+
static char const magic[] = "#!AMR\n";
#define AMR_CODED_MAX 32 /* max coded size */
#define AMR_ENCODING SOX_ENCODING_AMR_NB
@@ -53,11 +90,32 @@
#define AMR_MODE_MAX 7
#define AMR_NAMES "amr-nb", "anb"
#define AMR_RATE 8000
-#define D_IF_decode Decoder_Interface_Decode
-#define D_IF_exit Decoder_Interface_exit
-#define D_IF_init Decoder_Interface_init
-#define E_IF_encode Encoder_Interface_Encode
-#define E_IF_exit Encoder_Interface_exit
-#define E_IF_init() Encoder_Interface_init(1)
-static const unsigned block_size[] = {13,14,16,18,20,21,27,32,6,1,1,1,1,1,1,1};
+#define AMR_DESC "amr-nb library"
+
+#if !defined(HAVE_LIBLTDL)
+#undef DL_AMRNB
+#endif
+
+static const char* const amr_library_names[] =
+{
+#ifdef DL_AMRNB
+#ifdef HAVE_OPENCORE_AMRNB_INTERF_DEC_H
+ "libopencore-amrnb",
+#else
+ "libamrnb-3",
+ "libamrnb",
+ "amrnb",
+#endif
+#endif
+ NULL
+};
+
+#ifdef DL_AMRNB
+ #define AMR_FUNC LSX_DLENTRY_DYNAMIC
+#else
+ #define AMR_FUNC LSX_DLENTRY_STATIC
+#endif /* DL_AMRNB */
+
#include "amr.h"
+
+#endif /* HAVE_AMRNB */
--- a/src/amr-wb.c
+++ b/src/amr-wb.c
@@ -22,26 +22,80 @@
#include "sox_i.h"
+#ifdef HAVE_AMRWB
+
#ifdef HAVE_OPENCORE_AMRWB_DEC_IF_H
-#include "opencore-amrwb/dec_if.h"
-#include "opencore-amrwb/if_rom.h"
+
#define DISABLE_AMR_WB_ENCODE
-#else
-#include "amrwb/typedef.h"
-#include "amrwb/enc_if.h"
-#include "amrwb/dec_if.h"
-#include "amrwb/if_rom.h"
-#endif
+ void D_IF_decode(void* state, const unsigned char* bits, short* synth, int bfi);
+ void* D_IF_init(void);
+ void D_IF_exit(void* state);
+
+#define AMR_FUNC_ENTRIES(f,x) \
+ AMR_FUNC(f,x, void, D_IF_decode,(void* state, const unsigned char* bits, short* synth, int bfi)) \
+ AMR_FUNC(f,x, void*, D_IF_init, (void)) \
+ AMR_FUNC(f,x, void, D_IF_exit, (void* state))
+
+#else /* HAVE_OPENCORE_AMRWB_DEC_IF_H */
+
+ int GP3E_IF_encode(void *st, int16_t mode, int16_t *speech, uint8_t *serial, int16_t dtx);
+ void *E_IF_init(void);
+ void E_IF_exit(void *state);
+ void GP3D_IF_decode(void *st, uint8_t *bits, int16_t *synth, int32_t bfi);
+ void * D_IF_init(void);
+ void D_IF_exit(void *state);
+
+#define AMR_FUNC_ENTRIES(f,x) \
+ AMR_FUNC(f,x, int, GP3E_IF_encode,(void *st, int16_t mode, int16_t *speech, uint8_t *serial, int16_t dtx)) \
+ AMR_FUNC(f,x, void*, E_IF_init, (void)) \
+ AMR_FUNC(f,x, void, E_IF_exit, (void *state)) \
+ AMR_FUNC(f,x, void, GP3D_IF_decode,(void *st, uint8_t *bits, int16_t *synth, int32_t bfi)) \
+ AMR_FUNC(f,x, void*, D_IF_init, (void)) \
+ AMR_FUNC(f,x, void, D_IF_exit, (void *state))
+
+#define D_IF_decode GP3D_IF_decode
+#define E_IF_encode GP3E_IF_encode
+
+#endif /* HAVE_OPENCORE_AMRWB_DEC_IF_H */
+
+static const uint8_t amrwb_block_size[16]= {18, 24, 33, 37, 41, 47, 51, 59, 61, 6, 6, 0, 0, 0, 1, 1};
+#define block_size amrwb_block_size
+
static char const magic[] = "#!AMR-WB\n";
-#define AMR_CODED_MAX 61 /* max serial size */
+#define AMR_CODED_MAX 61 /* NB_SERIAL_MAX */
#define AMR_ENCODING SOX_ENCODING_AMR_WB
#define AMR_FORMAT_FN lsx_amr_wb_format_fn
-#define AMR_FRAME 320 /* Frame size at 16kHz */
+#define AMR_FRAME 320 /* L_FRAME16k */
#define AMR_MODE_MAX 8
#define AMR_NAMES "amr-wb", "awb"
#define AMR_RATE 16000
+#define AMR_DESC "amr-wb library"
+
+#if !defined(HAVE_LIBLTDL)
+#undef DL_AMRWB
+#endif
+
+static const char* const amr_library_names[] =
+{
+#ifdef DL_AMRWB
#ifdef HAVE_OPENCORE_AMRWB_DEC_IF_H
-static const unsigned block_size[16] = {18, 24, 33, 37, 41, 47, 51, 59, 61, 6, 6, 0, 0, 0, 1, 1};
+ "libopencore-amrwb",
+#else
+ "libamrwb-3",
+ "libamrwb",
+ "amrwb",
#endif
+#endif
+ NULL
+};
+
+#ifdef DL_AMRWB
+ #define AMR_FUNC LSX_DLENTRY_DYNAMIC
+#else
+ #define AMR_FUNC LSX_DLENTRY_STATIC
+#endif /* DL_AMRWB */
+
#include "amr.h"
+
+#endif /* HAVE_AMRWB */
--- a/src/amr.h
+++ b/src/amr.h
@@ -23,6 +23,7 @@
unsigned mode;
short pcm[AMR_FRAME];
size_t pcm_index;
+ LSX_DLENTRIES_TO_PTRS(AMR_FUNC_ENTRIES, amr_dl);
} priv_t;
static size_t decode_1_frame(sox_format_t * ft)
@@ -36,7 +37,7 @@
n_1 = block_size[(coded[0] >> 3) & 0x0F] - 1;
if (lsx_readbuf(ft, &coded[1], n_1) != n_1)
return AMR_FRAME;
- D_IF_decode(p->state, coded, p->pcm, 0);
+ p->D_IF_decode(p->state, coded, p->pcm, 0);
return 0;
}
@@ -44,10 +45,8 @@
{
priv_t * p = (priv_t *)ft->priv;
char buffer[sizeof(magic) - 1];
+ int open_library_result;
- p->pcm_index = AMR_FRAME;
- p->state = D_IF_init();
-
if (lsx_readchars(ft, buffer, sizeof(buffer)))
return SOX_EOF;
if (memcmp(buffer, magic, sizeof(buffer))) {
@@ -54,6 +53,20 @@
lsx_fail_errno(ft, SOX_EHDR, "invalid magic number");
return SOX_EOF;
}
+
+ LSX_DLLIBRARY_OPEN(
+ p,
+ amr_dl,
+ AMR_FUNC_ENTRIES,
+ AMR_DESC,
+ amr_library_names,
+ open_library_result);
+ if (open_library_result)
+ return SOX_EOF;
+
+ p->pcm_index = AMR_FRAME;
+ p->state = p->D_IF_init();
+
ft->signal.rate = AMR_RATE;
ft->encoding.encoding = AMR_ENCODING;
ft->signal.channels = 1;
@@ -78,7 +91,8 @@
static int stopread(sox_format_t * ft)
{
priv_t * p = (priv_t *)ft->priv;
- D_IF_exit(p->state);
+ p->D_IF_exit(p->state);
+ LSX_DLLIBRARY_CLOSE(p, amr_dl);
return SOX_SUCCESS;
}
@@ -89,8 +103,10 @@
return SOX_EOF;
#else
priv_t * p = (priv_t *)ft->priv;
+ int open_library_result;
+
if (ft->encoding.compression != HUGE_VAL) {
- p->mode = ft->encoding.compression;
+ p->mode = (unsigned)ft->encoding.compression;
if (p->mode != ft->encoding.compression || p->mode > AMR_MODE_MAX) {
lsx_fail_errno(ft, SOX_EINVAL, "compression level must be a whole number from 0 to %i", AMR_MODE_MAX);
return SOX_EOF;
@@ -98,7 +114,20 @@
}
else p->mode = 0;
-#include "amr2.h"
+ LSX_DLLIBRARY_OPEN(
+ p,
+ amr_dl,
+ AMR_FUNC_ENTRIES,
+ AMR_DESC,
+ amr_library_names,
+ open_library_result);
+ if (open_library_result)
+ return SOX_EOF;
+
+#define IGNORE_WARNING \
+ p->state = p->E_IF_init();
+#include "ignore-warning.h"
+
lsx_writes(ft, magic);
p->pcm_index = 0;
return SOX_SUCCESS;
@@ -110,7 +139,9 @@
{
priv_t * p = (priv_t *)ft->priv;
uint8_t coded[AMR_CODED_MAX];
-#include "amr1.h"
+#define IGNORE_WARNING \
+ int n = p->E_IF_encode(p->state, p->mode, p->pcm, coded, 1);
+#include "ignore-warning.h"
sox_bool result = lsx_writebuf(ft, coded, (size_t) (size_t) (unsigned)n) == (unsigned)n;
if (!result)
lsx_fail_errno(ft, errno, "write error");
@@ -154,7 +185,7 @@
if (!encode_1_frame(ft))
result = SOX_EOF;
}
- E_IF_exit(p->state);
+ p->E_IF_exit(p->state);
return result;
}
#endif