Hi,
In developing Audacity (a cross-platform audio editor), I've
continued to have nothing but good experiences with libmad.
I recently added support for 24-bit and 32-bit samples in
Audacity, and it's great that using libmad I can take
advantage of these sample formats.
I'd like to also switch over to using libid3tag. We had
been using id3lib, but it's buggy and has trouble compiling
on a lot of systems.
Our needs are minimal. We're not trying to be the ultimate
ID3 editor; we just want to be able to read and write
the most common tags for convenience.
I didn't see any documentation on libid3tag...did I miss
something? The sample code only uses a small subset
of its features.
Anyway, I was able to figure out how to use libid3tag
to import tags from a file. But I'm stuck trying to
render them using id3_tag_render.
1. First of all, the only way I was able to figure out to
add new frames was to muck around in the data structures.
Is this correct? It might be nice if there were more
API functions to make it easier...
For example, id3lib has a "simple API" which provides
functions that let you add and/or query the most common
tags (Title, Artist, etc.), without mucking in the
data structure at all.
2. What's the proper way to convert an ASCII string to
an id3_ucs4_t string? (I used a for loop, casting
chars to longs...is that OK?)
3. When I try to enable the ID3_TAG_OPTION_ID3V1,
the rendering fails. Is it supported?
4. Finally, I do get some bytes back from id3_tag_render
without the ID3V1 option, but when I prepend them to
the beginning of my MP3 file, programs don't recognize
them. In fact even libid3tag doesn't even load any
tags from the resulting file. Is there something else
I need to do to the id3_tag_render output?
I'm including some of my source code below. Thanks for
any help anyone can offer.
- Dominic
struct id3_frame *MakeID3Frame(const char *name, const char *data)
{
struct id3_frame *frame;
union id3_field *field;
id3_ucs4_t *ustr;
int i;
ustr = (id3_ucs4_t *)malloc(sizeof(id3_ucs4_t)*(strlen(data)+1));
for(i=0; i<strlen(data)+1; i++)
ustr[i] = (id3_ucs4_t)data[i];
field = (union id3_field *)calloc(1, sizeof(union id3_field));
field->type = ID3_FIELD_TYPE_STRINGLIST;
id3_field_setstrings(field, 1, &ustr);
frame = (struct id3_frame *)calloc(1, sizeof(struct id3_frame));
strncpy(frame->id, name, 4);
frame->nfields = 1;
frame->fields = field;
return frame;
}
// returns buffer len; caller frees
int Tags::ExportID3(char **buffer, bool *endOfFile)
{
struct id3_tag *tp;
struct id3_frame *frame;
tp = id3_tag_new();
id3_tag_attachframe(tp, MakeID3Frame(ID3_FRAME_TITLE, mTitle));
id3_tag_attachframe(tp, MakeID3Frame(ID3_FRAME_ARTIST, mArtist));
id3_tag_attachframe(tp, MakeID3Frame(ID3_FRAME_ALBUM, mAlbum));
if (mID3V2) {
tp->options |= ID3_TAG_OPTION_COMPRESSION;
*endOfFile = false;
}
else {
tp->options |= ID3_TAG_OPTION_ID3V1;
*endOfFile = true;
}
id3_length_t len;
len = id3_tag_render(tp, 0);
*buffer = (char *)malloc(len);
len = id3_tag_render(tp, (id3_byte_t *)*buffer);
id3_tag_delete(tp);
return len;
}