shithub: sox

Download patch

ref: 624ec8c88d6d3cd06a6c6f6ba0354d5437aec8d6
parent: fac1bc9a1b51f68ee417bf69180843eb4badf2d8
author: robs <robs>
date: Wed Sep 16 13:54:40 EDT 2009

write id3 tags to mp3

--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -121,6 +121,7 @@
 
 set(CMAKE_REQUIRED_LIBRARIES mp3lame m)
 check_function_exists("lame_set_VBR_quality" HAVE_LAME_SET_VBR_QUALITY)
+check_function_exists("id3tag_set_fieldvalue" HAVE_ID3TAG_SET_FIELDVALUE)
 
 if (HAVE_SUN_AUDIOIO_H OR HAVE_SYS_AUDIOIO_H)
   set(HAVE_SUN_AUDIO 1)
--- a/ChangeLog
+++ b/ChangeLog
@@ -37,6 +37,7 @@
   o New Grandstream ring-tone (gsrt) format.  (robs)
   o CVSD encode/decode speed-ups.  (Kimberly Rockwell, P. Chaintreuil)
   o Add ability to select MP3 compression parameters.  (Jim Harkins)
+  o Now writes out ID3-tags in MP3 files.  (Doug Cook)
 
 Audio device drivers:
 
--- a/configure.ac
+++ b/configure.ac
@@ -341,6 +341,10 @@
       if test "$ac_cv_lib_mp3lame_lame_set_VBR_quality" = yes; then
         AC_DEFINE(HAVE_LAME_SET_VBR_QUALITY, 1, [Define to 1 if you have lame_set_VBR_quality.])
       fi
+      AC_CHECK_LIB(mp3lame, id3tag_set_fieldvalue)
+      if test "$ac_cv_lib_mp3lame_id3tag_set_fieldvalue" = yes; then
+        AC_DEFINE(HAVE_ID3TAG_SET_FIELDVALUE, 1, [Define to 1 if you have id3tag_set_fieldvalue.])
+      fi
       if test "$with_lame" = "yes" -a "$using_lame" = "no"; then
         AC_MSG_FAILURE([cannot find LAME])
       fi
--- a/src/mp3-duration.h
+++ b/src/mp3-duration.h
@@ -19,8 +19,62 @@
 
 #include <sys/stat.h>
 
-#if HAVE_ID3TAG && HAVE_UNISTD_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)
 {
@@ -39,17 +93,6 @@
 
 static void read_comments(sox_format_t * ft)
 {
-  static char const * list[][2] = {
-    {ID3_FRAME_TITLE,   "Title"},
-    {ID3_FRAME_ARTIST,  "Artist"},
-    {ID3_FRAME_ALBUM,   "Album"},
-    {ID3_FRAME_TRACK,   "Tracknumber"},
-    {ID3_FRAME_YEAR,    "Year"},
-    {ID3_FRAME_GENRE,   "Genre"},
-    {ID3_FRAME_COMMENT, "Comment"},
-    {"TPOS",            "Discnumber"},
-    {NULL, NULL}
-  };
   struct id3_file   * id3struct;
   struct id3_tag    * tag;
   id3_utf8_t        * utf8;
@@ -57,10 +100,10 @@
 
   if ((id3struct = id3_file_fdopen(fd, ID3_FILE_MODE_READONLY))) {
     if ((tag = id3_file_tag(id3struct)) && tag->frames)
-      for (i = 0; list[i][0]; ++i)
-        if ((utf8 = utf8_id3tag_findframe(tag, list[i][0], 0))) {
-          char * comment = lsx_malloc(strlen(list[i][1]) + 1 + strlen((char *)utf8) + 1);
-          sprintf(comment, "%s=%s", list[i][1], utf8);
+      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);
--- a/src/mp3.c
+++ b/src/mp3.c
@@ -21,9 +21,17 @@
 #include <lame/lame.h>
 #endif
 
-#if HAVE_ID3TAG && HAVE_UNISTD_H
+#if defined(HAVE_ID3TAG) && (defined(HAVE_IO_H) || defined(HAVE_UNISTD_H))
+#define USING_ID3TAG 1
+#endif
+
+#ifdef USING_ID3TAG
   #include <id3tag.h>
+#if defined(HAVE_UNISTD_H)
   #include <unistd.h>
+#elif defined(HAVE_IO_H)
+  #include <io.h>
+#endif
 #else
   #define ID3_TAG_FLAG_FOOTERPRESENT 0x10
 #endif
@@ -80,8 +88,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 *);
+  int (*id3tag_set_fieldvalue)(lame_global_flags *, const char *);
   int (*lame_init_params)(lame_global_flags *);
-  int (*lame_set_errorf)(lame_global_flags *, 
+  int (*lame_set_errorf)(lame_global_flags *,
                          void (*func)(const char *, va_list));
   int (*lame_set_debugf)(lame_global_flags *,
                          void (*func)(const char *, va_list));
@@ -88,7 +97,7 @@
   int (*lame_set_msgf)(lame_global_flags *,
                        void (*func)(const char *, va_list));
   int (*lame_encode_buffer)(lame_global_flags *, const short int[],
-                            const short int[], const int, 
+                            const short int[], const int,
                             unsigned char *, const int);
   int (*lame_encode_flush)(lame_global_flags *, unsigned char *,
                            int);
@@ -242,7 +251,7 @@
 #else
   #define DL_LIB_NAME
   #define LOAD_FN_PTR(x) p->x = x;
-#endif 
+#endif
 
   LOAD_FN_PTR(mad_bit_read)
   LOAD_FN_PTR(mad_frame_decode)
@@ -271,7 +280,7 @@
 
     ft->signal.length = SOX_UNSPEC;
     if (ft->seekable) {
-#if HAVE_ID3TAG && HAVE_UNISTD_H
+#ifdef USING_ID3TAG
       read_comments(ft);
       rewind(ft->fp);
       if (!ft->signal.length)
@@ -485,7 +494,6 @@
   return;
 }
 
-
 static int startwrite(sox_format_t * ft)
 {
   priv_t *p = (priv_t *) ft->priv;
@@ -508,7 +516,7 @@
 #else
   #define DL_LIB_NAME
   #define LOAD_FN_PTR(x) p->x = x;
-#endif 
+#endif
 
   LOAD_FN_PTR(lame_init)
   LOAD_FN_PTR(lame_set_num_channels)
@@ -516,6 +524,9 @@
   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
+  LOAD_FN_PTR(id3tag_set_fieldvalue)
+#endif
   LOAD_FN_PTR(lame_init_params)
   LOAD_FN_PTR(lame_set_errorf)
   LOAD_FN_PTR(lame_set_debugf)
@@ -568,6 +579,10 @@
 
   p->lame_set_bWriteVbrTag(p->gfp, 0); /* disable writing VBR tag */
 
+#ifdef USING_ID3TAG
+  write_comments(ft);
+#endif
+
   /* The primary parameter to the LAME encoder is the bit rate. If the
    * value of encoding.compression is a positive integer, it's taken as
    * the bitrate in kbps (that is if you specify 128, it use 128 kbps).
@@ -730,7 +745,7 @@
     mp3buffer_size = 1.25 * nsamples + 7200;
     mp3buffer = lsx_malloc(mp3buffer_size);
 
-    if ((written = 
+    if ((written =
 	 p->lame_encode_buffer(p->gfp,buffer_l, buffer_r,
 			       nsamples, mp3buffer,
 			       (int)mp3buffer_size)) > mp3buffer_size){
--- a/src/soxconfig.h.cmake
+++ b/src/soxconfig.h.cmake
@@ -16,6 +16,7 @@
 #cmakedefine HAVE_GLOB_H              1
 #define HAVE_GSM                      1
 #cmakedefine HAVE_ID3TAG              1
+#cmakedefine HAVE_ID3TAG_SET_FIELDVALUE 1
 #cmakedefine HAVE_INTTYPES_H          1
 #cmakedefine HAVE_IO_H                1
 #cmakedefine HAVE_LAME_LAME_H         1