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