[libid3tag] saving both v1.1 and v2.3 tags

Pascal Ognibene <[email protected]> Sat, 2 Jan 2010 14:09:11 +0100
Newsgroups gmane.comp.audio.mad.devel
Message-ID <[email protected]>
--00151747beeab9e7aa047c2e3187
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: quoted-printable

Hi all,

Sorry for the double-post - gmail has decided to send the mail before I was
done :-(

I want to tag existing, untagged mp3 files. Using the code below, I can sav=
e
v1.1 id3 tags in the file,
but I'm struggling to get v2.3.0 tags to be saved as well (I want both v1.1
and v2.3.0 in the same file).
The code below will just save properly the first tag (ID3_FRAME_COMMENT),
the second one seems to be ignored.

Any help or code snippet would be welcome!

Thank's,

Pog

---
Code snippet below:

{
struct id3_file *id3 =3D
        id3_file_open("/home/myself/foo.mp3",
              ID3_FILE_MODE_READWRITE);

    struct id3_tag *tag =3D id3_file_tag(id3);

    if (tag !=3D NULL) {

        id3_tag_options(tag, ID3_TAG_OPTION_ID3V1, ~0);
        id3_tag_options(tag, ID3_TAG_OPTION_COMPRESSION, 0);//for
ipod/itunes compatibility
        id3_tag_options(tag, ID3_TAG_OPTION_CRC, 0);

        id3_set_string(tag, ID3_FRAME_TITLE,
                   "azertyuiopqdsfhjkklwxc=C3=A9=C3=A8=C3=A0=C3=A7@=C3=AA=
=C3=B4=C3=AE",
                   ID3_FIELD_TEXTENCODING_UTF_16);
        id3_set_string(tag, "TOWN",
                   "SimplePod",
                   ID3_FIELD_TEXTENCODING_UTF_16);

    }
    // update
    id3_file_update(id3);
    id3_file_close(id3);
}


// taken from the gtkpod code base
void id3_set_string(struct id3_tag *tag,
            const char *frame_name,
            const char *data, enum id3_field_textencoding encoding)
{
    int res;

    struct id3_frame *frame;

    union id3_field *field;

    id3_ucs4_t *ucs4;

    /* clear the frame, because of bug in libid3tag see
       http://www.mars.org/mailman/public/mad-dev/2004-October/001113.html
     */
    while ((frame =3D id3_tag_findframe(tag, frame_name, 0))) {
        id3_tag_detachframe(tag, frame);
        id3_frame_delete(frame);
    }

    if ((data =3D=3D NULL) || (strlen(data) =3D=3D 0))
        return;

    frame =3D id3_frame_new(frame_name);
    id3_tag_attachframe(tag, frame);

    /* Use the specified text encoding */
    field =3D id3_frame_field(frame, 0);
    id3_field_settextencoding(field, encoding);

    if ((strcmp(frame_name, ID3_FRAME_COMMENT) =3D=3D 0) ||
        (strcmp(frame_name, "USLT") =3D=3D 0)) {
        field =3D id3_frame_field(frame, 3);
        field->type =3D ID3_FIELD_TYPE_STRINGFULL;
    } else {
        field =3D id3_frame_field(frame, 1);
        field->type =3D ID3_FIELD_TYPE_STRINGLIST;
    }

    if (encoding =3D=3D ID3_FIELD_TEXTENCODING_ISO_8859_1) {
        /* we read 'ISO_8859_1' to stand for 'any locale charset'
           -- most programs seem to work that way */

        //always use utf-8, local encoding FIXME
        //id3_latin1_t *raw =3D charset_from_utf8(data);

        ucs4 =3D id3_latin1_ucs4duplicate(data);
        //g_free(raw);
    } else {
        /* Yeah! We use unicode encoding and won't have to
           worry about charsets */
        ucs4 =3D id3_utf8_ucs4duplicate((id3_utf8_t *) data);
    }

    if ((strcmp(frame_name, ID3_FRAME_COMMENT) =3D=3D 0)
        || (strcmp(frame_name, "USLT") =3D=3D 0))
        res =3D id3_field_setfullstring(field, ucs4);
    else
        res =3D id3_field_setstrings(field, 1, &ucs4);

    g_free(ucs4);

    if (res !=3D 0)
        g_print(_("Error setting ID3 field: %s\n"), frame_name);
}

--00151747beeab9e7aa047c2e3187
Content-Type: text/html; charset=UTF-8
Content-Transfer-Encoding: quoted-printable

Hi all,<br><br>Sorry for the double-post - gmail has decided to send the ma=
il before I was done :-(<br><br>I want to tag existing, untagged mp3 files.=
 Using the code below, I can save v1.1 id3 tags in the file,<br>but I&#39;m=
 struggling to get v2.3.0 tags to be saved as well (I want both v1.1 and v2=
.3.0 in the same file).<br>
The code below will just save properly the first tag (ID3_FRAME_COMMENT), t=
he second one seems to be ignored.<br><br>Any help or code snippet would be=
 welcome!<br><br>Thank&#39;s,<br><br>Pog<br><br>---<br>Code snippet below:<=
br>
<br>{<br>struct id3_file *id3 =3D<br>=C2=A0=C2=A0=C2=A0 =C2=A0=C2=A0=C2=A0 =
id3_file_open(&quot;/home/myself/foo.mp3&quot;,<br>=C2=A0=C2=A0=C2=A0 =C2=
=A0=C2=A0=C2=A0 =C2=A0=C2=A0=C2=A0 =C2=A0 ID3_FILE_MODE_READWRITE);<br><br>=
=C2=A0=C2=A0=C2=A0 struct id3_tag *tag =3D id3_file_tag(id3);<br><br>=C2=A0=
=C2=A0=C2=A0 if (tag !=3D NULL) {<br><br>
=C2=A0=C2=A0=C2=A0 =C2=A0=C2=A0=C2=A0 id3_tag_options(tag, ID3_TAG_OPTION_I=
D3V1, ~0);<br>=C2=A0=C2=A0=C2=A0 =C2=A0=C2=A0=C2=A0 id3_tag_options(tag, ID=
3_TAG_OPTION_COMPRESSION, 0);//for ipod/itunes compatibility<br>=C2=A0=C2=
=A0=C2=A0 =C2=A0=C2=A0=C2=A0 id3_tag_options(tag, ID3_TAG_OPTION_CRC, 0);<b=
r><br>=C2=A0=C2=A0=C2=A0 =C2=A0=C2=A0=C2=A0 id3_set_string(tag, ID3_FRAME_T=
ITLE,<br>
=C2=A0=C2=A0=C2=A0 =C2=A0=C2=A0=C2=A0 =C2=A0=C2=A0=C2=A0 =C2=A0=C2=A0=C2=A0=
=C2=A0=C2=A0=C2=A0 &quot;azertyuiopqdsfhjkklwxc=C3=A9=C3=A8=C3=A0=C3=A7@=C3=
=AA=C3=B4=C3=AE&quot;,<br>=C2=A0=C2=A0=C2=A0 =C2=A0=C2=A0=C2=A0 =C2=A0=C2=
=A0=C2=A0 =C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 ID3_FIELD_TEXTENCODING_UTF_1=
6);<br>=C2=A0=C2=A0=C2=A0 =C2=A0=C2=A0=C2=A0 id3_set_string(tag, &quot;TOWN=
&quot;,<br>=C2=A0=C2=A0=C2=A0 =C2=A0=C2=A0=C2=A0 =C2=A0=C2=A0=C2=A0 =C2=A0=
=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 &quot;SimplePod&quot;,<br>=C2=A0=C2=A0=C2=A0=
 =C2=A0=C2=A0=C2=A0 =C2=A0=C2=A0=C2=A0 =C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=
 ID3_FIELD_TEXTENCODING_UTF_16);<br>
<br>=C2=A0=C2=A0=C2=A0 }<br>=C2=A0=C2=A0=C2=A0 // update<br>=C2=A0=C2=A0=C2=
=A0 id3_file_update(id3);<br>=C2=A0=C2=A0=C2=A0 id3_file_close(id3);<br>}<b=
r><br><br>// taken from the gtkpod code base<br>void id3_set_string(struct =
id3_tag *tag,<br>=C2=A0=C2=A0=C2=A0 =C2=A0=C2=A0=C2=A0 =C2=A0=C2=A0=C2=A0 c=
onst char *frame_name,<br>
=C2=A0=C2=A0=C2=A0 =C2=A0=C2=A0=C2=A0 =C2=A0=C2=A0=C2=A0 const char *data, =
enum id3_field_textencoding encoding)<br>{<br>=C2=A0=C2=A0=C2=A0 int res;<b=
r><br>=C2=A0=C2=A0=C2=A0 struct id3_frame *frame;<br><br>=C2=A0=C2=A0=C2=A0=
 union id3_field *field;<br><br>=C2=A0=C2=A0=C2=A0 id3_ucs4_t *ucs4;<br><br=
>=C2=A0=C2=A0=C2=A0 /* clear the frame, because of bug in libid3tag see<br>
=C2=A0=C2=A0=C2=A0 =C2=A0=C2=A0 <a href=3D"http://www.mars.org/mailman/publ=
ic/mad-dev/2004-October/001113.html">http://www.mars.org/mailman/public/mad=
-dev/2004-October/001113.html</a><br>=C2=A0=C2=A0=C2=A0 =C2=A0*/<br>=C2=A0=
=C2=A0=C2=A0 while ((frame =3D id3_tag_findframe(tag, frame_name, 0))) {<br=
>
=C2=A0=C2=A0=C2=A0 =C2=A0=C2=A0=C2=A0 id3_tag_detachframe(tag, frame);<br>=
=C2=A0=C2=A0=C2=A0 =C2=A0=C2=A0=C2=A0 id3_frame_delete(frame);<br>=C2=A0=C2=
=A0=C2=A0 }<br><br>=C2=A0=C2=A0=C2=A0 if ((data =3D=3D NULL) || (strlen(dat=
a) =3D=3D 0))<br>=C2=A0=C2=A0=C2=A0 =C2=A0=C2=A0=C2=A0 return;<br><br>=C2=
=A0=C2=A0=C2=A0 frame =3D id3_frame_new(frame_name);<br>=C2=A0=C2=A0=C2=A0 =
id3_tag_attachframe(tag, frame);<br>
<br>=C2=A0=C2=A0=C2=A0 /* Use the specified text encoding */<br>=C2=A0=C2=
=A0=C2=A0 field =3D id3_frame_field(frame, 0);<br>=C2=A0=C2=A0=C2=A0 id3_fi=
eld_settextencoding(field, encoding);<br><br>=C2=A0=C2=A0=C2=A0 if ((strcmp=
(frame_name, ID3_FRAME_COMMENT) =3D=3D 0) ||<br>=C2=A0=C2=A0=C2=A0 =C2=A0=
=C2=A0=C2=A0 (strcmp(frame_name, &quot;USLT&quot;) =3D=3D 0)) {<br>
=C2=A0=C2=A0=C2=A0 =C2=A0=C2=A0=C2=A0 field =3D id3_frame_field(frame, 3);<=
br>=C2=A0=C2=A0=C2=A0 =C2=A0=C2=A0=C2=A0 field-&gt;type =3D ID3_FIELD_TYPE_=
STRINGFULL;<br>=C2=A0=C2=A0=C2=A0 } else {<br>=C2=A0=C2=A0=C2=A0 =C2=A0=C2=
=A0=C2=A0 field =3D id3_frame_field(frame, 1);<br>=C2=A0=C2=A0=C2=A0 =C2=A0=
=C2=A0=C2=A0 field-&gt;type =3D ID3_FIELD_TYPE_STRINGLIST;<br>=C2=A0=C2=A0=
=C2=A0 }<br>
<br>=C2=A0=C2=A0=C2=A0 if (encoding =3D=3D ID3_FIELD_TEXTENCODING_ISO_8859_=
1) {<br>=C2=A0=C2=A0=C2=A0 =C2=A0=C2=A0=C2=A0 /* we read &#39;ISO_8859_1&#3=
9; to stand for &#39;any locale charset&#39;<br>=C2=A0=C2=A0=C2=A0 =C2=A0=
=C2=A0=C2=A0 =C2=A0=C2=A0 -- most programs seem to work that way */<br><br>=
=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 //always use utf-8, local encodi=
ng FIXME<br>
=C2=A0=C2=A0=C2=A0 =C2=A0=C2=A0=C2=A0 //id3_latin1_t *raw =3D charset_from_=
utf8(data);<br><br>=C2=A0=C2=A0=C2=A0 =C2=A0=C2=A0=C2=A0 ucs4 =3D id3_latin=
1_ucs4duplicate(data);<br>=C2=A0=C2=A0=C2=A0 =C2=A0=C2=A0=C2=A0 //g_free(ra=
w);<br>=C2=A0=C2=A0=C2=A0 } else {<br>=C2=A0=C2=A0=C2=A0 =C2=A0=C2=A0=C2=A0=
 /* Yeah! We use unicode encoding and won&#39;t have to<br>=C2=A0=C2=A0=C2=
=A0 =C2=A0=C2=A0=C2=A0 =C2=A0=C2=A0 worry about charsets */<br>
=C2=A0=C2=A0=C2=A0 =C2=A0=C2=A0=C2=A0 ucs4 =3D id3_utf8_ucs4duplicate((id3_=
utf8_t *) data);<br>=C2=A0=C2=A0=C2=A0 }<br><br>=C2=A0=C2=A0=C2=A0 if ((str=
cmp(frame_name, ID3_FRAME_COMMENT) =3D=3D 0)<br>=C2=A0=C2=A0=C2=A0 =C2=A0=
=C2=A0=C2=A0 || (strcmp(frame_name, &quot;USLT&quot;) =3D=3D 0))<br>=C2=A0=
=C2=A0=C2=A0 =C2=A0=C2=A0=C2=A0 res =3D id3_field_setfullstring(field, ucs4=
);<br>
=C2=A0=C2=A0=C2=A0 else<br>=C2=A0=C2=A0=C2=A0 =C2=A0=C2=A0=C2=A0 res =3D id=
3_field_setstrings(field, 1, &amp;ucs4);<br><br>=C2=A0=C2=A0=C2=A0 g_free(u=
cs4);<br><br>=C2=A0=C2=A0=C2=A0 if (res !=3D 0)<br>=C2=A0=C2=A0=C2=A0 =C2=
=A0=C2=A0=C2=A0 g_print(_(&quot;Error setting ID3 field: %s\n&quot;), frame=
_name);<br>}<br>

--00151747beeab9e7aa047c2e3187--