shithub: sox

Download patch

ref: 0b885112668a2d1acb1a038041c78ab24bb908cf
parent: b110c3bea3ecf032acc4e710e6683b2e5738dfd8
author: idigdoug <idigdoug>
date: Thu Dec 17 00:19:20 EST 2009

Make AMR formats be able to dlopen either 3GPP or OpenCore shared library.

--- a/src/amr-nb.c
+++ b/src/amr-nb.c
@@ -24,65 +24,18 @@
 
 #ifdef HAVE_AMRNB
 
-#ifdef HAVE_OPENCORE_AMRNB_INTERF_DEC_H
+/* Common definitions: */
 
-  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);
+static const unsigned amrnb_block_size[] = {13, 14, 16, 18, 20, 21, 27, 32, 6, 0, 0, 0, 0, 0, 0, 1};
+static char const amrnb_magic[] = "#!AMR\n";
+#define amr_block_size amrnb_block_size
+#define amr_magic amrnb_magic
+#define amr_priv_t amrnb_priv_t
+#define amr_opencore_funcs amrnb_opencore_funcs
+#define amr_gp3_funcs amrnb_gp3_funcs
 
-#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
 #define AMR_FORMAT_FN       lsx_amr_nb_format_fn
@@ -90,32 +43,94 @@
 #define AMR_MODE_MAX        7
 #define AMR_NAMES           "amr-nb", "anb"
 #define AMR_RATE            8000
-#define AMR_DESC            "amr-nb library"
+#define AMR_DESC            "3GPP Adaptive Multi Rate Narrow-Band (AMR-NB) lossy speech compressor"
 
 #if !defined(HAVE_LIBLTDL)
-#undef DL_AMRNB
+  #undef DL_AMRNB
 #endif
 
-static const char* const amr_library_names[] =
-{
 #ifdef DL_AMRNB
-#ifdef HAVE_OPENCORE_AMRNB_INTERF_DEC_H
-  "libopencore-amrnb",
+  #define AMR_FUNC  LSX_DLENTRY_DYNAMIC
 #else
+  #define AMR_FUNC  LSX_DLENTRY_STATIC
+#endif /* DL_AMRNB */
+
+/* OpenCore definitions: */
+
+#if defined(HAVE_OPENCORE_AMRNB_INTERF_DEC_H) || defined(DL_AMRNB)
+  #define AMR_OPENCORE 1
+  #define AMR_OPENCORE_ENABLE_ENCODE 1
+#endif
+
+#define AMR_OPENCORE_FUNC_ENTRIES(f,x) \
+  AMR_FUNC(f,x, void*, Encoder_Interface_init,   (int dtx)) \
+  AMR_FUNC(f,x, int,   Encoder_Interface_Encode, (void* state, enum amrnb_mode mode, const short* in, unsigned char* out, int forceSpeech)) \
+  AMR_FUNC(f,x, void,  Encoder_Interface_exit,   (void* state)) \
+  AMR_FUNC(f,x, void*, Decoder_Interface_init,   (void)) \
+  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_exit,   (void* state)) \
+
+#define AmrOpencoreEncoderInit() \
+  Encoder_Interface_init(1)
+#define AmrOpencoreEncoderEncode(state, mode, in, out, forceSpeech) \
+  Encoder_Interface_Encode(state, mode, in, out, forceSpeech)
+#define AmrOpencoreEncoderExit(state) \
+  Encoder_Interface_exit(state)
+#define AmrOpencoreDecoderInit() \
+  Decoder_Interface_init()
+#define AmrOpencoreDecoderDecode(state, in, out, bfi) \
+  Decoder_Interface_Decode(state, in, out, bfi)
+#define AmrOpencoreDecoderExit(state) \
+  Decoder_Interface_exit(state)
+
+#define AMR_OPENCORE_DESC "amr-nb OpenCore library"
+static const char* const amr_opencore_library_names[] =
+{
+#ifdef DL_AMRWB
+  "libopencore-amrnb",
+#endif
+  NULL
+};
+
+/* 3GPP (reference implementation) definitions: */
+
+#if !defined(HAVE_OPENCORE_AMRNB_INTERF_DEC_H) || defined(DL_AMRNB)
+  #define AMR_GP3 1
+#endif
+
+#define AMR_GP3_FUNC_ENTRIES(f,x) \
+  AMR_FUNC(f,x, void*, VADxEncoder_Interface_init,      (int dtx, char vad2_code)) \
+  AMR_FUNC(f,x, int,   GP3VADxEncoder_Interface_Encode, (void* state, enum amrnb_mode mode, short* in, unsigned char* out, int forceSpeech, char vad2_code)) \
+  AMR_FUNC(f,x, void,  Encoder_Interface_exit,          (void* state)) \
+  AMR_FUNC(f,x, void*, Decoder_Interface_init,          (void)) \
+  AMR_FUNC(f,x, void,  GP3Decoder_Interface_Decode,     (void* state, unsigned char* in, short* out, int bfi)) \
+  AMR_FUNC(f,x, void,  Decoder_Interface_exit,          (void* state)) \
+
+#define AmrGp3EncoderInit() \
+  VADxEncoder_Interface_init(1, 0)
+#define AmrGp3EncoderEncode(state, mode, in, out, forceSpeech) \
+  GP3VADxEncoder_Interface_Encode(state, mode, in, out, forceSpeech, 0)
+#define AmrGp3EncoderExit(state) \
+  Encoder_Interface_exit(state)
+#define AmrGp3DecoderInit() \
+  Decoder_Interface_init()
+#define AmrGp3DecoderDecode(state, in, out, bfi) \
+  GP3Decoder_Interface_Decode(state, in, out, bfi)
+#define AmrGp3DecoderExit(state) \
+  Decoder_Interface_exit(state)
+
+#define AMR_GP3_DESC "amr-nb 3GPP reference library"
+static const char* const amr_gp3_library_names[] =
+{
+#ifdef DL_AMRWB
   "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 */
+    
\ No newline at end of file
--- a/src/amr-wb.c
+++ b/src/amr-wb.c
@@ -24,45 +24,16 @@
 
 #ifdef HAVE_AMRWB
 
-#ifdef HAVE_OPENCORE_AMRWB_DEC_IF_H
+/* Common definitions: */
 
-#define DISABLE_AMR_WB_ENCODE
+static const uint8_t amrwb_block_size[] = {18, 24, 33, 37, 41, 47, 51, 59, 61, 6, 6, 0, 0, 0, 1, 1};
+static char const amrwb_magic[] = "#!AMR-WB\n";
+#define amr_block_size amrwb_block_size
+#define amr_magic amrwb_magic
+#define amr_priv_t amrwb_priv_t
+#define amr_opencore_funcs amrwb_opencore_funcs
+#define amr_gp3_funcs amrwb_gp3_funcs
 
-  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 /* NB_SERIAL_MAX */
 #define AMR_ENCODING        SOX_ENCODING_AMR_WB
 #define AMR_FORMAT_FN       lsx_amr_wb_format_fn
@@ -70,31 +41,83 @@
 #define AMR_MODE_MAX        8
 #define AMR_NAMES           "amr-wb", "awb"
 #define AMR_RATE            16000
-#define AMR_DESC            "amr-wb library"
+#define AMR_DESC            "3GPP Adaptive Multi Rate Wide-Band (AMR-WB) lossy speech compressor"
 
 #if !defined(HAVE_LIBLTDL)
-#undef DL_AMRWB
+  #undef DL_AMRWB
 #endif
 
-static const char* const amr_library_names[] =
+#ifdef DL_AMRWB
+  #define AMR_FUNC  LSX_DLENTRY_DYNAMIC
+#else
+  #define AMR_FUNC  LSX_DLENTRY_STATIC
+#endif /* DL_AMRWB */
+
+/* OpenCore definitions: */
+
+#if defined(HAVE_OPENCORE_AMRWB_DEC_IF_H) || defined(DL_AMRWB)
+  #define AMR_OPENCORE 1
+  #define AMR_OPENCORE_ENABLE_ENCODE 0
+#endif
+
+#define AMR_OPENCORE_FUNC_ENTRIES(f,x) \
+  AMR_FUNC(f,x, void*, D_IF_init,   (void)) \
+  AMR_FUNC(f,x, void,  D_IF_decode, (void* state, const unsigned char* in, short* out, int bfi)) \
+  AMR_FUNC(f,x, void,  D_IF_exit,   (void* state)) \
+
+#define AmrOpencoreDecoderInit() \
+  D_IF_init()
+#define AmrOpencoreDecoderDecode(state, in, out, bfi) \
+  D_IF_decode(state, in, out, bfi)
+#define AmrOpencoreDecoderExit(state) \
+  D_IF_exit(state)
+
+#define AMR_OPENCORE_DESC "amr-wb OpenCore library"
+static const char* const amr_opencore_library_names[] =
 {
 #ifdef DL_AMRWB
-#ifdef HAVE_OPENCORE_AMRWB_DEC_IF_H
   "libopencore-amrwb",
-#else
+#endif
+  NULL
+};
+
+/* 3GPP (reference implementation) definitions: */
+
+#if !defined(HAVE_OPENCORE_AMRWB_DEC_IF_H) || defined(DL_AMRWB)
+  #define AMR_GP3 1
+#endif
+
+#define AMR_GP3_FUNC_ENTRIES(f,x) \
+  AMR_FUNC(f,x, void*, E_IF_init,     (void)) \
+  AMR_FUNC(f,x, int,   GP3E_IF_encode,(void* state, int16_t mode, int16_t* in, uint8_t* out, int16_t dtx)) \
+  AMR_FUNC(f,x, void,  E_IF_exit,     (void* state)) \
+  AMR_FUNC(f,x, void*, D_IF_init,     (void)) \
+  AMR_FUNC(f,x, void,  GP3D_IF_decode,(void* state, uint8_t* in, int16_t* out, int32_t bfi)) \
+  AMR_FUNC(f,x, void,  D_IF_exit,     (void* state)) \
+
+#define AmrGp3EncoderInit() \
+  E_IF_init()
+#define AmrGp3EncoderEncode(state, mode, in, out, forceSpeech) \
+  GP3E_IF_encode(state, mode, in, out, forceSpeech)
+#define AmrGp3EncoderExit(state) \
+  E_IF_exit(state)
+#define AmrGp3DecoderInit() \
+  D_IF_init()
+#define AmrGp3DecoderDecode(state, in, out, bfi) \
+  GP3D_IF_decode(state, in, out, bfi)
+#define AmrGp3DecoderExit(state) \
+  D_IF_exit(state)
+
+#define AMR_GP3_DESC "amr-wb 3GPP reference library"
+static const char* const amr_gp3_library_names[] =
+{
+#ifdef DL_AMRWB
   "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"
 
--- a/src/amr.h
+++ b/src/amr.h
@@ -18,12 +18,57 @@
 #include <string.h>
 #include <math.h>
 
-typedef struct {
-  void * state;
+#ifdef AMR_OPENCORE
+
+LSX_DLENTRIES_TO_FUNCTIONS(AMR_OPENCORE_FUNC_ENTRIES)
+
+typedef struct amr_opencore_funcs {
+  LSX_DLENTRIES_TO_PTRS(AMR_OPENCORE_FUNC_ENTRIES, amr_dl);
+} amr_opencore_funcs;
+
+#endif /* AMR_OPENCORE */
+
+#ifdef AMR_GP3
+
+LSX_DLENTRIES_TO_FUNCTIONS(AMR_GP3_FUNC_ENTRIES)
+
+typedef struct amr_gp3_funcs {
+  LSX_DLENTRIES_TO_PTRS(AMR_GP3_FUNC_ENTRIES, amr_dl);
+} amr_gp3_funcs;
+
+#endif /* AMR_GP3 */
+
+#if defined(AMR_OPENCORE) && defined (AMR_GP3)
+  #define AMR_CALL(p, opencoreFunc, gp3Func, args) \
+    ((p)->loaded_opencore ? ((p)->opencore.opencoreFunc args) : ((p)->gp3.gp3Func args))
+  #if AMR_OPENCORE_ENABLE_ENCODE
+    #define AMR_CALL_ENCODER AMR_CALL
+  #else
+    #define AMR_CALL_ENCODER(p, opencoreFunc, gp3Func, args) \
+      ((p)->gp3.gp3Func args)
+  #endif
+#elif defined(AMR_OPENCORE)
+  #define AMR_CALL(p, opencoreFunc, gp3Func, args) \
+    ((p)->opencore.opencoreFunc args)
+  #define AMR_CALL_ENCODER AMR_CALL
+#elif defined(AMR_GP3)
+  #define AMR_CALL(p, opencoreFunc, gp3Func, args) \
+    ((p)->gp3.gp3Func args)
+  #define AMR_CALL_ENCODER AMR_CALL
+#endif
+
+typedef struct amr_priv_t {
+  void* state;
   unsigned mode;
-  short pcm[AMR_FRAME];
   size_t pcm_index;
-  LSX_DLENTRIES_TO_PTRS(AMR_FUNC_ENTRIES, amr_dl);
+  int loaded_opencore;
+#ifdef AMR_OPENCORE
+  amr_opencore_funcs opencore;
+#endif /* AMR_OPENCORE */
+#ifdef AMR_GP3
+  amr_gp3_funcs gp3;
+#endif /* AMR_GP3 */
+  short pcm[AMR_FRAME];
 } priv_t;
 
 static size_t decode_1_frame(sox_format_t * ft)
@@ -34,38 +79,103 @@
 
   if (lsx_readbuf(ft, &coded[0], (size_t)1) != 1)
     return AMR_FRAME;
-  n_1 = block_size[(coded[0] >> 3) & 0x0F] - 1;
+  n_1 = amr_block_size[(coded[0] >> 3) & 0x0F] - 1;
   if (lsx_readbuf(ft, &coded[1], n_1) != n_1)
     return AMR_FRAME;
-  p->D_IF_decode(p->state, coded, p->pcm, 0);
+  AMR_CALL(p, AmrOpencoreDecoderDecode, AmrGp3DecoderDecode, (p->state, coded, p->pcm, 0));
   return 0;
 }
 
+static int openlibrary(priv_t* p, int encoding)
+{
+  int open_library_result;
+
+#ifdef AMR_OPENCORE
+  if (AMR_OPENCORE_ENABLE_ENCODE || !encoding)
+  {
+    LSX_DLLIBRARY_TRYOPEN(
+      0,
+      &p->opencore,
+      amr_dl,
+      AMR_OPENCORE_FUNC_ENTRIES,
+      AMR_OPENCORE_DESC,
+      amr_opencore_library_names,
+      open_library_result);
+    if (!open_library_result)
+    {
+      p->loaded_opencore = 1;
+      return SOX_SUCCESS;
+    }
+  }
+  else
+  {
+      lsx_report("Not attempting to load " AMR_OPENCORE_DESC " because it does not support encoding.");
+  }
+#endif /* AMR_OPENCORE */
+
+#ifdef AMR_GP3
+  LSX_DLLIBRARY_TRYOPEN(
+      0,
+      &p->gp3,
+      amr_dl,
+      AMR_GP3_FUNC_ENTRIES,
+      AMR_GP3_DESC,
+      amr_gp3_library_names,
+      open_library_result);
+  if (!open_library_result)
+    return SOX_SUCCESS;
+#endif /* AMR_GP3 */
+
+  lsx_fail(
+      "Unable to open "
+#ifdef AMR_OPENCORE
+      AMR_OPENCORE_DESC
+#endif
+#if defined(AMR_OPENCORE) && defined(AMR_GP3)
+      " or "
+#endif
+#ifdef AMR_GP3
+      AMR_GP3_DESC
+#endif
+      ".");
+  return SOX_EOF;
+}
+
+static void closelibrary(priv_t* p)
+{
+#ifdef AMR_OPENCORE
+  LSX_DLLIBRARY_CLOSE(&p->opencore, amr_dl);
+#endif
+#ifdef AMR_GP3
+  LSX_DLLIBRARY_CLOSE(&p->gp3, amr_dl);
+#endif
+}
+
 static int startread(sox_format_t * ft)
 {
   priv_t * p = (priv_t *)ft->priv;
-  char buffer[sizeof(magic) - 1];
+  char buffer[sizeof(amr_magic) - 1];
   int open_library_result;
 
   if (lsx_readchars(ft, buffer, sizeof(buffer)))
     return SOX_EOF;
-  if (memcmp(buffer, magic, sizeof(buffer))) {
+  if (memcmp(buffer, amr_magic, sizeof(buffer))) {
     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;
+  open_library_result = openlibrary(p, 0);
+  if (open_library_result != SOX_SUCCESS)
+    return open_library_result;
 
   p->pcm_index = AMR_FRAME;
-  p->state = p->D_IF_init();
+  p->state = AMR_CALL(p, AmrOpencoreDecoderInit, AmrGp3DecoderInit, ());
+  if (!p->state)
+  {
+      closelibrary(p);
+      lsx_fail("AMR decoder failed to initialize.");
+      return SOX_EOF;
+  }
 
   ft->signal.rate = AMR_RATE;
   ft->encoding.encoding = AMR_ENCODING;
@@ -91,14 +201,14 @@
 static int stopread(sox_format_t * ft)
 {
   priv_t * p = (priv_t *)ft->priv;
-  p->D_IF_exit(p->state);
-  LSX_DLLIBRARY_CLOSE(p, amr_dl);
+  AMR_CALL(p, AmrOpencoreDecoderExit, AmrGp3DecoderExit, (p->state));
+  closelibrary(p);
   return SOX_SUCCESS;
 }
 
 static int startwrite(sox_format_t * ft)
 {
-#ifdef DISABLE_AMR_WB_ENCODE
+#if !defined(AMR_GP3) && !AMR_OPENCORE_ENABLE_ENCODE
   lsx_fail_errno(ft, SOX_EOF, "SoX was compiled without AMR-WB encoding support.");
   return SOX_EOF;
 #else
@@ -114,33 +224,34 @@
   }
   else p->mode = 0;
 
-  LSX_DLLIBRARY_OPEN(
-      p,
-      amr_dl,
-      AMR_FUNC_ENTRIES,
-      AMR_DESC,
-      amr_library_names,
-      open_library_result);
-  if (open_library_result)
-    return SOX_EOF;
+  open_library_result = openlibrary(p, 1);
+  if (open_library_result != SOX_SUCCESS)
+    return open_library_result;
 
 #define IGNORE_WARNING \
-  p->state = p->E_IF_init();
+  p->state = AMR_CALL_ENCODER(p, AmrOpencoreEncoderInit, AmrGp3EncoderInit, ());
 #include "ignore-warning.h"
+  if (!p->state)
+  {
+      closelibrary(p);
+      lsx_fail("AMR encoder failed to initialize.");
+      return SOX_EOF;
+  }
 
-  lsx_writes(ft, magic);
+  lsx_writes(ft, amr_magic);
   p->pcm_index = 0;
   return SOX_SUCCESS;
 #endif
 }
 
-#ifndef DISABLE_AMR_WB_ENCODE
+#if defined(AMR_GP3) || AMR_OPENCORE_ENABLE_ENCODE
+
 static sox_bool encode_1_frame(sox_format_t * ft)
 {
   priv_t * p = (priv_t *)ft->priv;
   uint8_t coded[AMR_CODED_MAX];
 #define IGNORE_WARNING \
-  int n = p->E_IF_encode(p->state, p->mode, p->pcm, coded, 1);
+  int n = AMR_CALL_ENCODER(p, AmrOpencoreEncoderEncode, AmrGp3EncoderEncode, (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)
@@ -147,11 +258,7 @@
     lsx_fail_errno(ft, errno, "write error");
   return result;
 }
-#endif
 
-#ifdef DISABLE_AMR_WB_ENCODE
-#define write_samples NULL
-#else
 static size_t write_samples(sox_format_t * ft, const sox_sample_t * buf, size_t len)
 {
   priv_t * p = (priv_t *)ft->priv;
@@ -168,11 +275,7 @@
   }
   return done;
 }
-#endif
 
-#ifdef DISABLE_AMR_WB_ENCODE
-#define stopwrite NULL
-#else
 static int stopwrite(sox_format_t * ft)
 {
   priv_t * p = (priv_t *)ft->priv;
@@ -185,11 +288,17 @@
     if (!encode_1_frame(ft))
       result = SOX_EOF;
   }
-  p->E_IF_exit(p->state);
+  AMR_CALL_ENCODER(p, AmrOpencoreEncoderExit, AmrGp3EncoderExit, (p->state));
   return result;
 }
-#endif
 
+#else
+
+#define write_samples NULL
+#define stopwrite NULL
+
+#endif /* defined(AMR_GP3) || AMR_OPENCORE_ENABLE_ENCODE */
+
 sox_format_handler_t const * AMR_FORMAT_FN(void);
 sox_format_handler_t const * AMR_FORMAT_FN(void)
 {
@@ -198,7 +307,7 @@
   static unsigned const write_encodings[] = {AMR_ENCODING, 0, 0};
   static sox_format_handler_t handler = {
     SOX_LIB_VERSION_CODE,
-    "3GPP Adaptive Multi Rate lossy speech compressor",
+    AMR_DESC,
     names, SOX_FILE_MONO,
     startread, read_samples, stopread,
     startwrite, write_samples, stopwrite,
--- a/src/sox_i.h
+++ b/src/sox_i.h
@@ -329,6 +329,7 @@
 } lsx_dlfunction_info;
 
 int lsx_open_dllibrary(
+    int show_error_on_failure,
     const char* library_description,
     const char * const library_names[],
     const lsx_dlfunction_info func_infos[],
@@ -343,6 +344,9 @@
 #define LSX_DLENTRY_TO_PTR__(unused, func_return, func_name, func_args, static_func, stub_func, func_ptr) \
     func_return (*func_ptr) func_args;
 
+#define LSX_DLENTRIES_TO_FUNCTIONS__(unused, func_return, func_name, func_args, static_func, stub_func, func_ptr) \
+    func_return func_name func_args;
+
 /* LSX_DLENTRIES_TO_PTRS: Given an ENTRIES macro and the name of the dlhandle
    variable, declares the corresponding function pointer variables and the
    dlhandle variable. */
@@ -350,6 +354,11 @@
     LSX_DLENTRIES_APPLY__(entries, LSX_DLENTRY_TO_PTR__, 0) \
     lsx_dlhandle dlhandle
 
+/* LSX_DLENTRIES_TO_FUNCTIONS: Given an ENTRIES macro, declares the corresponding
+   functions. */
+#define LSX_DLENTRIES_TO_FUNCTIONS(entries) \
+    LSX_DLENTRIES_APPLY__(entries, LSX_DLENTRIES_TO_FUNCTIONS__, 0)
+
 #define LSX_DLLIBRARY_OPEN1__(unused, func_return, func_name, func_args, static_func, stub_func, func_ptr) \
     { #func_name, (lsx_dlptr)(static_func), (lsx_dlptr)(stub_func) },
 
@@ -356,14 +365,25 @@
 #define LSX_DLLIBRARY_OPEN2__(ptr_container, func_return, func_name, func_args, static_func, stub_func, func_ptr) \
     (ptr_container)->func_ptr = (func_return (*)func_args)lsx_dlfunction_open_library_funcs[lsx_dlfunction_open_library_index++];
 
-/* LSX_DLFUNCTION_OPEN_LIBRARY: Input an ENTRIES macro, the library's description,
+/* LSX_DLLIBRARY_OPEN: Input an ENTRIES macro, the library's description,
    a null-terminated list of library names (i.e. { "libmp3-0", "libmp3", NULL }),
    the name of the dlhandle variable, the name of the structure that contains
    the function pointer and dlhandle variables, and the name of the variable in
    which the result of the lsx_open_dllibrary call should be stored. This will
    call lsx_open_dllibrary and copy the resulting function pointers into the
-   structure members. */
+   structure members. If the library cannot be opened, show a failure message. */
 #define LSX_DLLIBRARY_OPEN(ptr_container, dlhandle, entries, library_description, library_names, return_var) \
+    LSX_DLLIBRARY_TRYOPEN(1, ptr_container, dlhandle, entries, library_description, library_names, return_var)
+
+/* LSX_DLLIBRARY_TRYOPEN: Input an ENTRIES macro, the library's description,
+   a null-terminated list of library names (i.e. { "libmp3-0", "libmp3", NULL }),
+   the name of the dlhandle variable, the name of the structure that contains
+   the function pointer and dlhandle variables, and the name of the variable in
+   which the result of the lsx_open_dllibrary call should be stored. This will
+   call lsx_open_dllibrary and copy the resulting function pointers into the
+   structure members. If the library cannot be opened, show a report or a failure
+   message, depending on whether error_on_failure is non-zero. */
+#define LSX_DLLIBRARY_TRYOPEN(error_on_failure, ptr_container, dlhandle, entries, library_description, library_names, return_var) \
     do { \
       lsx_dlfunction_info lsx_dlfunction_open_library_infos[] = { \
         LSX_DLENTRIES_APPLY__(entries, LSX_DLLIBRARY_OPEN1__, 0) \
@@ -370,7 +390,7 @@
         {NULL,NULL,NULL} }; \
       int lsx_dlfunction_open_library_index = 0; \
       lsx_dlptr lsx_dlfunction_open_library_funcs[sizeof(lsx_dlfunction_open_library_infos)/sizeof(lsx_dlfunction_open_library_infos[0])]; \
-      (return_var) = lsx_open_dllibrary((library_description), (library_names), lsx_dlfunction_open_library_infos, lsx_dlfunction_open_library_funcs, &(ptr_container)->dlhandle); \
+      (return_var) = lsx_open_dllibrary((error_on_failure), (library_description), (library_names), lsx_dlfunction_open_library_infos, lsx_dlfunction_open_library_funcs, &(ptr_container)->dlhandle); \
       LSX_DLENTRIES_APPLY__(entries, LSX_DLLIBRARY_OPEN2__, ptr_container) \
     } while(0)
 
--- a/src/util.c
+++ b/src/util.c
@@ -147,6 +147,7 @@
 }
 
 int lsx_open_dllibrary(
+  int show_error_on_failure,
   const char* library_description,
   const char* const library_names[] UNUSED,
   const lsx_dlfunction_info func_infos[],
@@ -248,24 +249,42 @@
 #endif /* HAVE_LIBLTDL */
     if (failed_funcname)
     {
-      lsx_fail(
-        "Unable to load %s (%s) function \"%s\"." LTDL_MISSING,
-        library_description,
-        failed_libname,
-        failed_funcname);
+      if (show_error_on_failure)
+        lsx_fail(
+          "Unable to load %s (%s) function \"%s\"." LTDL_MISSING,
+          library_description,
+          failed_libname,
+          failed_funcname);
+      else
+        lsx_report(
+          "Unable to load %s (%s) function \"%s\"." LTDL_MISSING,
+          library_description,
+          failed_libname,
+          failed_funcname);
     }
     else if (failed_libname)
     {
-      lsx_fail(
-        "Unable to load %s (%s)." LTDL_MISSING,
-        library_description,
-        failed_libname);
+      if (show_error_on_failure)
+        lsx_fail(
+          "Unable to load %s (%s)." LTDL_MISSING,
+          library_description,
+          failed_libname);
+      else
+        lsx_report(
+          "Unable to load %s (%s)." LTDL_MISSING,
+          library_description,
+          failed_libname);
     }
     else
     {
-      lsx_fail(
-        "Unable to load %s - no dynamic library names selected." LTDL_MISSING,
-        library_description);
+      if (show_error_on_failure)
+        lsx_fail(
+          "Unable to load %s - no dynamic library names selected." LTDL_MISSING,
+          library_description);
+      else
+        lsx_report(
+          "Unable to load %s - no dynamic library names selected." LTDL_MISSING,
+          library_description);
     }
   }