diff options
-rw-r--r-- | src/audioOutputs/audioOutput_shout.c | 20 | ||||
-rw-r--r-- | src/decode.c | 4 | ||||
-rw-r--r-- | src/directory.c | 59 | ||||
-rw-r--r-- | src/inputPlugins/flac_plugin.c | 122 | ||||
-rw-r--r-- | src/inputPlugins/mod_plugin.c | 4 | ||||
-rw-r--r-- | src/inputPlugins/mp3_plugin.c | 20 | ||||
-rw-r--r-- | src/inputPlugins/mp4_plugin.c | 42 | ||||
-rw-r--r-- | src/inputPlugins/ogg_plugin.c | 28 | ||||
-rw-r--r-- | src/metadataChunk.c | 28 | ||||
-rw-r--r-- | src/song.c | 43 | ||||
-rw-r--r-- | src/tag.c | 158 | ||||
-rw-r--r-- | src/tag.h | 35 |
12 files changed, 335 insertions, 228 deletions
diff --git a/src/audioOutputs/audioOutput_shout.c b/src/audioOutputs/audioOutput_shout.c index 8eb4f4672..7f21a73f4 100644 --- a/src/audioOutputs/audioOutput_shout.c +++ b/src/audioOutputs/audioOutput_shout.c @@ -375,9 +375,23 @@ static void myShout_closeDevice(AudioOutput * audioOutput) { static void copyTagToVorbisComment(ShoutData * sd) { if(sd->tag) { - addTag("ARTIST", sd->tag->artist); - addTag("ALBUM", sd->tag->album); - addTag("TITLE", sd->tag->title); + MpdTagItem * item = sd->tag->tagItems; + + while(item && item->type!=TAG_ITEM_END) { + switch(item->type) { + case TAG_ITEM_ARTIST: + addTag("ARTIST", item->value); + break; + case TAG_ITEM_ALBUM: + addTag("ALBUM", item->value); + break; + case TAG_ITEM_TITLE: + addTag("TITLE", item->value); + break; + } + + item++; + } } } diff --git a/src/decode.c b/src/decode.c index 52923ce87..893e1a55c 100644 --- a/src/decode.c +++ b/src/decode.c @@ -158,10 +158,6 @@ int waitOnDecode(PlayerControl * pc, DecoderControl * dc, OutputBuffer * cb, } if((tag = metadataChunkToMpdTagDup(&(pc->fileMetadataChunk)))) { - /* lets put the filename in the title if no tag info */ - if(!tag->title && !tag->artist && !tag->album) { - tag->title = strdup(pc->currentUrl); - } sendMetadataToAudioDevice(tag); freeMpdTag(tag); } diff --git a/src/directory.c b/src/directory.c index 38043276f..0fa5e85f6 100644 --- a/src/directory.c +++ b/src/directory.c @@ -1188,29 +1188,42 @@ int printSongInDirectory(FILE * fp, Song * song, void * data) { return 0; } -int searchForAlbumInDirectory(FILE * fp, Song * song, void * string) { - if(song->tag && song->tag->album) { - char * dup = strDupToUpper(song->tag->album); - if(strstr(dup,(char *)string)) printSongInfo(fp,song); +static inline int strstrSearchTag(Song * song, int type, char * str) { + MpdTagItem * item; + char * dup; + + if(!song->tag) return 0; + + for(item = song->tag->tagItems; item && item->type!=TAG_ITEM_END; + item++) + { + if(item->type != type) continue; + + dup = strDupToUpper(item->value); + if(strstr(dup, str)) return 1; free(dup); } + + return 0; +} + +int searchForAlbumInDirectory(FILE * fp, Song * song, void * string) { + if(strstrSearchTag(song, TAG_ITEM_ALBUM, (char *)string)) { + printSongInfo(fp, song); + } return 0; } int searchForArtistInDirectory(FILE * fp, Song * song, void * string) { - if(song->tag && song->tag->artist) { - char * dup = strDupToUpper(song->tag->artist); - if(strstr(dup,(char *)string)) printSongInfo(fp,song); - free(dup); + if(strstrSearchTag(song, TAG_ITEM_ARTIST, (char *)string)) { + printSongInfo(fp, song); } return 0; } int searchForTitleInDirectory(FILE * fp, Song * song, void * string) { - if(song->tag && song->tag->title) { - char * dup = strDupToUpper(song->tag->title); - if(strstr(dup,(char *)string)) printSongInfo(fp,song); - free(dup); + if(strstrSearchTag(song, TAG_ITEM_TITLE, (char *)string)) { + printSongInfo(fp, song); } return 0; } @@ -1249,9 +1262,24 @@ int searchForSongsIn(FILE * fp, char * name, char * item, char * string) { return ret; } +static inline int tagItemFoundAndMatches(Song * song, int type, char * str) { + MpdTagItem * item; + + if(!song->tag) return 0; + + for(item = song->tag->tagItems; item && item->type != TAG_ITEM_END; + item++) + { + if(item->type != type) continue; + + if( 0 == strcmp(str, item->value)) return 1; + } + + return 0; +} + int findAlbumInDirectory(FILE * fp, Song * song, void * string) { - if(song->tag && song->tag->album && - strcmp((char *)string,song->tag->album)==0) + if(tagItemFoundAndMatches(song, TAG_ITEM_ALBUM, (char *)string)) { printSongInfo(fp,song); } @@ -1260,8 +1288,7 @@ int findAlbumInDirectory(FILE * fp, Song * song, void * string) { } int findArtistInDirectory(FILE * fp, Song * song, void * string) { - if(song->tag && song->tag->artist && - strcmp((char *)string,song->tag->artist)==0) + if(tagItemFoundAndMatches(song, TAG_ITEM_ARTIST, (char *)string)) { printSongInfo(fp,song); } diff --git a/src/inputPlugins/flac_plugin.c b/src/inputPlugins/flac_plugin.c index d038f1418..bc706ff64 100644 --- a/src/inputPlugins/flac_plugin.c +++ b/src/inputPlugins/flac_plugin.c @@ -450,12 +450,73 @@ FLAC__StreamDecoderWriteStatus flacWrite(const FLAC__SeekableStreamDecoder *dec, return FLAC__STREAM_DECODER_WRITE_STATUS_CONTINUE; } +static int commentMatchesAddToTag( + char * str, + FLAC__StreamMetadata_VorbisComment_Entry * entry, + int itemType, + MpdTag ** tag) +{ + int slen = strlen(str); + int vlen = entry->length - slen; + + if( vlen <= 0 ) return 0; + + if( 0 == strncasecmp(str, entry->entry, slen) ) { + if(*tag == NULL) *tag = newMpdTag(); + addItemToMpdTagWithLen(*tag, itemType, + entry->entry+slen, vlen); + return 1; + } + + return 0; +} + + +static MpdTag * copyVorbisCommentBlockToMpdTag(FLAC__StreamMetadata * block, + MpdTag * tag) +{ + int i; + + for(i = 0; i < block->data.vorbis_comment.num_comments; i++) { + if(commentMatchesAddToTag( + "artist=", + block->data.vorbis_comment.comments+i, + TAG_ITEM_ARTIST, + &tag)); + else if(commentMatchesAddToTag( + "title=", + block->data.vorbis_comment.comments+i, + TAG_ITEM_TITLE, + &tag)); + else if(commentMatchesAddToTag( + "album=", + block->data.vorbis_comment.comments+i, + TAG_ITEM_ALBUM, + &tag)); + else if(commentMatchesAddToTag( + "tracknumber=", + block->data.vorbis_comment.comments+i, + TAG_ITEM_TRACK, + &tag)); + else if(commentMatchesAddToTag( + "genre=", + block->data.vorbis_comment.comments+i, + TAG_ITEM_GENRE, + &tag)); + else if(commentMatchesAddToTag( + "date=", + block->data.vorbis_comment.comments+i, + TAG_ITEM_DATE, + &tag)); + } + + return tag; +} + MpdTag * flacMetadataDup(char * file, int * vorbisCommentFound) { MpdTag * ret = NULL; FLAC__Metadata_SimpleIterator * it; FLAC__StreamMetadata * block = NULL; - int offset; - int len, pos; *vorbisCommentFound = 0; @@ -469,60 +530,9 @@ MpdTag * flacMetadataDup(char * file, int * vorbisCommentFound) { block = FLAC__metadata_simple_iterator_get_block(it); if(!block) break; if(block->type == FLAC__METADATA_TYPE_VORBIS_COMMENT) { - char * dup; - - offset = FLAC__metadata_object_vorbiscomment_find_entry_from(block,0,"artist"); - if(offset>=0) { - *vorbisCommentFound = 1; - if(!ret) ret = newMpdTag(); - pos = strlen("artist="); - len = block->data.vorbis_comment.comments[offset].length-pos; - if(len>0) { - dup = malloc(len+1); - memcpy(dup,&(block->data.vorbis_comment.comments[offset].entry[pos]),len); - dup[len] = '\0'; - ret->artist = dup; - } - } - offset = FLAC__metadata_object_vorbiscomment_find_entry_from(block,0,"album"); - if(offset>=0) { - *vorbisCommentFound = 1; - if(!ret) ret = newMpdTag(); - pos = strlen("album="); - len = block->data.vorbis_comment.comments[offset].length-pos; - if(len>0) { - dup = malloc(len+1); - memcpy(dup,&(block->data.vorbis_comment.comments[offset].entry[pos]),len); - dup[len] = '\0'; - ret->album = dup; - } - } - offset = FLAC__metadata_object_vorbiscomment_find_entry_from(block,0,"title"); - if(offset>=0) { - *vorbisCommentFound = 1; - if(!ret) ret = newMpdTag(); - pos = strlen("title="); - len = block->data.vorbis_comment.comments[offset].length-pos; - if(len>0) { - dup = malloc(len+1); - memcpy(dup,&(block->data.vorbis_comment.comments[offset].entry[pos]),len); - dup[len] = '\0'; - ret->title = dup; - } - } - offset = FLAC__metadata_object_vorbiscomment_find_entry_from(block,0,"tracknumber"); - if(offset>=0) { - *vorbisCommentFound = 1; - if(!ret) ret = newMpdTag(); - pos = strlen("tracknumber="); - len = block->data.vorbis_comment.comments[offset].length-pos; - if(len>0) { - dup = malloc(len+1); - memcpy(dup,&(block->data.vorbis_comment.comments[offset].entry[pos]),len); - dup[len] = '\0'; - ret->track = dup; - } - } + ret = copyVorbisCommentBlockToMpdTag(block, ret); + + if(ret) *vorbisCommentFound = 1; } else if(block->type == FLAC__METADATA_TYPE_STREAMINFO) { if(!ret) ret = newMpdTag(); diff --git a/src/inputPlugins/mod_plugin.c b/src/inputPlugins/mod_plugin.c index 2a03cc404..a204867fb 100644 --- a/src/inputPlugins/mod_plugin.c +++ b/src/inputPlugins/mod_plugin.c @@ -212,6 +212,7 @@ int mod_decode(OutputBuffer * cb, DecoderControl * dc, char * path) { MpdTag * modTagDup(char * file) { MpdTag * ret = NULL; MODULE * moduleHandle; + char * title = NULL; if(mod_initMikMod() < 0) return NULL; @@ -222,7 +223,8 @@ MpdTag * modTagDup(char * file) { ret = newMpdTag(); ret->time = 0; - ret->title = Player_LoadTitle(file); + title = Player_LoadTitle(file); + if(title) addItemToMpdTag(ret, TAG_ITEM_TITLE, title); fail: MikMod_Exit(); diff --git a/src/inputPlugins/mp3_plugin.c b/src/inputPlugins/mp3_plugin.c index ab204ffa9..cdb2a74c0 100644 --- a/src/inputPlugins/mp3_plugin.c +++ b/src/inputPlugins/mp3_plugin.c @@ -549,9 +549,12 @@ int mp3Read(mp3DecodeData * data, OutputBuffer * cb, DecoderControl * dc) { if(data->inStream->metaTitle) { MpdTag * tag = newMpdTag(); if(data->inStream->metaName) { - tag->name = strdup(data->inStream->metaName); + addItemToMpdTag(tag, + TAG_ITEM_NAME, + data->inStream->metaName); } - tag->title = strdup(data->inStream->metaTitle); + addItemToMpdTag(tag, TAG_ITEM_TITLE, + data->inStream->metaTitle); free(data->inStream->metaTitle); data->inStream->metaTitle = NULL; copyMpdTagToOutputBuffer(cb, tag); @@ -676,19 +679,21 @@ int mp3_decode(OutputBuffer * cb, DecoderControl * dc, InputStream * inStream) { if(inStream->metaTitle) { if(tag) freeMpdTag(tag); tag = newMpdTag(); - tag->title = strdup(inStream->metaTitle); + addItemToMpdTag(tag, TAG_ITEM_TITLE, inStream->metaTitle); free(inStream->metaTitle); inStream->metaTitle = NULL; if(inStream->metaName) { - tag->name = strdup(inStream->metaName); + addItemToMpdTag(tag, TAG_ITEM_NAME, + inStream->metaName); } copyMpdTagToOutputBuffer(cb, tag); freeMpdTag(tag); } else if(tag) { if(inStream->metaName) { - if(tag->name) free(tag->name); - tag->name = strdup(inStream->metaName); + clearItemsFromMpdTag(tag, TAG_ITEM_NAME); + addItemToMpdTag(tag, TAG_ITEM_NAME, + inStream->metaName); } copyMpdTagToOutputBuffer(cb, tag); freeMpdTag(tag); @@ -696,7 +701,8 @@ int mp3_decode(OutputBuffer * cb, DecoderControl * dc, InputStream * inStream) { else if(inStream->metaName) { tag = newMpdTag(); if(inStream->metaName) { - tag->name = strdup(inStream->metaName); + addItemToMpdTag(tag, TAG_ITEM_NAME, + inStream->metaName); } copyMpdTagToOutputBuffer(cb, tag); freeMpdTag(tag); diff --git a/src/inputPlugins/mp4_plugin.c b/src/inputPlugins/mp4_plugin.c index 66d5600b4..a66f7d43d 100644 --- a/src/inputPlugins/mp4_plugin.c +++ b/src/inputPlugins/mp4_plugin.c @@ -322,6 +322,7 @@ MpdTag * mp4DataDup(char * file, int * mp4MetadataFound) { int32_t track; int32_t time; int32_t scale; + int i; *mp4MetadataFound = 0; @@ -359,20 +360,39 @@ MpdTag * mp4DataDup(char * file, int * mp4MetadataFound) { } ret->time = ((float)time)/scale+0.5; - if(!mp4ff_meta_get_artist(mp4fh,&ret->artist)) { - *mp4MetadataFound = 1; - } + for(i = 0; i < mp4ff_meta_get_num_items(mp4fh); i++) { + char * item; + char * value; - if(!mp4ff_meta_get_album(mp4fh,&ret->album)) { - *mp4MetadataFound = 1; - } + mp4ff_meta_get_by_index(mp4fh, i, &item, &value); - if(!mp4ff_meta_get_title(mp4fh,&ret->title)) { - *mp4MetadataFound = 1; - } + if(0 == strcasecmp("artist", item)) { + addItemToMpdTag(ret, TAG_ITEM_ARTIST, value); + *mp4MetadataFound = 1; + } + else if(0 == strcasecmp("title", item)) { + addItemToMpdTag(ret, TAG_ITEM_TITLE, value); + *mp4MetadataFound = 1; + } + else if(0 == strcasecmp("album", item)) { + addItemToMpdTag(ret, TAG_ITEM_ALBUM, value); + *mp4MetadataFound = 1; + } + else if(0 == strcasecmp("track", item)) { + addItemToMpdTag(ret, TAG_ITEM_TRACK, value); + *mp4MetadataFound = 1; + } + else if(0 == strcasecmp("genre", item)) { + addItemToMpdTag(ret, TAG_ITEM_GENRE, value); + *mp4MetadataFound = 1; + } + else if(0 == strcasecmp("date", item)) { + addItemToMpdTag(ret, TAG_ITEM_DATE, value); + *mp4MetadataFound = 1; + } - if(!mp4ff_meta_get_track(mp4fh,&ret->track)) { - *mp4MetadataFound = 1; + free(item); + free(value); } mp4ff_close(mp4fh); diff --git a/src/inputPlugins/ogg_plugin.c b/src/inputPlugins/ogg_plugin.c index d6add6d3a..b681a27e0 100644 --- a/src/inputPlugins/ogg_plugin.c +++ b/src/inputPlugins/ogg_plugin.c @@ -162,27 +162,27 @@ MpdTag * oggCommentsParse(char ** comments) { while(*comments) { if((temp = ogg_parseComment(*comments,"artist"))) { if(!ret) ret = newMpdTag(); - if(!ret->artist) { - ret->artist = strdup(temp); - } + addItemToMpdTag(ret, TAG_ITEM_ARTIST, temp); } else if((temp = ogg_parseComment(*comments,"title"))) { if(!ret) ret = newMpdTag(); - if(!ret->title) { - ret->title = strdup(temp); - } + addItemToMpdTag(ret, TAG_ITEM_TITLE, temp); } else if((temp = ogg_parseComment(*comments,"album"))) { if(!ret) ret = newMpdTag(); - if(!ret->album) { - ret->album = strdup(temp); - } + addItemToMpdTag(ret, TAG_ITEM_ALBUM, temp); } else if((temp = ogg_parseComment(*comments,"tracknumber"))) { if(!ret) ret = newMpdTag(); - if(!ret->track) { - ret->track = strdup(temp); - } + addItemToMpdTag(ret, TAG_ITEM_TRACK, temp); + } + else if((temp = ogg_parseComment(*comments,"genre"))) { + if(!ret) ret = newMpdTag(); + addItemToMpdTag(ret, TAG_ITEM_GENRE, temp); + } + else if((temp = ogg_parseComment(*comments,"date"))) { + if(!ret) ret = newMpdTag(); + addItemToMpdTag(ret, TAG_ITEM_DATE, temp); } comments++; @@ -208,8 +208,8 @@ void putOggCommentsIntoOutputBuffer(OutputBuffer * cb, char * streamName, if(tag->title) printf("Title: %s\n", tag->title);*/ if(streamName) { - if(tag->name) free(tag->name); - tag->name = strdup(streamName); + clearItemsFromMpdTag(tag, TAG_ITEM_NAME); + addItemToMpdTag(tag, TAG_ITEM_NAME, streamName); } copyMpdTagToOutputBuffer(cb, tag); diff --git a/src/metadataChunk.c b/src/metadataChunk.c index 84817eb0e..40da4c512 100644 --- a/src/metadataChunk.c +++ b/src/metadataChunk.c @@ -29,9 +29,9 @@ void initMetadataChunk(MetadataChunk * chunk) { chunk->title = -1; } -#define dupElementToTag(string, element) { \ +#define dupElementToTag(item, element) { \ if(element >= 0 && element < METADATA_BUFFER_LENGTH) { \ - string = strdup(chunk->buffer+element); \ + addItemToMpdTag(ret, item, chunk->buffer+element); \ } \ } @@ -40,10 +40,10 @@ MpdTag * metadataChunkToMpdTagDup(MetadataChunk * chunk) { chunk->buffer[METADATA_BUFFER_LENGTH-1] = '\0'; - dupElementToTag(ret->name, chunk->name); - dupElementToTag(ret->title, chunk->title); - dupElementToTag(ret->artist, chunk->artist); - dupElementToTag(ret->album, chunk->album); + dupElementToTag(TAG_ITEM_NAME, chunk->name); + dupElementToTag(TAG_ITEM_TITLE, chunk->title); + dupElementToTag(TAG_ITEM_ARTIST, chunk->artist); + dupElementToTag(TAG_ITEM_ALBUM, chunk->album); return ret; } @@ -67,8 +67,16 @@ void copyMpdTagToMetadataChunk(MpdTag * tag, MetadataChunk * chunk) { if(!tag) return; - copyStringToChunk(tag->name, chunk->name); - copyStringToChunk(tag->title, chunk->title); - copyStringToChunk(tag->artist, chunk->artist); - copyStringToChunk(tag->album, chunk->album); + copyStringToChunk( + getNextItemFromMpdTag(tag, TAG_ITEM_NAME, NULL), + chunk->name); + copyStringToChunk( + getNextItemFromMpdTag(tag, TAG_ITEM_TITLE, NULL), + chunk->title); + copyStringToChunk( + getNextItemFromMpdTag(tag, TAG_ITEM_ARTIST, NULL), + chunk->title); + copyStringToChunk( + getNextItemFromMpdTag(tag, TAG_ITEM_ALBUM, NULL), + chunk->album); } diff --git a/src/song.c b/src/song.c index fac103fad..3d8ef4769 100644 --- a/src/song.c +++ b/src/song.c @@ -28,11 +28,6 @@ #define SONG_KEY "key: " #define SONG_FILE "file: " -#define SONG_ARTIST "Artist: " -#define SONG_ALBUM "Album: " -#define SONG_TRACK "Track: " -#define SONG_TITLE "Title: " -#define SONG_NAME "Name: " #define SONG_TIME "Time: " #define SONG_MTIME "mtime: " @@ -185,6 +180,20 @@ void insertSongIntoList(SongList * list, ListNode ** nextSongNode, char * key, } } +static int matchesAnMpdTagItemKey(char * buffer, int * itemType) { + int i; + + for(i = 0; i < TAG_NUM_OF_ITEM_TYPES; i++) { + if( 0 == strncmp(mpdTagItemKeys[i], buffer, + strlen(mpdTagItemKeys[i]))) + { + return 1; + } + } + + return 0; +} + void readSongInfoIntoList(FILE * fp, SongList * list) { char buffer[MAXPATHLEN+1024]; int bufferSize = MAXPATHLEN+1024; @@ -192,6 +201,7 @@ void readSongInfoIntoList(FILE * fp, SongList * list) { char * key = NULL; ListNode * nextSongNode = list->firstNode; ListNode * nodeTemp; + int itemType; while(myFgets(buffer,bufferSize,fp) && 0!=strcmp(SONG_END,buffer)) { if(0==strncmp(SONG_KEY,buffer,strlen(SONG_KEY))) { @@ -212,32 +222,17 @@ void readSongInfoIntoList(FILE * fp, SongList * list) { } song->utf8url = strdup(&(buffer[strlen(SONG_FILE)])); } - else if(0==strncmp(SONG_ARTIST,buffer,strlen(SONG_ARTIST))) { - if(!song->tag) song->tag = newMpdTag(); - song->tag->artist = strdup(&(buffer[strlen(SONG_ARTIST)])); - } - else if(0==strncmp(SONG_ALBUM,buffer,strlen(SONG_ALBUM))) { - if(!song->tag) song->tag = newMpdTag(); - song->tag->album = strdup(&(buffer[strlen(SONG_ALBUM)])); - } - else if(0==strncmp(SONG_TRACK,buffer,strlen(SONG_TRACK))) { - if(!song->tag) song->tag = newMpdTag(); - song->tag->track = strdup(&(buffer[strlen(SONG_TRACK)])); - } - else if(0==strncmp(SONG_TITLE,buffer,strlen(SONG_TITLE))) { - if(!song->tag) song->tag = newMpdTag(); - song->tag->title = strdup(&(buffer[strlen(SONG_TITLE)])); - } - else if(0==strncmp(SONG_NAME,buffer,strlen(SONG_NAME))) { + else if(matchesAnMpdTagItemKey(buffer, &itemType)) { if(!song->tag) song->tag = newMpdTag(); - song->tag->name = strdup(&(buffer[strlen(SONG_NAME)])); + addItemToMpdTag(song->tag, itemType, + &(buffer[strlen(mpdTagItemKeys[itemType])])); } else if(0==strncmp(SONG_TIME,buffer,strlen(SONG_TIME))) { if(!song->tag) song->tag = newMpdTag(); song->tag->time = atoi(&(buffer[strlen(SONG_TIME)])); } else if(0==strncmp(SONG_MTIME,buffer,strlen(SONG_MTIME))) { - song->mtime = atoi(&(buffer[strlen(SONG_TITLE)])); + song->mtime = atoi(&(buffer[strlen(SONG_MTIME)])); } else { ERROR("songinfo: unknown line in db: %s\n",buffer); @@ -40,12 +40,25 @@ #include <FLAC/metadata.h> #endif +char * mpdTagItemsKeys[TAG_NUM_OF_ITEM_TYPES] = +{ + "Artist", + "Album", + "Title", + "Track", + "Name", + "Genre", + "Date" +}; + void printMpdTag(FILE * fp, MpdTag * tag) { - if(tag->artist) myfprintf(fp,"Artist: %s\n",tag->artist); - if(tag->album) myfprintf(fp,"Album: %s\n",tag->album); - if(tag->track) myfprintf(fp,"Track: %s\n",tag->track); - if(tag->title) myfprintf(fp,"Title: %s\n",tag->title); - if(tag->name) myfprintf(fp,"Name: %s\n",tag->name); + MpdTagItem * item; + + for(item = tag->tagItems; item && item->type!=TAG_ITEM_END; item++) { + myfprintf(fp, "%s: %s\n", mpdTagItemKeys[item->type], + item->value); + } + if(tag->time>=0) myfprintf(fp,"Time: %i\n",tag->time); } @@ -60,25 +73,24 @@ void printMpdTag(FILE * fp, MpdTag * tag) { } void validateUtf8Tag(MpdTag * tag) { - fixUtf8(tag->artist); - stripReturnChar(tag->artist); - fixUtf8(tag->album); - stripReturnChar(tag->album); - fixUtf8(tag->track); - stripReturnChar(tag->track); - fixUtf8(tag->title); - stripReturnChar(tag->title); - fixUtf8(tag->name); - stripReturnChar(tag->name); + MpdTagItem * item = tag->tagItems; + + while(item && item->type != TAG_ITEM_END) { + fixUtf8(item->value); + stripReturnChar(item->value); + item++; + } } #ifdef HAVE_ID3TAG -char * getID3Info(struct id3_tag * tag, char * id) { +MpdTag * getID3Info(struct id3_tag * tag, char * id, int type, MpdTag * mpdTag) +{ struct id3_frame const * frame; id3_ucs4_t const * ucs4; id3_utf8_t * utf8; union id3_field const * field; unsigned int nstrings; + int i; frame = id3_tag_findframe(tag, id, 0); if(!frame) return NULL; @@ -87,44 +99,37 @@ char * getID3Info(struct id3_tag * tag, char * id) { nstrings = id3_field_getnstrings(field); if(nstrings<1) return NULL; - ucs4 = id3_field_getstrings(field,0); - assert(ucs4); + for(i = 0; i < nstrings; i++) { + ucs4 = id3_field_getstrings(field,0); + assert(ucs4); + + if(type == TAG_ITEM_GENRE) { + ucs4 = id3_genre_name(ucs4); + } + + utf8 = id3_ucs4_utf8duplicate(ucs4); + if(!utf8) continue; - utf8 = id3_ucs4_utf8duplicate(ucs4); - if(!utf8) return NULL; + if( NULL == mpdTag ) mpdTag == newMpdTag(); + addItemToMpdTag(mpdTag, type, utf8); - return utf8; + free(utf8); + } + + return mpdTag; } #endif #ifdef HAVE_ID3TAG MpdTag * parseId3Tag(struct id3_tag * tag) { MpdTag * ret = NULL; - char * str; - - str = getID3Info(tag,ID3_FRAME_ARTIST); - if(str) { - if(!ret) ret = newMpdTag(); - ret->artist = str; - } - str = getID3Info(tag,ID3_FRAME_TITLE); - if(str) { - if(!ret) ret = newMpdTag(); - ret->title = str; - } - - str = getID3Info(tag,ID3_FRAME_ALBUM); - if(str) { - if(!ret) ret = newMpdTag(); - ret->album = str; - } - - str = getID3Info(tag,ID3_FRAME_TRACK); - if(str) { - if(!ret) ret = newMpdTag(); - ret->track = str; - } + ret = getID3Info(tag, ID3_FRAME_ARTIST, TAG_ITEM_ARTIST, ret); + ret = getID3Info(tag, ID3_FRAME_TITLE, TAG_ITEM_TITLE, ret); + ret = getID3Info(tag, ID3_FRAME_ALBUM, TAG_ITEM_ALBUM, ret); + ret = getID3Info(tag, ID3_FRAME_TRACK, TAG_ITEM_TRACK, ret); + ret = getID3Info(tag, ID3_FRAME_YEAR, TAG_ITEM_DATE, ret); + ret = getID3Info(tag, ID3_FRAME_GENRE, TAG_ITEM_GENRE, ret); return ret; } @@ -158,21 +163,20 @@ MpdTag * id3Dup(char * file) { MpdTag * newMpdTag() { MpdTag * ret = malloc(sizeof(MpdTag)); - ret->album = NULL; - ret->artist = NULL; - ret->title = NULL; - ret->track = NULL; - ret->name = NULL; + ret->tagItems = NULL; ret->time = -1; return ret; } void clearMpdTag(MpdTag * tag) { - if(tag->artist) free(tag->artist); - if(tag->album) free(tag->album); - if(tag->title) free(tag->title); - if(tag->name) free(tag->name); - if(tag->track) free(tag->track); + MpdTagItem * item; + + for(item = tag->tagItems; item && item->type != TAG_ITEM_END; item++) { + free(item->value); + } + + if(tag->tagItems) free(tag->tagItems); + tag->tagItems = NULL; } void freeMpdTag(MpdTag * tag) { @@ -182,40 +186,40 @@ void freeMpdTag(MpdTag * tag) { MpdTag * mpdTagDup(MpdTag * tag) { MpdTag * ret = NULL; + MpdTagItem * item; - if(tag) { - ret = newMpdTag(); - if(tag->artist) ret->artist = strdup(tag->artist); - if(tag->album) ret->album = strdup(tag->album); - if(tag->title) ret->title = strdup(tag->title); - if(tag->track) ret->track = strdup(tag->track); - if(tag->name) ret->name = strdup(tag->name); - ret->time = tag->time; - } + if(!tag) return NULL; - return ret; -} + ret = newMpdTag(); + ret->time = tag->time; -int mpdTagStringsAreEqual(char * s1, char * s2) { - if(s1 && s2) { - if(strcmp(s1, s2)) return 0; - } - else if(s1 || s2) return 0; + for(item = tag->tagItems; item && item->type != TAG_ITEM_END; item++) { + addItemToMpdTag(ret, item->type, item->value); + } - return 1; + return ret; } int mpdTagsAreEqual(MpdTag * tag1, MpdTag * tag2) { + MpdTagItem * item1; + MpdTagItem * item2; + if(tag1 == NULL && tag2 == NULL) return 1; else if(!tag1 || !tag2) return 0; if(tag1->time != tag2->time) return 0; - if(!mpdTagStringsAreEqual(tag1->artist, tag2->artist)) return 0; - if(!mpdTagStringsAreEqual(tag1->album, tag2->album)) return 0; - if(!mpdTagStringsAreEqual(tag1->track, tag2->track)) return 0; - if(!mpdTagStringsAreEqual(tag1->title, tag2->title)) return 0; - if(!mpdTagStringsAreEqual(tag1->name, tag2->name)) return 0; + for(item1 = tag1->tagItems, item2 = tag2->tagItems; + item1 && item1->type != TAG_ITEM_END; + item1++, item2++) + { + if(!item2) return 0; + if(item1->type != item2->type) return 0; + if(0 == strcmp(item1->value, item2->value)) return 0; + } + + if(item2 && !item1) return 0; + if(item2->type != item1->type) return 0; return 1; } @@ -21,6 +21,8 @@ #include "../config.h" +#include "mpd_types.h" + #include <stdio.h> #ifdef HAVE_ID3TAG #ifdef USE_MPD_ID3TAG @@ -30,13 +32,27 @@ #endif #endif +#define TAG_ITEM_END -1 +#define TAG_ITEM_ARTIST 0 +#define TAG_ITEM_ALBUM 1 +#define TAG_ITEM_TITLE 2 +#define TAG_ITEM_TRACK 3 +#define TAG_ITEM_NAME 4 +#define TAG_ITEM_GENRE 5 +#define TAG_ITEM_DATE 6 + +#define TAG_NUM_OF_ITEM_TYPES 7 + +extern char * mpdTagItemKeys[]; + +typedef struct _MpdTagItem { + mpd_sint8 type; + char * value; +} MpdTagItem; + typedef struct _MpdTag { - char * artist; - char * album; - char * track; - char * title; - char * name; int time; + MpdTagItem * tagItems; } MpdTag; #ifdef HAVE_ID3TAG @@ -47,10 +63,16 @@ MpdTag * id3Dup(char * file); MpdTag * newMpdTag(); +void clearItemsFromMpdTag(MpdTag * tag, int itemType); + void clearMpdTag(MpdTag * tag); void freeMpdTag(MpdTag * tag); +void addItemToMpdTag(MpdTag * tag, int itemType, char * value); + +void addItemToMpdTagWithLen(MpdTag * tag, int itemType, char * value, int len); + void printMpdTag(FILE * fp, MpdTag * tag); MpdTag * mpdTagDup(MpdTag * tag); @@ -59,4 +81,7 @@ void validateUtf8Tag(MpdTag * tag); int mpdTagsAreEqual(MpdTag * tag1, MpdTag * tag2); +/* *last shoudl be initialzed to -1 before calling this function */ +char * getNextItemFromMpdTag(MpdTag * tag, int itemType, int * last); + #endif |