shithub: sox

Download patch

ref: 51522baa33bc7ed8a1a2451bcc935c8f59f688df
parent: e585fc3eda6e340f23396a65ae1decffeeb384e1
author: robs <robs>
date: Thu Sep 17 13:00:12 EDT 2009

latest mp3 patch

--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -69,7 +69,7 @@
 	rate_filters.h rate_half_fir.h rate_poly_fir0.h rate_poly_fir.h \
 	remix.c repeat.c reverb.c reverse.c silence.c sinc.c skeleff.c speed.c \
 	splice.c stat.c stats.c stretch.c swap.c synth.c tempo.c tremolo.c \
-	trim.c vad.c vol.c mp3-1.h
+	trim.c vad.c vol.c ignore-warning.h
 if HAVE_PNG
     libsox_la_SOURCES += spectrogram.c
 endif
--- /dev/null
+++ b/src/ignore-warning.h
@@ -1,0 +1,32 @@
+/* This library is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation; either version 2.1 of the License, or (at
+ * your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Lesser
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this library; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
+ */
+
+#if defined __GNUC__
+  #pragma GCC system_header
+#elif defined __SUNPRO_CC
+  #pragma disable_warn
+#elif defined _MSC_VER
+  #pragma warning(push, 1)
+#endif
+
+  IGNORE_WARNING
+#undef IGNORE_WARNING
+
+
+#if defined __SUNPRO_CC
+  #pragma enable_warn
+#elif defined _MSC_VER
+  #pragma warning(pop)
+#endif
--- a/src/mp3-1.h
+++ /dev/null
@@ -1,30 +1,0 @@
-/* This library is free software; you can redistribute it and/or modify it
- * under the terms of the GNU Lesser General Public License as published by
- * the Free Software Foundation; either version 2.1 of the License, or (at
- * your option) any later version.
- *
- * This library is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Lesser
- * General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public License
- * along with this library; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
- */
-
-#if defined __GNUC__
-  #pragma GCC system_header
-#elif defined __SUNPRO_CC
-  #pragma disable_warn
-#elif defined _MSC_VER
-  #pragma warning(push, 1)
-#endif
-
-      if (p->lame_set_VBR_quality(p->gfp, floor_compression) < 0)
-
-#if defined __SUNPRO_CC
-  #pragma enable_warn
-#elif defined _MSC_VER
-  #pragma warning(pop)
-#endif
--- a/src/mp3-duration.h
+++ /dev/null
@@ -1,230 +1,0 @@
-/* libSoX MP3 support routines  Copyright (c) 2007-9 SoX contributors
- *
- * This library is free software; you can redistribute it and/or modify it
- * under the terms of the GNU Lesser General Public License as published by
- * the Free Software Foundation; either version 2.1 of the License, or (at
- * your option) any later version.
- *
- * This library is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Lesser
- * General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public License
- * along with this library; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
- */
-
-#include <sys/stat.h>
-
-#ifdef USING_ID3TAG
-
-static char const * id3tagmap[][2] =
-{
-  {"TIT2", "Title"},
-  {"TPE1", "Artist"},
-  {"TALB", "Album"},
-  {"TRCK", "Tracknumber"},
-  {"TDRC", "Year"},
-  {"TCON", "Genre"},
-  {"COMM", "Comment"},
-  {"TPOS", "Discnumber"},
-  {NULL, NULL}
-};
-
-static void write_comments(sox_format_t * ft)
-{
-#if HAVE_ID3TAG_SET_FIELDVALUE
-  priv_t *p = (priv_t *) ft->priv;
-  size_t i;
-  char* id3tag_buf = NULL;
-  size_t id3tag_size = 0;
-  const char* comment;
-  size_t required_size;
-
-  for (i = 0; id3tagmap[i][0]; i++)
-  {
-    comment = sox_find_comment(ft->oob.comments, id3tagmap[i][1]);
-    if (comment)
-    {
-      required_size = strlen(comment) + 6;
-      if (id3tag_size < required_size)
-      {
-        char* id3tag_realloc = lsx_realloc(id3tag_buf, required_size);
-        if (id3tag_realloc)
-        {
-          id3tag_buf = id3tag_realloc;
-          id3tag_size = required_size;
-        }
-      }
-
-      if (id3tag_size >= required_size)
-      {
-        sprintf(id3tag_buf, "%s=%s", id3tagmap[i][0], comment);
-        id3tag_buf[id3tag_size - 1] = 0;
-        p->id3tag_set_fieldvalue(p->gfp, id3tag_buf);
-      }
-    }
-  }
-
-  free(id3tag_buf);
-#else
-  (void)ft;
-#endif
-}
-
-static id3_utf8_t * utf8_id3tag_findframe(
-    struct id3_tag * tag, const char * const frameid, unsigned index)
-{
-  struct id3_frame const * frame = id3_tag_findframe(tag, frameid, index);
-  if (frame) {
-    union id3_field  const * field = id3_frame_field(frame, 1);
-    unsigned nstrings = id3_field_getnstrings(field);
-    while (nstrings--){
-      id3_ucs4_t const * ucs4 = id3_field_getstrings(field, nstrings);
-      if (ucs4)
-        return id3_ucs4_utf8duplicate(ucs4); /* Must call free() on this */
-    }
-  }
-  return NULL;
-}
-
-static void read_comments(sox_format_t * ft)
-{
-  struct id3_file   * id3struct;
-  struct id3_tag    * tag;
-  id3_utf8_t        * utf8;
-  int               i, fd = dup(fileno(ft->fp));
-
-  if ((id3struct = id3_file_fdopen(fd, ID3_FILE_MODE_READONLY))) {
-    if ((tag = id3_file_tag(id3struct)) && tag->frames)
-      for (i = 0; id3tagmap[i][0]; ++i)
-        if ((utf8 = utf8_id3tag_findframe(tag, id3tagmap[i][0], 0))) {
-          char * comment = lsx_malloc(strlen(id3tagmap[i][1]) + 1 + strlen((char *)utf8) + 1);
-          sprintf(comment, "%s=%s", id3tagmap[i][1], utf8);
-          sox_append_comment(&ft->oob.comments, comment);
-          free(comment);
-          free(utf8);
-        }
-      if ((utf8 = utf8_id3tag_findframe(tag, "TLEN", 0))) {
-        if (atoi((char *)utf8) > 0) {
-          ft->signal.length = atoi((char *)utf8); /* In ms; convert to samples later */
-          lsx_debug("got exact duration from ID3 TLEN");
-        }
-        free(utf8);
-      }
-    id3_file_close(id3struct);
-  }
-  else close(fd);
-}
-
-#endif
-
-static unsigned long xing_frames(priv_t * p, struct mad_bitptr ptr, unsigned bitlen)
-{
-  #define XING_MAGIC ( ('X' << 24) | ('i' << 16) | ('n' << 8) | 'g' )
-  if (bitlen >= 96 && p->mad_bit_read(&ptr, 32) == XING_MAGIC &&
-      (p->mad_bit_read(&ptr, 32) & 1 )) /* XING_FRAMES */
-    return p->mad_bit_read(&ptr, 32);
-  return 0;
-}
-
-static void mad_timer_mult(mad_timer_t * t, double d)
-{
-  t->seconds = d *= (t->seconds + t->fraction * (1. / MAD_TIMER_RESOLUTION));
-  t->fraction = (d - t->seconds) * MAD_TIMER_RESOLUTION + .5;
-}
-
-static size_t mp3_duration_ms(sox_format_t * ft, unsigned char *buffer)
-{
-  priv_t              * p = (priv_t *) ft->priv;
-  FILE                * fp = ft->fp;
-  struct mad_stream   mad_stream;
-  struct mad_header   mad_header;
-  struct mad_frame    mad_frame;
-  mad_timer_t         time = mad_timer_zero;
-  size_t              initial_bitrate = 0; /* Initialised to prevent warning */
-  size_t              tagsize = 0, consumed = 0, frames = 0;
-  sox_bool            vbr = sox_false, depadded = sox_false;
-
-  p->mad_stream_init(&mad_stream);
-  p->mad_header_init(&mad_header);
-  p->mad_frame_init(&mad_frame);
-
-  do {  /* Read data from the MP3 file */
-    int read, padding = 0;
-    size_t leftover = mad_stream.bufend - mad_stream.next_frame;
-
-    memcpy(buffer, mad_stream.this_frame, leftover);
-    read = fread(buffer + leftover, (size_t) 1, INPUT_BUFFER_SIZE - leftover, fp);
-    if (read <= 0) {
-      lsx_debug("got exact duration by scan to EOF (frames=%lu leftover=%lu)", (unsigned long)frames, (unsigned long)leftover);
-      break;
-    }
-    for (; !depadded && padding < read && !buffer[padding]; ++padding);
-    depadded = sox_true;
-    p->mad_stream_buffer(&mad_stream, buffer + padding, leftover + read - padding);
-
-    while (sox_true) {  /* Decode frame headers */
-      mad_stream.error = MAD_ERROR_NONE;
-      if (p->mad_header_decode(&mad_header, &mad_stream) == -1) {
-        if (mad_stream.error == MAD_ERROR_BUFLEN)
-          break;  /* Normal behaviour; get some more data from the file */
-        if (!MAD_RECOVERABLE(mad_stream.error)) {
-          lsx_warn("unrecoverable MAD error");
-          break;
-        }
-        if (mad_stream.error == MAD_ERROR_LOSTSYNC) {
-          unsigned available = (mad_stream.bufend - mad_stream.this_frame);
-          tagsize = tagtype(mad_stream.this_frame, (size_t) available);
-          if (tagsize) {   /* It's some ID3 tags, so just skip */
-            if (tagsize >= available) {
-              fseeko(fp, (off_t)(tagsize - available), SEEK_CUR);
-              depadded = sox_false;
-            }
-            p->mad_stream_skip(&mad_stream, min(tagsize, available));
-          }
-          else lsx_warn("MAD lost sync");
-        }
-        else lsx_warn("recoverable MAD error");
-        continue; /* Not an audio frame */
-      }
-
-      p->mad_timer_add(&time, mad_header.duration);
-      consumed += mad_stream.next_frame - mad_stream.this_frame;
-
-      if (!frames) {
-        initial_bitrate = mad_header.bitrate;
-
-        /* Get the precise frame count from the XING header if present */
-        mad_frame.header = mad_header;
-        if (p->mad_frame_decode(&mad_frame, &mad_stream) == -1)
-          if (!MAD_RECOVERABLE(mad_stream.error)) {
-            lsx_warn("unrecoverable MAD error");
-            break;
-          }
-        if ((frames = xing_frames(p, mad_stream.anc_ptr, mad_stream.anc_bitlen))) {
-          p->mad_timer_multiply(&time, (signed long)frames);
-          lsx_debug("got exact duration from XING frame count (%lu)", (unsigned long)frames);
-          break;
-        }
-      }
-      else vbr |= mad_header.bitrate != initial_bitrate;
-
-      /* If not VBR, we can time just a few frames then extrapolate */
-      if (++frames == 10 && !vbr) {
-        struct stat filestat;
-        fstat(fileno(fp), &filestat);
-        mad_timer_mult(&time, (double)(filestat.st_size - tagsize) / consumed);
-        lsx_debug("got approx. duration by CBR extrapolation");
-        break;
-      }
-    }
-  } while (mad_stream.error == MAD_ERROR_BUFLEN);
-
-  p->mad_frame_finish(&mad_frame);
-  mad_header_finish(&mad_header);
-  p->mad_stream_finish(&mad_stream);
-  rewind(fp);
-  return p->mad_timer_count(time, MAD_UNITS_MILLISECONDS);
-}
--- /dev/null
+++ b/src/mp3-util.h
@@ -1,0 +1,234 @@
+/* libSoX MP3 utilities  Copyright (c) 2007-9 SoX contributors
+ *
+ * This library is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation; either version 2.1 of the License, or (at
+ * your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Lesser
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this library; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
+ */
+
+#include <sys/stat.h>
+
+static char const * id3tagmap[][2] =
+{
+  {"TIT2", "Title"},
+  {"TPE1", "Artist"},
+  {"TALB", "Album"},
+  {"TRCK", "Tracknumber"},
+  {"TDRC", "Year"},
+  {"TCON", "Genre"},
+  {"COMM", "Comment"},
+  {"TPOS", "Discnumber"},
+  {NULL, NULL}
+};
+
+#if defined(HAVE_LAME_LAME_H) && defined(HAVE_ID3TAG_SET_FIELDVALUE)
+
+static void write_comments(sox_format_t * ft)
+{
+  priv_t *p = (priv_t *) ft->priv;
+  size_t i;
+  char* id3tag_buf = NULL;
+  size_t id3tag_size = 0;
+  const char* comment;
+  size_t required_size;
+
+  for (i = 0; id3tagmap[i][0]; i++)
+  {
+    comment = sox_find_comment(ft->oob.comments, id3tagmap[i][1]);
+    if (comment)
+    {
+      required_size = strlen(comment) + 6;
+      if (id3tag_size < required_size)
+      {
+        char* id3tag_realloc = lsx_realloc(id3tag_buf, required_size);
+        if (id3tag_realloc)
+        {
+          id3tag_buf = id3tag_realloc;
+          id3tag_size = required_size;
+        }
+      }
+
+      if (id3tag_size >= required_size)
+      {
+        sprintf(id3tag_buf, "%s=%s", id3tagmap[i][0], comment);
+        id3tag_buf[id3tag_size - 1] = 0;
+        p->id3tag_set_fieldvalue(p->gfp, id3tag_buf);
+      }
+    }
+  }
+
+  free(id3tag_buf);
+}
+
+#endif /* HAVE_LAME_LAME_H && HAVE_ID3TAG_SET_FIELDVALUE */
+
+#ifdef USING_ID3TAG
+
+static id3_utf8_t * utf8_id3tag_findframe(
+    struct id3_tag * tag, const char * const frameid, unsigned index)
+{
+  struct id3_frame const * frame = id3_tag_findframe(tag, frameid, index);
+  if (frame) {
+    union id3_field  const * field = id3_frame_field(frame, 1);
+    unsigned nstrings = id3_field_getnstrings(field);
+    while (nstrings--){
+      id3_ucs4_t const * ucs4 = id3_field_getstrings(field, nstrings);
+      if (ucs4)
+        return id3_ucs4_utf8duplicate(ucs4); /* Must call free() on this */
+    }
+  }
+  return NULL;
+}
+
+static void read_comments(sox_format_t * ft)
+{
+  struct id3_file   * id3struct;
+  struct id3_tag    * tag;
+  id3_utf8_t        * utf8;
+  int               i, fd = dup(fileno(ft->fp));
+
+  if ((id3struct = id3_file_fdopen(fd, ID3_FILE_MODE_READONLY))) {
+    if ((tag = id3_file_tag(id3struct)) && tag->frames)
+      for (i = 0; id3tagmap[i][0]; ++i)
+        if ((utf8 = utf8_id3tag_findframe(tag, id3tagmap[i][0], 0))) {
+          char * comment = lsx_malloc(strlen(id3tagmap[i][1]) + 1 + strlen((char *)utf8) + 1);
+          sprintf(comment, "%s=%s", id3tagmap[i][1], utf8);
+          sox_append_comment(&ft->oob.comments, comment);
+          free(comment);
+          free(utf8);
+        }
+      if ((utf8 = utf8_id3tag_findframe(tag, "TLEN", 0))) {
+        if (atoi((char *)utf8) > 0) {
+          ft->signal.length = atoi((char *)utf8); /* In ms; convert to samples later */
+          lsx_debug("got exact duration from ID3 TLEN");
+        }
+        free(utf8);
+      }
+    id3_file_close(id3struct);
+  }
+  else close(fd);
+}
+
+#endif /* USING_ID3TAG */
+
+#ifdef HAVE_MAD_H
+
+static unsigned long xing_frames(priv_t * p, struct mad_bitptr ptr, unsigned bitlen)
+{
+  #define XING_MAGIC ( ('X' << 24) | ('i' << 16) | ('n' << 8) | 'g' )
+  if (bitlen >= 96 && p->mad_bit_read(&ptr, 32) == XING_MAGIC &&
+      (p->mad_bit_read(&ptr, 32) & 1 )) /* XING_FRAMES */
+    return p->mad_bit_read(&ptr, 32);
+  return 0;
+}
+
+static void mad_timer_mult(mad_timer_t * t, double d)
+{
+  t->seconds = d *= (t->seconds + t->fraction * (1. / MAD_TIMER_RESOLUTION));
+  t->fraction = (d - t->seconds) * MAD_TIMER_RESOLUTION + .5;
+}
+
+static size_t mp3_duration_ms(sox_format_t * ft, unsigned char *buffer)
+{
+  priv_t              * p = (priv_t *) ft->priv;
+  FILE                * fp = ft->fp;
+  struct mad_stream   mad_stream;
+  struct mad_header   mad_header;
+  struct mad_frame    mad_frame;
+  mad_timer_t         time = mad_timer_zero;
+  size_t              initial_bitrate = 0; /* Initialised to prevent warning */
+  size_t              tagsize = 0, consumed = 0, frames = 0;
+  sox_bool            vbr = sox_false, depadded = sox_false;
+
+  p->mad_stream_init(&mad_stream);
+  p->mad_header_init(&mad_header);
+  p->mad_frame_init(&mad_frame);
+
+  do {  /* Read data from the MP3 file */
+    int read, padding = 0;
+    size_t leftover = mad_stream.bufend - mad_stream.next_frame;
+
+    memcpy(buffer, mad_stream.this_frame, leftover);
+    read = fread(buffer + leftover, (size_t) 1, INPUT_BUFFER_SIZE - leftover, fp);
+    if (read <= 0) {
+      lsx_debug("got exact duration by scan to EOF (frames=%lu leftover=%lu)", (unsigned long)frames, (unsigned long)leftover);
+      break;
+    }
+    for (; !depadded && padding < read && !buffer[padding]; ++padding);
+    depadded = sox_true;
+    p->mad_stream_buffer(&mad_stream, buffer + padding, leftover + read - padding);
+
+    while (sox_true) {  /* Decode frame headers */
+      mad_stream.error = MAD_ERROR_NONE;
+      if (p->mad_header_decode(&mad_header, &mad_stream) == -1) {
+        if (mad_stream.error == MAD_ERROR_BUFLEN)
+          break;  /* Normal behaviour; get some more data from the file */
+        if (!MAD_RECOVERABLE(mad_stream.error)) {
+          lsx_warn("unrecoverable MAD error");
+          break;
+        }
+        if (mad_stream.error == MAD_ERROR_LOSTSYNC) {
+          unsigned available = (mad_stream.bufend - mad_stream.this_frame);
+          tagsize = tagtype(mad_stream.this_frame, (size_t) available);
+          if (tagsize) {   /* It's some ID3 tags, so just skip */
+            if (tagsize >= available) {
+              fseeko(fp, (off_t)(tagsize - available), SEEK_CUR);
+              depadded = sox_false;
+            }
+            p->mad_stream_skip(&mad_stream, min(tagsize, available));
+          }
+          else lsx_warn("MAD lost sync");
+        }
+        else lsx_warn("recoverable MAD error");
+        continue; /* Not an audio frame */
+      }
+
+      p->mad_timer_add(&time, mad_header.duration);
+      consumed += mad_stream.next_frame - mad_stream.this_frame;
+
+      if (!frames) {
+        initial_bitrate = mad_header.bitrate;
+
+        /* Get the precise frame count from the XING header if present */
+        mad_frame.header = mad_header;
+        if (p->mad_frame_decode(&mad_frame, &mad_stream) == -1)
+          if (!MAD_RECOVERABLE(mad_stream.error)) {
+            lsx_warn("unrecoverable MAD error");
+            break;
+          }
+        if ((frames = xing_frames(p, mad_stream.anc_ptr, mad_stream.anc_bitlen))) {
+          p->mad_timer_multiply(&time, (signed long)frames);
+          lsx_debug("got exact duration from XING frame count (%lu)", (unsigned long)frames);
+          break;
+        }
+      }
+      else vbr |= mad_header.bitrate != initial_bitrate;
+
+      /* If not VBR, we can time just a few frames then extrapolate */
+      if (++frames == 10 && !vbr) {
+        struct stat filestat;
+        fstat(fileno(fp), &filestat);
+        mad_timer_mult(&time, (double)(filestat.st_size - tagsize) / consumed);
+        lsx_debug("got approx. duration by CBR extrapolation");
+        break;
+      }
+    }
+  } while (mad_stream.error == MAD_ERROR_BUFLEN);
+
+  p->mad_frame_finish(&mad_frame);
+  mad_header_finish(&mad_header);
+  p->mad_stream_finish(&mad_stream);
+  rewind(fp);
+  return p->mad_timer_count(time, MAD_UNITS_MILLISECONDS);
+}
+
+#endif /* HAVE_MAD_H */
--- a/src/mp3.c
+++ b/src/mp3.c
@@ -11,6 +11,8 @@
 
 #include "sox_i.h"
 
+#if defined(HAVE_LAME_LAME_H) || defined (HAVE_MAD_H)
+
 #include <string.h>
 
 #ifdef HAVE_MAD_H
@@ -38,7 +40,7 @@
 
 #if defined HAVE_LIBLTDL
   #include <ltdl.h>
-#if defined DL_MAD
+#if defined HAVE_MAD_H && defined DL_MAD
 mad_timer_t const mad_timer_zero;
 #endif
 #endif
@@ -88,7 +90,9 @@
   int (*lame_set_in_samplerate)(lame_global_flags *, int);
   int (*lame_set_bWriteVbrTag)(lame_global_flags *, int);
   int (*lame_get_bWriteVbrTag)(lame_global_flags const *);
+  #ifdef HAVE_ID3TAG_SET_FIELDVALUE
   int (*id3tag_set_fieldvalue)(lame_global_flags *, const char *);
+  #endif
   int (*lame_init_params)(lame_global_flags *);
   int (*lame_set_errorf)(lame_global_flags *,
                          void (*func)(const char *, va_list));
@@ -108,7 +112,9 @@
   int (*lame_set_quality)(lame_global_flags *, int);
   int (*lame_set_VBR)(lame_global_flags *, vbr_mode);
   int (*lame_set_VBR_min_bitrate_kbps)(lame_global_flags *, int);
+  #ifdef HAVE_LAME_SET_VBR_QUALITY
   int (*lame_set_VBR_quality)(lame_global_flags *, float);
+  #endif
   vbr_mode (*lame_get_VBR)(const lame_global_flags *);
 
   #if defined HAVE_LIBLTDL && defined DL_LAME
@@ -117,8 +123,6 @@
 #endif /*HAVE_LAME_LAME_H*/
 } priv_t;
 
-#ifdef HAVE_MAD_H
-
 /* This function merges the functions tagtype() and id3_tag_query()
    from MAD's libid3tag, so we don't have to link to it
    Returns 0 if the frame is not an ID3 tag, tag length if it is */
@@ -148,8 +152,10 @@
     return 0;
 }
 
-#include "mp3-duration.h"
+#include "mp3-util.h"
 
+#ifdef HAVE_MAD_H
+
 /*
  * (Re)fill the stream buffer that is to be decoded.  If any data
  * still exists in the buffer then they are first shifted to be
@@ -524,7 +530,7 @@
   LOAD_FN_PTR(lame_set_in_samplerate)
   LOAD_FN_PTR(lame_set_bWriteVbrTag)
   LOAD_FN_PTR(lame_get_bWriteVbrTag)
-#if defined USING_ID3TAG && HAVE_ID3TAG_SET_FIELDVALUE
+#ifdef HAVE_ID3TAG_SET_FIELDVALUE
   LOAD_FN_PTR(id3tag_set_fieldvalue)
 #endif
   LOAD_FN_PTR(lame_init_params)
@@ -579,7 +585,7 @@
 
   p->lame_set_bWriteVbrTag(p->gfp, 0); /* disable writing VBR tag */
 
-#ifdef USING_ID3TAG
+#ifdef HAVE_ID3TAG_SET_FIELDVALUE
   write_comments(ft);
 #endif
 
@@ -591,9 +597,9 @@
    * performance), which allows balancing encoding speed vs. quality.
    * In LAME, 0 specifies highest quality but is very slow, while
    * 9 selects poor quality, but is fast. (5 is the default and 2 is
-   * recommend as a good trade-off for high quality encodes.)
+   * recommended as a good trade-off for high quality encodes.)
    *
-   * Becaues encoding.compression is a float, the fractional part is used
+   * Because encoding.compression is a float, the fractional part is used
    * to select quality. 128.2 selects 128 kbps encoding with a quality
    * of 2. There is one problem with this approach. We need 128 to specify
    * 128 kbps encoding with default quality, so 0 means use default. Instead
@@ -601,7 +607,7 @@
    * (128.01 or 128.99).
    *
    * LAME uses bitrate to specify a constant bitrate, but higher quality
-   * can be acheived using Variable Bit Rate (VBR). VBR quality (really
+   * can be achieved using Variable Bit Rate (VBR). VBR quality (really
    * size) is selected using a number from 0 to 9. Use a value of 0 for high
    * quality, larger files, and 9 for smaller files of lower quality. 4 is
    * the default.
@@ -640,7 +646,9 @@
       }
 
 #if HAVE_LAME_SET_VBR_QUALITY
-#include "mp3-1.h"
+#define IGNORE_WARNING \
+      if (p->lame_set_VBR_quality(p->gfp, floor_compression) < 0)
+#include "ignore-warning-1.h"
       {
         lsx_fail_errno(ft, SOX_EOF,
           "lame_set_VBR_quality(%f) failed (should be between 0 and 9)",
@@ -817,3 +825,4 @@
   };
   return &handler;
 }
+#endif /* defined(HAVE_LAME_LAME_H) || defined (HAVE_MAD_H) */
--- a/src/optional-fmts.am
+++ b/src/optional-fmts.am
@@ -110,11 +110,11 @@
 
 if HAVE_MP3
 if STATIC_MP3
-  libsox_la_SOURCES += mp3.c mp3-duration.h
+  libsox_la_SOURCES += mp3.c mp3-util.h
   libsox_la_LIBADD += @MP3_LIBS@
   sox_LDADD += @MP3_LIBS@
 else
-  libsox_fmt_mp3_la_SOURCES = mp3.c mp3-duration.h
+  libsox_fmt_mp3_la_SOURCES = mp3.c mp3-util.h
   libsox_fmt_mp3_la_LIBADD = libsox.la @MP3_LIBS@
   pkglib_LTLIBRARIES += libsox_fmt_mp3.la
 endif
@@ -182,11 +182,11 @@
 
 if HAVE_OGG_VORBIS
 if STATIC_OGG_VORBIS
-  libsox_la_SOURCES += vorbis.c vorbis1.h
+  libsox_la_SOURCES += vorbis.c
   libsox_la_LIBADD += @OGG_VORBIS_LIBS@
   sox_LDADD += @OGG_VORBIS_LIBS@
 else
-  libsox_fmt_vorbis_la_SOURCES = vorbis.c vorbis1.h
+  libsox_fmt_vorbis_la_SOURCES = vorbis.c
   libsox_fmt_vorbis_la_LIBADD = libsox.la @OGG_VORBIS_LIBS@
   pkglib_LTLIBRARIES += libsox_fmt_vorbis.la
 endif
--- a/src/optional-fmts.in
+++ b/src/optional-fmts.in
@@ -21,13 +21,13 @@
 OPT_FORMAT(flac, FLAC, flac.c)
 OPT_FORMAT(gsm, GSM, gsm.c)
 OPT_FORMAT(lpc10, LPC10, lpc10.c)
-OPT_FORMAT(mp3, MP3, mp3.c mp3-duration.h)
+OPT_FORMAT(mp3, MP3, mp3.c mp3-util.h)
 OPT_FORMAT(oss, OSS, oss.c)
 OPT_FORMAT(pulseaudio, PULSEAUDIO, pulseaudio.c)
 OPT_FORMAT(waveaudio, WAVEAUDIO, waveaudio.c)
 OPT_FORMAT(sndio, SNDIO, sndio.c)
 OPT_FORMAT(sunau, SUN_AUDIO, sunaudio.c)
-OPT_FORMAT(vorbis, OGG_VORBIS, vorbis.c vorbis1.h)
+OPT_FORMAT(vorbis, OGG_VORBIS, vorbis.c)
 OPT_FORMAT(wavpack, WAVPACK, wavpack.c)
 
 if HAVE_SNDFILE
--- a/src/vorbis.c
+++ b/src/vorbis.c
@@ -300,7 +300,13 @@
     }
     quality = ft->encoding.compression;
   }
-#include "vorbis1.h"
+#define IGNORE_WARNING \
+  if (vorbis_encode_init_vbr(&ve->vi, ft->signal.channels, ft->signal.rate + .5, quality / 10))
+#include "ignore-warning.h"
+  {
+    lsx_fail_errno(ft, SOX_EFMT, "libVorbis cannot encode this sample-rate or # of channels");
+    return SOX_EOF;
+  }
 
   vorbis_analysis_init(&ve->vd, &ve->vi);
   vorbis_block_init(&ve->vd, &ve->vb);
--- a/src/vorbis1.h
+++ /dev/null
@@ -1,31 +1,0 @@
-/* This library is free software; you can redistribute it and/or modify it
- * under the terms of the GNU Lesser General Public License as published by
- * the Free Software Foundation; either version 2.1 of the License, or (at
- * your option) any later version.
- *
- * This library is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Lesser
- * General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public License
- * along with this library; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
- */
-
-#if defined __GNUC__
-  #pragma GCC system_header
-#elif defined __SUNPRO_CC
-  #pragma disable_warn
-#elif defined _MSC_VER
-  #pragma warning(push, 1)
-#endif
-
-  vorbis_encode_init_vbr(
-      &ve->vi, ft->signal.channels, ft->signal.rate + .5, quality / 10);
-
-#if defined __SUNPRO_CC
-  #pragma enable_warn
-#elif defined _MSC_VER
-  #pragma warning(pop)
-#endif