aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/Makefile.am4
-rw-r--r--src/decode.c88
-rw-r--r--src/decode.h2
-rw-r--r--src/metadataChunk.c46
-rw-r--r--src/metadataChunk.h22
-rw-r--r--src/outputBuffer.c48
-rw-r--r--src/outputBuffer.h12
-rw-r--r--src/player.c26
-rw-r--r--src/player.h7
-rw-r--r--src/playerData.c15
-rw-r--r--src/playlist.c4
-rw-r--r--src/tag.c2
-rw-r--r--src/tag.h1
13 files changed, 143 insertions, 134 deletions
diff --git a/src/Makefile.am b/src/Makefile.am
index de55f202..e602248c 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -13,7 +13,7 @@ mpd_headers = buffer2array.h interface.h command.h playlist.h ls.h \
charConv.h permission.h mpd_types.h pcm_utils.h \
signal_check.h utf8.h inputStream.h \
outputBuffer.h replayGain.h inputStream_file.h inputStream_http.h \
- inputPlugin.h
+ inputPlugin.h metadataChunk.h
mpd_SOURCES = main.c buffer2array.c interface.c command.c playlist.c ls.c \
song.c list.c directory.c tables.c utils.c path.c \
tag.c player.c listen.c conf.c volume.c \
@@ -21,7 +21,7 @@ mpd_SOURCES = main.c buffer2array.c interface.c command.c playlist.c ls.c \
charConv.c permission.c pcm_utils.c \
signal_check.c utf8.c inputStream.c outputBuffer.c \
replayGain.c inputStream_file.c inputStream_http.c inputPlugin.c \
- $(mpd_headers) $(mpd_inputPlugins)
+ metadataChunk.c $(mpd_headers) $(mpd_inputPlugins)
mpd_CFLAGS = $(MPD_CFLAGS)
mpd_LDADD = $(MPD_LIBS) $(ID3_LIB) $(MAD_LIB) $(MP4FF_LIB)
diff --git a/src/decode.c b/src/decode.c
index 99a4bd78..8053f44f 100644
--- a/src/decode.c
+++ b/src/decode.c
@@ -260,12 +260,7 @@ void decodeStart(PlayerControl * pc, OutputBuffer * cb, DecoderControl * dc) {
return;
}
- cb->metadataSet = 0;
- memset(cb->metadata, 0, DECODE_METADATA_LENGTH);
- cb->name = -1;
- cb->title = -1;
- cb->album = -1;
- cb->artist = -1;
+ copyMpdTagToOutputBuffer(cb, NULL);
strncpy(dc->utf8url, pc->utf8url, MAXPATHLEN);
dc->utf8url[MAXPATHLEN] = '\0';
@@ -292,13 +287,14 @@ void decodeStart(PlayerControl * pc, OutputBuffer * cb, DecoderControl * dc) {
return;
}
- /*if(inStream.metaTitle) {
- strncpy(cb->metadata, inStream.metaTitle,
- DECODE_METADATA_LENGTH-1);
- cb->name = 0;
- cb->metaChunk = cb->end;
- cb->metadataSet = 1;
- }*/
+ if(inStream.metaTitle) {
+ MpdTag * tag = newMpdTag();
+ tag->name = strdup(inStream.metaTitle);
+ copyMpdTagToOutputBuffer(cb, tag);
+ freeMpdTag(tag);
+ }
+
+ /* reset Metadata in OutputBuffer */
ret = DECODE_ERROR_UNKTYPE;
if(isRemoteUrl(dc->utf8url)) {
@@ -403,42 +399,25 @@ int decoderInit(PlayerControl * pc, OutputBuffer * cb, DecoderControl * dc) {
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 handleMetadata(OutputBuffer * cb, PlayerControl * pc) {
+ static int previous = -1;
+
+ if(cb->begin!=cb->end || cb->wrap) {
+ int meta = cb->metaChunk[cb->begin];
+ if( meta != previous ) {
+ if( meta >= 0 && pc->metadataState ==
+ PLAYER_METADATA_STATE_WRITE)
+ {
+ printf("METADATA!, copying it.\n");
+ memcpy(&(pc->metadataChunk),
+ cb->metadataChunks+meta,
+ sizeof(MetadataChunk));
+ pc->metadataState =
+ PLAYER_METADATA_STATE_READ;
+ previous = meta;
+ }
+ }
+ }
}
void decodeParent(PlayerControl * pc, DecoderControl * dc, OutputBuffer * cb) {
@@ -453,13 +432,6 @@ 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);
@@ -473,15 +445,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();
+ handleMetadata(cb, pc);
if(dc->state==DECODE_STATE_STOP &&
pc->queueState==PLAYER_QUEUE_FULL &&
pc->queueLockState==PLAYER_QUEUE_UNLOCKED)
@@ -643,7 +614,6 @@ void decode() {
cb->begin = 0;
cb->end = 0;
cb->wrap = 0;
- cb->metadataSet = 0;
pc = &(getPlayerData()->playerControl);
dc = &(getPlayerData()->decoderControl);
dc->error = 0;
diff --git a/src/decode.h b/src/decode.h
index 4c2043b5..874e8230 100644
--- a/src/decode.h
+++ b/src/decode.h
@@ -46,8 +46,6 @@
#define DECODE_SUFFIX_MP4 5
#define DECODE_SUFFIX_WAVE 6
-#define DECODE_METADATA_LENGTH 8192
-
typedef struct _DecoderControl {
volatile mpd_sint8 state;
volatile mpd_sint8 stop;
diff --git a/src/metadataChunk.c b/src/metadataChunk.c
new file mode 100644
index 00000000..1deab3d9
--- /dev/null
+++ b/src/metadataChunk.c
@@ -0,0 +1,46 @@
+#include "metadataChunk.h"
+
+#include <string.h>
+
+void initMetadataChunk(MetadataChunk * chunk) {
+ memset(chunk, 0, sizeof(MetadataChunk));
+
+ chunk->name = -1;
+ chunk->artist = -1;
+ chunk->album = -1;
+ chunk->title = -1;
+}
+
+MpdTag * metadataChunkToMpdTagDup(MetadataChunk * chunk) {
+ MpdTag * ret = newMpdTag();
+
+ if(chunk->name >= 0) ret->name = strdup(chunk->buffer+chunk->name);
+ if(chunk->artist >= 0) ret->artist = strdup(chunk->buffer+chunk->artist);
+ if(chunk->album >= 0) ret->album = strdup(chunk->buffer+chunk->album);
+ if(chunk->title >= 0) ret->title = strdup(chunk->buffer+chunk->title);
+
+ return ret;
+}
+
+#define copyStringToChunk(string, element) { \
+ if(string && (slen = strlen(string)) && \
+ pos < METADATA_BUFFER_LENGTH-1) \
+ { \
+ strncpy(chunk->buffer+pos, string, \
+ METADATA_BUFFER_LENGTH-1-pos); \
+ element = pos; \
+ pos += slen+1; \
+ } \
+}
+
+void copyMpdTagToMetadataChunk(MpdTag * tag, MetadataChunk * chunk) {
+ int pos = 0;
+ int slen;
+
+ initMetadataChunk(chunk);
+
+ copyStringToChunk(tag->name, chunk->name);
+ copyStringToChunk(tag->title, chunk->title);
+ copyStringToChunk(tag->artist, chunk->artist);
+ copyStringToChunk(tag->album, chunk->album);
+}
diff --git a/src/metadataChunk.h b/src/metadataChunk.h
new file mode 100644
index 00000000..05e1c907
--- /dev/null
+++ b/src/metadataChunk.h
@@ -0,0 +1,22 @@
+#ifndef METADATA_CHUNK_H
+#define METADATA_CHUNK_H
+
+#define METADATA_BUFFER_LENGTH 1024
+
+#include "tag.h"
+
+typedef struct _MetadataChunk {
+ int name;
+ int title;
+ int artist;
+ int album;
+ char buffer[METADATA_BUFFER_LENGTH];
+} MetadataChunk;
+
+void initMetadataChunk(MetadataChunk *);
+
+MpdTag * metadataChunkToMpdTagDup(MetadataChunk * chunk);
+
+void copyMpdTagToMetadataChunk(MpdTag * tag, MetadataChunk * chunk);
+
+#endif
diff --git a/src/outputBuffer.c b/src/outputBuffer.c
index 194e3af8..d0a98b69 100644
--- a/src/outputBuffer.c
+++ b/src/outputBuffer.c
@@ -26,6 +26,9 @@
static mpd_sint16 currentChunk = -1;
+static mpd_sint8 currentMetaChunk = -1;
+static mpd_sint8 sendMetaChunk = 0;
+
void clearOutputBuffer(OutputBuffer * cb) {
currentChunk = -1;
cb->end = cb->begin;
@@ -95,6 +98,13 @@ int sendDataToOutputBuffer(OutputBuffer * cb, InputStream * inStream,
currentChunk = cb->end;
cb->chunkSize[currentChunk] = 0;
+
+ if(sendMetaChunk) {
+ cb->metaChunk[currentChunk] = currentMetaChunk;
+ }
+ else cb->metaChunk[currentChunk] = -1;
+ cb->bitRate[currentChunk] = bitRate;
+ cb->times[currentChunk] = time;
}
chunkLeft = CHUNK_SIZE-cb->chunkSize[currentChunk];
@@ -104,9 +114,6 @@ int sendDataToOutputBuffer(OutputBuffer * cb, InputStream * inStream,
cb->chunkSize[currentChunk],
data, dataToSend);
cb->chunkSize[currentChunk]+= dataToSend;
- cb->bitRate[currentChunk] = bitRate;
- cb->times[currentChunk] = time;
-
datalen-= dataToSend;
data+= dataToSend;
@@ -118,32 +125,19 @@ int sendDataToOutputBuffer(OutputBuffer * cb, InputStream * inStream,
return 0;
}
-/* 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;
+ printf("copyMpdTagToOB called\n");
+
+ if(!cb->acceptMetadata || !tag) {
+ sendMetaChunk = 0;
+ return;
+ }
- if(!cb->acceptMetadata) return;
- if(!tag) return;
+ sendMetaChunk = 1;
+ currentMetaChunk++;
+ if(currentMetaChunk >= BUFFERED_METACHUNKS) currentMetaChunk = 0;
- 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);
+ printMpdTag(stdout, tag);
- cb->metaChunk = cb->end;
- cb->metadataSet = 1;
+ copyMpdTagToMetadataChunk(tag, &(cb->metadataChunks[currentMetaChunk]));
}
diff --git a/src/outputBuffer.h b/src/outputBuffer.h
index 71136b36..a7e5bb17 100644
--- a/src/outputBuffer.h
+++ b/src/outputBuffer.h
@@ -23,10 +23,13 @@
#include "decode.h"
#include "audio.h"
#include "inputStream.h"
+#include "metadataChunk.h"
#define OUTPUT_BUFFER_DC_STOP -1
#define OUTPUT_BUFFER_DC_SEEK -2
+#define BUFFERED_METACHUNKS 25
+
typedef struct _OutputBuffer {
char * volatile chunks;
mpd_uint16 * volatile chunkSize;
@@ -37,13 +40,8 @@ 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;
+ MetadataChunk metadataChunks[BUFFERED_METACHUNKS];
+ mpd_sint8 * volatile metaChunk;
volatile mpd_sint8 acceptMetadata;
} OutputBuffer;
diff --git a/src/player.c b/src/player.c
index 587a5501..e6da9aeb 100644
--- a/src/player.c
+++ b/src/player.c
@@ -55,9 +55,6 @@ static void resetPlayerMetadata() {
if(pc->metadataState == PLAYER_METADATA_STATE_READ) {
pc->metadataState = PLAYER_METADATA_STATE_WRITE;
- pc->title = -1;
- pc->artist = -1;
- pc->album = -1;
}
}
@@ -75,8 +72,6 @@ void resetPlayer() {
getPlayerData()->playerControl.seek = 0;
getPlayerData()->playerControl.metadataState =
PLAYER_METADATA_STATE_WRITE;
- getPlayerData()->playerControl.title = -1;
- /* kill decode process if it got left running */
pid = getPlayerData()->playerControl.decode_pid;
if(pid>0) kill(pid,SIGTERM);
getPlayerData()->playerControl.decode_pid = 0;
@@ -474,31 +469,24 @@ void playerCycleLogFiles() {
/* this actually creates a dupe of the current metadata */
Song * playerCurrentDecodeSong() {
static Song * song = NULL;
- static char * prev = NULL;
+ static MetadataChunk * prev = NULL;
PlayerControl * pc = &(getPlayerData()->playerControl);
if(pc->metadataState == PLAYER_METADATA_STATE_READ &&
((!song || strcmp(song->utf8url, pc->currentUrl))
- || (!prev || strcmp(prev,pc->metadata))))
+ || (!prev || memcmp(prev, &(pc->metadataChunk),
+ sizeof(MetadataChunk)))))
{
+ printf("metadata in the PLAYER!\n");
if(song) freeJustSong(song);
song = newNullSong();
- song->tag = newMpdTag();
if(song->utf8url) free(song->utf8url);
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);
- }
- if(pc->album >= 0) {
- song->tag->album = strdup(pc->album + pc->metadata);
- }
+ song->tag = metadataChunkToMpdTagDup(&(pc->metadataChunk));
validateUtf8Tag(song->tag);
if(prev) free(prev);
- prev = strdup(pc->metadata);
+ prev = malloc(sizeof(MetadataChunk));
+ memcpy(prev, &(pc->metadataChunk), sizeof(MetadataChunk));
resetPlayerMetadata();
return song;
}
diff --git a/src/player.h b/src/player.h
index 5e8d90e9..6453bd37 100644
--- a/src/player.h
+++ b/src/player.h
@@ -24,6 +24,7 @@
#include "decode.h"
#include "mpd_types.h"
#include "song.h"
+#include "metadataChunk.h"
#include <stdio.h>
#include <sys/param.h>
@@ -84,11 +85,7 @@ typedef struct _PlayerControl {
volatile int decode_pid;
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;
+ MetadataChunk metadataChunk;
} PlayerControl;
void clearPlayerPid();
diff --git a/src/playerData.c b/src/playerData.c
index 4950a2c7..5804f306 100644
--- a/src/playerData.c
+++ b/src/playerData.c
@@ -73,6 +73,7 @@ void initPlayerData() {
allocationSize+= buffered_chunks*sizeof(float); /*for times*/
allocationSize+= buffered_chunks*sizeof(mpd_sint16); /*for chunkSize*/
allocationSize+= buffered_chunks*sizeof(mpd_sint16); /*for bitRate*/
+ allocationSize+= buffered_chunks*sizeof(mpd_sint8); /*for metaChunk*/
allocationSize+= sizeof(PlayerData); /*for playerData struct*/
if((shmid = shmget(IPC_PRIVATE,allocationSize,IPC_CREAT|0600))<0) {
@@ -95,8 +96,10 @@ void initPlayerData() {
buffered_chunks*CHUNK_SIZE);
buffer->bitRate = (mpd_uint16 *)(((char *)buffer->chunkSize)+
buffered_chunks*sizeof(mpd_sint16));
- buffer->times = (float *)(((char *)buffer->bitRate)+
+ buffer->metaChunk = (mpd_sint8 *)(((char *)buffer->bitRate)+
buffered_chunks*sizeof(mpd_sint16));
+ buffer->times = (float *)(((char *)buffer->metaChunk)+
+ buffered_chunks*sizeof(mpd_sint8));
playerData_pd->playerControl.stop = 0;
playerData_pd->playerControl.pause = 0;
@@ -111,16 +114,10 @@ void initPlayerData() {
memset(playerData_pd->playerControl.utf8url, 0, MAXPATHLEN+1);
memset(playerData_pd->playerControl.erroredUrl, 0, MAXPATHLEN+1);
memset(playerData_pd->playerControl.currentUrl, 0, MAXPATHLEN+1);
- memset(playerData_pd->playerControl.metadata, 0,
- DECODE_METADATA_LENGTH);
playerData_pd->playerControl.crossFade = crossfade;
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;
playerData_pd->playerControl.metadataState =
PLAYER_METADATA_STATE_WRITE;
@@ -130,9 +127,6 @@ 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->buffer.metadata, 0, DECODE_METADATA_LENGTH);
- playerData_pd->buffer.metadataSet = 0;
}
PlayerData * getPlayerData() {
@@ -142,4 +136,3 @@ PlayerData * getPlayerData() {
void freePlayerData() {
shmdt(playerData_pd);
}
-/* vim:set shiftwidth=4 tabstop=8 expandtab: */
diff --git a/src/playlist.c b/src/playlist.c
index dd261cfd..4b6fa520 100644
--- a/src/playlist.c
+++ b/src/playlist.c
@@ -802,15 +802,19 @@ void syncCurrentPlayerDecodeMetadata() {
songNum = playlist.order[playlist.current];
song = playlist.songs[songNum];
+ printf("HERE 1\n");
+
if(song->type == SONG_TYPE_URL &&
0 == strcmp(song->utf8url, songPlayer->utf8url) &&
!mpdTagsAreEqual(song->tag, songPlayer->tag))
{
+ printf("HERE 1-1\n");
if(song->tag) freeMpdTag(song->tag);
song->tag = mpdTagDup(songPlayer->tag);
playlist.songMod[songNum] = playlist.version;
incrPlaylistVersion();
}
+ printf("HERE 2\n");
}
void syncPlayerAndPlaylist() {
diff --git a/src/tag.c b/src/tag.c
index 729ccb0f..afb9d7a7 100644
--- a/src/tag.c
+++ b/src/tag.c
@@ -169,7 +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->name) free(tag->name);
if(tag->track) free(tag->track);
}
diff --git a/src/tag.h b/src/tag.h
index 841791ae..06129b76 100644
--- a/src/tag.h
+++ b/src/tag.h
@@ -60,4 +60,3 @@ void validateUtf8Tag(MpdTag * tag);
int mpdTagsAreEqual(MpdTag * tag1, MpdTag * tag2);
#endif
-/* vim:set shiftwidth=4 tabstop=8 expandtab: */