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; }