diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/Makefile.am | 4 | ||||
-rw-r--r-- | src/decode.c | 88 | ||||
-rw-r--r-- | src/decode.h | 2 | ||||
-rw-r--r-- | src/metadataChunk.c | 46 | ||||
-rw-r--r-- | src/metadataChunk.h | 22 | ||||
-rw-r--r-- | src/outputBuffer.c | 48 | ||||
-rw-r--r-- | src/outputBuffer.h | 12 | ||||
-rw-r--r-- | src/player.c | 26 | ||||
-rw-r--r-- | src/player.h | 7 | ||||
-rw-r--r-- | src/playerData.c | 15 | ||||
-rw-r--r-- | src/playlist.c | 4 | ||||
-rw-r--r-- | src/tag.c | 2 | ||||
-rw-r--r-- | src/tag.h | 1 |
13 files changed, 143 insertions, 134 deletions
diff --git a/src/Makefile.am b/src/Makefile.am index de55f202a..e602248c1 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 99a4bd784..8053f44fa 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 4c2043b53..874e82303 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 000000000..1deab3d90 --- /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 000000000..05e1c907e --- /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 194e3af8a..d0a98b692 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 71136b363..a7e5bb171 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 587a5501d..e6da9aeb9 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 5e8d90e97..6453bd372 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 4950a2c7e..5804f306c 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 dd261cfd2..4b6fa5205 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() { @@ -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); } @@ -60,4 +60,3 @@ void validateUtf8Tag(MpdTag * tag); int mpdTagsAreEqual(MpdTag * tag1, MpdTag * tag2); #endif -/* vim:set shiftwidth=4 tabstop=8 expandtab: */ |