summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--TODO23
-rw-r--r--src/decode.c122
-rw-r--r--src/decode.h9
-rw-r--r--src/inputPlugins/mp3_plugin.c6
-rw-r--r--src/inputPlugins/ogg_plugin.c23
-rw-r--r--src/outputBuffer.c31
-rw-r--r--src/outputBuffer.h11
-rw-r--r--src/pcm_utils.c2
-rw-r--r--src/player.c9
-rw-r--r--src/player.h1
-rw-r--r--src/playerData.c10
-rw-r--r--src/song.c5
-rw-r--r--src/tag.c6
-rw-r--r--src/tag.h1
14 files changed, 175 insertions, 84 deletions
diff --git a/TODO b/TODO
index 0ea67b84d..387dce3a2 100644
--- a/TODO
+++ b/TODO
@@ -1,9 +1,20 @@
-1) Parse icymetadata
-
-2) Put a new metadata entry for icyName for Song's
-
-3) handle changes in audioFormat in a single stream/file,
- esp need for vorbis streams
+1) Construct a small metadata buffer
+ a) MetadataChunk struct
+ 1) functions for converting between block and MpdTag
+ 2) char * buffer
+ 3) positions ints for name, title, artist, album
+ b) MetadataChunk buffer in OutputBuffer
+ 1) deal with incrementing and finding a free buffer Chunk
+ the decoder element
+ 2) corresponding metachunk # for each audio chunk
+ c) player proccess
+ 1) if not metachunk be sure to clear the current metadata
+ in playerControl
+ 2) if it is, if WRITE, then write do pc->metadataChunk
+
+2) Parse icymetadata
+
+3) Put a new metadata entry for icyName for Song's
4) put some sort of error reporting for streaming/inputStream!
diff --git a/src/decode.c b/src/decode.c
index decc313ae..99a4bd784 100644
--- a/src/decode.c
+++ b/src/decode.c
@@ -112,17 +112,6 @@ int calculateCrossFadeChunks(PlayerControl * pc, AudioFormat * af) {
quitDecode(pc,dc); \
return; \
} \
- if(pc->metadataState == PLAYER_METADATA_STATE_WRITE && \
- dc->metadataSet) \
- { \
- memcpy(pc->metadata, dc->metadata, \
- DECODE_METADATA_LENGTH); \
- pc->metadata[DECODE_METADATA_LENGTH-1] = '\0'; \
- pc->title = dc->title; \
- pc->artist = dc->artist; \
- pc->album = dc->album; \
- } \
- pc->metadataState = PLAYER_METADATA_STATE_READ; \
pc->totalTime = dc->totalTime; \
pc->sampleRate = dc->audioFormat.sampleRate; \
pc->bits = dc->audioFormat.bits; \
@@ -271,11 +260,12 @@ void decodeStart(PlayerControl * pc, OutputBuffer * cb, DecoderControl * dc) {
return;
}
- dc->metadataSet = 0;
- memset(dc->metadata, 0, DECODE_METADATA_LENGTH);
- dc->title = -1;
- dc->album = -1;
- dc->artist = -1;
+ cb->metadataSet = 0;
+ memset(cb->metadata, 0, DECODE_METADATA_LENGTH);
+ cb->name = -1;
+ cb->title = -1;
+ cb->album = -1;
+ cb->artist = -1;
strncpy(dc->utf8url, pc->utf8url, MAXPATHLEN);
dc->utf8url[MAXPATHLEN] = '\0';
@@ -302,15 +292,17 @@ void decodeStart(PlayerControl * pc, OutputBuffer * cb, DecoderControl * dc) {
return;
}
- if(inStream.metaTitle) {
- strncpy(dc->metadata, inStream.metaTitle,
+ /*if(inStream.metaTitle) {
+ strncpy(cb->metadata, inStream.metaTitle,
DECODE_METADATA_LENGTH-1);
- dc->title = 0;
- dc->metadataSet = 1;
- }
+ cb->name = 0;
+ cb->metaChunk = cb->end;
+ cb->metadataSet = 1;
+ }*/
ret = DECODE_ERROR_UNKTYPE;
if(isRemoteUrl(dc->utf8url)) {
+ cb->acceptMetadata = 1;
plugin = getInputPluginFromMimeType(inStream.mime);
if(plugin == NULL) {
plugin = getInputPluginFromSuffix(
@@ -328,6 +320,7 @@ void decodeStart(PlayerControl * pc, OutputBuffer * cb, DecoderControl * dc) {
}
}
else {
+ cb->acceptMetadata = 0;
plugin = getInputPluginFromSuffix(getSuffix(dc->utf8url));
if(plugin && (plugin->streamTypes && INPUT_PLUGIN_STREAM_FILE))
{
@@ -399,6 +392,55 @@ int decoderInit(PlayerControl * pc, OutputBuffer * cb, DecoderControl * dc) {
return 0;
}
+#define copyMetadata() { \
+ memcpy(pc->metadata, metadata, DECODE_METADATA_LENGTH); \
+ pc->name = name; \
+ pc->title = title; \
+ pc->artist = artist; \
+ pc->album = album; \
+ gotMetadata = 0; \
+ pc->metadataState = PLAYER_METADATA_STATE_READ; \
+ kill(getppid(), SIGUSR1); \
+}
+
+/* do some fancier shit here, like put metadata in a linked list metadata
+buffer, and assign it to current and whether current is written */
+#define handleMetadata() { \
+ if(cb->metadataSet) {\
+ gotMetadata = 1;\
+ memcpy(metadata, cb->metadata, DECODE_METADATA_LENGTH); \
+ artist = cb->artist; \
+ name = cb->name; \
+ title = cb->title; \
+ album = cb->album; \
+ metaChunk = cb->metaChunk; \
+ cb->metadataSet = 0; \
+ } \
+ if(gotMetadata) { \
+ int end = cb->end; \
+ if(end > cb->begin && (metaChunk < cb->begin || \
+ metaChunk > end)) \
+ { \
+ gotMetadata = 0; \
+ } \
+ else if(cb->begin > end && (metaChunk > cb->begin && \
+ metaChunk < end)) \
+ { \
+ gotMetadata = 0; \
+ } \
+ else if(pc->metadataState == PLAYER_METADATA_STATE_WRITE) { \
+ if(end > metaChunk && metaChunk <= cb->begin ) { \
+ copyMetadata(); \
+ } \
+ else if(metaChunk >= end && (cb->begin >= metaChunk || \
+ cb->begin < end)) \
+ { \
+ copyMetadata(); \
+ } \
+ } \
+ } \
+}
+
void decodeParent(PlayerControl * pc, DecoderControl * dc, OutputBuffer * cb) {
int pause = 0;
int quit = 0;
@@ -411,6 +453,13 @@ void decodeParent(PlayerControl * pc, DecoderControl * dc, OutputBuffer * cb) {
int decodeWaitedOn = 0;
char silence[CHUNK_SIZE];
double sizeToTime = 0.0;
+ char metadata[DECODE_METADATA_LENGTH];
+ mpd_sint16 name = -1;
+ mpd_sint16 title = -1;
+ mpd_sint16 artist = -1;
+ mpd_sint16 album = -1;
+ mpd_sint16 metaChunk = -1;
+ int gotMetadata = 0;
memset(silence,0,CHUNK_SIZE);
@@ -424,12 +473,14 @@ void decodeParent(PlayerControl * pc, DecoderControl * dc, OutputBuffer * cb) {
dc->state!=DECODE_STATE_STOP)
{
processDecodeInput();
+ handleMetadata();
if(quit) return;
my_usleep(10000);
}
while(!quit) {
processDecodeInput();
+ handleMetadata();
handleDecodeStart();
if(dc->state==DECODE_STATE_STOP &&
pc->queueState==PLAYER_QUEUE_FULL &&
@@ -592,6 +643,7 @@ void decode() {
cb->begin = 0;
cb->end = 0;
cb->wrap = 0;
+ cb->metadataSet = 0;
pc = &(getPlayerData()->playerControl);
dc = &(getPlayerData()->decoderControl);
dc->error = 0;
@@ -606,31 +658,3 @@ void decode() {
decodeParent(pc, dc, cb);
}
-
-/* this is stuff for inputPlugins to use! */
-#define copyStringToMetadata(string, element) { \
- if(string && (slen = strlen(string)) && \
- pos < DECODE_METADATA_LENGTH-1) \
- { \
- strncpy(dc->metadata+pos, string, \
- DECODE_METADATA_LENGTH-1-pos); \
- element = pos; \
- pos += slen+1; \
- } \
-}
-
-void copyMpdTagToDecoderControlMetadata(DecoderControl * dc, MpdTag * tag) {
- int pos = 0;
- int slen;
-
- if(dc->metadataSet) return;
- if(!tag) return;
-
- memset(dc->metadata, 0, DECODE_METADATA_LENGTH);
-
- copyStringToMetadata(tag->title, dc->title);
- copyStringToMetadata(tag->artist, dc->artist);
- copyStringToMetadata(tag->album, dc->album);
-
- dc->metadataSet = 1;
-}
diff --git a/src/decode.h b/src/decode.h
index a0c4332ba..4c2043b53 100644
--- a/src/decode.h
+++ b/src/decode.h
@@ -46,7 +46,7 @@
#define DECODE_SUFFIX_MP4 5
#define DECODE_SUFFIX_WAVE 6
-#define DECODE_METADATA_LENGTH 4096
+#define DECODE_METADATA_LENGTH 8192
typedef struct _DecoderControl {
volatile mpd_sint8 state;
@@ -61,18 +61,11 @@ typedef struct _DecoderControl {
AudioFormat audioFormat;
char utf8url[MAXPATHLEN+1];
volatile float totalTime;
- volatile mpd_sint8 metadataSet;
- char metadata[DECODE_METADATA_LENGTH];
- volatile mpd_sint16 title;
- volatile mpd_sint16 artist;
- volatile mpd_sint16 album;
} DecoderControl;
void decodeSigHandler(int sig);
void decode();
-void copyMpdTagToDecoderControlMetadata(DecoderControl * dc, MpdTag * tag);
-
#endif
/* vim:set shiftwidth=4 tabstop=8 expandtab: */
diff --git a/src/inputPlugins/mp3_plugin.c b/src/inputPlugins/mp3_plugin.c
index a73276c74..f2ad57500 100644
--- a/src/inputPlugins/mp3_plugin.c
+++ b/src/inputPlugins/mp3_plugin.c
@@ -644,7 +644,11 @@ int mp3_decode(OutputBuffer * cb, DecoderControl * dc, InputStream * inStream) {
dc->totalTime = data.totalTime;
if(tag) {
- copyMpdTagToDecoderControlMetadata(dc, tag);
+ if(inStream->metaTitle) {
+ if(tag->name) free(tag->name);
+ tag->name = strdup(inStream->metaTitle);
+ }
+ copyMpdTagToOutputBuffer(cb, tag);
freeMpdTag(tag);
}
diff --git a/src/inputPlugins/ogg_plugin.c b/src/inputPlugins/ogg_plugin.c
index 9a27ad712..a79c0d876 100644
--- a/src/inputPlugins/ogg_plugin.c
+++ b/src/inputPlugins/ogg_plugin.c
@@ -200,21 +200,26 @@ MpdTag * oggCommentsParse(char ** comments) {
return ret;
}
-void putOggCommentsIntoDecoderControlMetadata(DecoderControl * dc,
- char ** comments)
+void putOggCommentsIntoOutputBuffer(OutputBuffer * cb, char * streamName,
+ char ** comments)
{
MpdTag * tag;
tag = oggCommentsParse(comments);
if(!tag) return;
- copyMpdTagToDecoderControlMetadata(dc, tag);
-
/*if(tag->artist) printf("Artist: %s\n", tag->artist);
if(tag->album) printf("Album: %s\n", tag->album);
if(tag->track) printf("Track: %s\n", tag->track);
if(tag->title) printf("Title: %s\n", tag->title);*/
+ if(streamName) {
+ if(tag->name) free(tag->name);
+ tag->name = strdup(streamName);
+ }
+
+ copyMpdTagToOutputBuffer(cb, tag);
+
freeMpdTag(tag);
}
@@ -280,10 +285,14 @@ int ogg_decode(OutputBuffer * cb, DecoderControl * dc, InputStream * inStream)
vorbis_info *vi=ov_info(&vf,-1);
dc->audioFormat.channels = vi->channels;
dc->audioFormat.sampleRate = vi->rate;
- getOutputAudioFormat(&(dc->audioFormat),&(cb->audioFormat));
+ if(dc->state == DECODE_STATE_START) {
+ getOutputAudioFormat(&(dc->audioFormat),
+ &(cb->audioFormat));
+ dc->state = DECODE_STATE_DECODE;
+ }
comments = ov_comment(&vf, -1)->user_comments;
- putOggCommentsIntoDecoderControlMetadata(dc, comments);
- dc->state = DECODE_STATE_DECODE;
+ putOggCommentsIntoOutputBuffer(cb, inStream->metaTitle,
+ comments);
replayGainScale = ogg_getReplayGainScale(comments);
}
diff --git a/src/outputBuffer.c b/src/outputBuffer.c
index 41932faa5..194e3af8a 100644
--- a/src/outputBuffer.c
+++ b/src/outputBuffer.c
@@ -117,4 +117,33 @@ int sendDataToOutputBuffer(OutputBuffer * cb, InputStream * inStream,
return 0;
}
-/* vim:set shiftwidth=4 tabstop=8 expandtab: */
+
+/* this is stuff for inputPlugins to use! */
+#define copyStringToMetadata(string, element) { \
+ if(string && (slen = strlen(string)) && \
+ pos < DECODE_METADATA_LENGTH-1) \
+ { \
+ strncpy(cb->metadata+pos, string, \
+ DECODE_METADATA_LENGTH-1-pos); \
+ element = pos; \
+ pos += slen+1; \
+ } \
+}
+
+void copyMpdTagToOutputBuffer(OutputBuffer * cb, MpdTag * tag) {
+ int pos = 0;
+ int slen;
+
+ if(!cb->acceptMetadata) return;
+ if(!tag) return;
+
+ memset(cb->metadata, 0, DECODE_METADATA_LENGTH);
+
+ copyStringToMetadata(tag->name, cb->name);
+ copyStringToMetadata(tag->artist, cb->artist);
+ copyStringToMetadata(tag->title, cb->title);
+ copyStringToMetadata(tag->album, cb->album);
+
+ cb->metaChunk = cb->end;
+ cb->metadataSet = 1;
+}
diff --git a/src/outputBuffer.h b/src/outputBuffer.h
index 90cc6906b..71136b363 100644
--- a/src/outputBuffer.h
+++ b/src/outputBuffer.h
@@ -37,6 +37,14 @@ typedef struct _OutputBuffer {
mpd_sint16 volatile next;
mpd_sint8 volatile wrap;
AudioFormat audioFormat;
+ volatile mpd_sint8 metadataSet;
+ char metadata[DECODE_METADATA_LENGTH];
+ volatile mpd_sint16 title;
+ volatile mpd_sint16 artist;
+ volatile mpd_sint16 album;
+ volatile mpd_sint16 name;
+ volatile mpd_uint16 metaChunk;
+ volatile mpd_sint8 acceptMetadata;
} OutputBuffer;
void clearOutputBuffer(OutputBuffer * cb);
@@ -49,5 +57,6 @@ int sendDataToOutputBuffer(OutputBuffer * cb, InputStream * inStream,
DecoderControl * dc, int seekable, char * data, long datalen,
float time, mpd_uint16 bitRate);
+void copyMpdTagToOutputBuffer(OutputBuffer * cb, MpdTag * tag);
+
#endif
-/* vim:set shiftwidth=4 tabstop=8 expandtab: */
diff --git a/src/pcm_utils.c b/src/pcm_utils.c
index e0ebf2ecb..e9beeeead 100644
--- a/src/pcm_utils.c
+++ b/src/pcm_utils.c
@@ -281,5 +281,3 @@ size_t pcm_sizeOfOutputBufferForAudioFormatConversion(AudioFormat * inFormat,
return outSize;
}
-
-/* vim:set shiftwidth=8 tabstop=8 expandtab: */
diff --git a/src/player.c b/src/player.c
index cda88fff4..587a5501d 100644
--- a/src/player.c
+++ b/src/player.c
@@ -474,10 +474,12 @@ void playerCycleLogFiles() {
/* this actually creates a dupe of the current metadata */
Song * playerCurrentDecodeSong() {
static Song * song = NULL;
+ static char * prev = NULL;
PlayerControl * pc = &(getPlayerData()->playerControl);
if(pc->metadataState == PLAYER_METADATA_STATE_READ &&
- (!song || strcmp(song->utf8url, pc->currentUrl)))
+ ((!song || strcmp(song->utf8url, pc->currentUrl))
+ || (!prev || strcmp(prev,pc->metadata))))
{
if(song) freeJustSong(song);
song = newNullSong();
@@ -486,6 +488,7 @@ Song * playerCurrentDecodeSong() {
song->utf8url = strdup(pc->currentUrl);
if(pc->title >= 0) {
song->tag->title = strdup(pc->title + pc->metadata);
+ /*printf("player title: %s\n", song->tag->title);*/
}
if(pc->artist >= 0) {
song->tag->artist = strdup(pc->artist + pc->metadata);
@@ -494,11 +497,11 @@ Song * playerCurrentDecodeSong() {
song->tag->album = strdup(pc->album + pc->metadata);
}
validateUtf8Tag(song->tag);
+ if(prev) free(prev);
+ prev = strdup(pc->metadata);
resetPlayerMetadata();
return song;
}
return NULL;
}
-
-/* vim:set shiftwidth=4 tabstop=8 expandtab: */
diff --git a/src/player.h b/src/player.h
index 11f408fdc..5e8d90e97 100644
--- a/src/player.h
+++ b/src/player.h
@@ -85,6 +85,7 @@ typedef struct _PlayerControl {
volatile mpd_sint8 cycleLogFiles;
volatile mpd_sint8 metadataState;
char metadata[DECODE_METADATA_LENGTH];
+ volatile mpd_sint16 name;
volatile mpd_sint16 title;
volatile mpd_sint16 artist;
volatile mpd_sint16 album;
diff --git a/src/playerData.c b/src/playerData.c
index 2dbdace0d..4950a2c7e 100644
--- a/src/playerData.c
+++ b/src/playerData.c
@@ -117,6 +117,7 @@ void initPlayerData() {
playerData_pd->playerControl.softwareVolume = 1000;
playerData_pd->playerControl.totalPlayTime = 0;
playerData_pd->playerControl.decode_pid = 0;
+ playerData_pd->playerControl.name = -1;
playerData_pd->playerControl.title = -1;
playerData_pd->playerControl.artist = -1;
playerData_pd->playerControl.album = -1;
@@ -129,12 +130,9 @@ void initPlayerData() {
playerData_pd->decoderControl.seek = 0;
playerData_pd->decoderControl.error = DECODE_ERROR_NOERROR;
memset(playerData_pd->decoderControl.utf8url, 0, MAXPATHLEN+1);
- memset(playerData_pd->decoderControl.metadata, 0,
- DECODE_METADATA_LENGTH);
- playerData_pd->decoderControl.title = -1;
- playerData_pd->decoderControl.artist = -1;
- playerData_pd->decoderControl.album = -1;
- playerData_pd->decoderControl.metadataSet = 0;
+
+ memset(playerData_pd->buffer.metadata, 0, DECODE_METADATA_LENGTH);
+ playerData_pd->buffer.metadataSet = 0;
}
PlayerData * getPlayerData() {
diff --git a/src/song.c b/src/song.c
index ed88f1f60..41e3d4b66 100644
--- a/src/song.c
+++ b/src/song.c
@@ -34,6 +34,7 @@
#define SONG_ALBUM "Album: "
#define SONG_TRACK "Track: "
#define SONG_TITLE "Title: "
+#define SONG_NAME "Name: "
#define SONG_TIME "Time: "
#define SONG_MTIME "mtime: "
@@ -235,6 +236,10 @@ void readSongInfoIntoList(FILE * fp, SongList * list) {
if(!song->tag) song->tag = newMpdTag();
song->tag->title = strdup(&(buffer[strlen(SONG_TITLE)]));
}
+ else if(0==strncmp(SONG_NAME,buffer,strlen(SONG_NAME))) {
+ if(!song->tag) song->tag = newMpdTag();
+ song->tag->name = strdup(&(buffer[strlen(SONG_NAME)]));
+ }
else if(0==strncmp(SONG_TIME,buffer,strlen(SONG_TIME))) {
if(!song->tag) song->tag = newMpdTag();
song->tag->time = atoi(&(buffer[strlen(SONG_TIME)]));
diff --git a/src/tag.c b/src/tag.c
index c6bd1ffa8..729ccb0f6 100644
--- a/src/tag.c
+++ b/src/tag.c
@@ -43,6 +43,7 @@ void printMpdTag(FILE * fp, MpdTag * tag) {
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);
if(tag->time>=0) myfprintf(fp,"Time: %i\n",tag->time);
}
@@ -62,6 +63,7 @@ void validateUtf8Tag(MpdTag * tag) {
fixUtf8(tag->album);
fixUtf8(tag->track);
fixUtf8(tag->title);
+ fixUtf8(tag->name);
}
#ifdef HAVE_ID3TAG
@@ -158,6 +160,7 @@ MpdTag * newMpdTag() {
ret->artist = NULL;
ret->title = NULL;
ret->track = NULL;
+ ret->name = NULL;
ret->time = -1;
return ret;
}
@@ -166,6 +169,7 @@ 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->title);
if(tag->track) free(tag->track);
}
@@ -183,6 +187,7 @@ MpdTag * mpdTagDup(MpdTag * tag) {
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;
}
@@ -208,6 +213,7 @@ int mpdTagsAreEqual(MpdTag * tag1, MpdTag * tag2) {
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;
return 1;
}
diff --git a/src/tag.h b/src/tag.h
index 225b3189e..841791ae0 100644
--- a/src/tag.h
+++ b/src/tag.h
@@ -35,6 +35,7 @@ typedef struct _MpdTag {
char * album;
char * track;
char * title;
+ char * name;
int time;
} MpdTag;