aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--src/audioOutputs/audioOutput_shout.c20
-rw-r--r--src/decode.c4
-rw-r--r--src/directory.c59
-rw-r--r--src/inputPlugins/flac_plugin.c122
-rw-r--r--src/inputPlugins/mod_plugin.c4
-rw-r--r--src/inputPlugins/mp3_plugin.c20
-rw-r--r--src/inputPlugins/mp4_plugin.c42
-rw-r--r--src/inputPlugins/ogg_plugin.c28
-rw-r--r--src/metadataChunk.c28
-rw-r--r--src/song.c43
-rw-r--r--src/tag.c158
-rw-r--r--src/tag.h35
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);
diff --git a/src/tag.c b/src/tag.c
index b5c71c500..8b365f85f 100644
--- a/src/tag.c
+++ b/src/tag.c
@@ -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;
}
diff --git a/src/tag.h b/src/tag.h
index 06129b767..7905e92a8 100644
--- a/src/tag.h
+++ b/src/tag.h
@@ -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