aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/audio.c6
-rw-r--r--src/audio.h5
-rw-r--r--src/audioOutput.c6
-rw-r--r--src/audioOutput.h9
-rw-r--r--src/audioOutput_ao.c3
-rw-r--r--src/audioOutput_shout.c96
-rw-r--r--src/decode.c10
-rw-r--r--src/metadataChunk.c4
-rw-r--r--src/player.c6
-rw-r--r--src/player.h1
10 files changed, 116 insertions, 30 deletions
diff --git a/src/audio.c b/src/audio.c
index 75d833be3..f66d25c98 100644
--- a/src/audio.c
+++ b/src/audio.c
@@ -34,7 +34,7 @@ static AudioFormat * audio_configFormat = NULL;
static AudioOutput * aoOutput = NULL;
static AudioOutput * shoutOutput = NULL;
-static void copyAudioFormat(AudioFormat * dest, AudioFormat * src) {
+void copyAudioFormat(AudioFormat * dest, AudioFormat * src) {
if(!src) return;
dest->sampleRate = src->sampleRate;
@@ -182,3 +182,7 @@ void closeAudioDevice() {
if(shoutOutput) closeAudioOutput(shoutOutput);
closeAudioOutput(aoOutput);
}
+
+void sendMetdataToAudioDevice(MpdTag * tag) {
+ if(shoutOutput) sendMetadataToAudioOutput(shoutOutput, tag);
+}
diff --git a/src/audio.h b/src/audio.h
index 7a1209c1b..cda95c7d8 100644
--- a/src/audio.h
+++ b/src/audio.h
@@ -22,6 +22,7 @@
#include "../config.h"
#include "mpd_types.h"
+#include "tag.h"
#include <stdio.h>
@@ -33,6 +34,8 @@ typedef struct _AudioFormat {
volatile mpd_sint8 bits;
} AudioFormat;
+void copyAudioFormat(AudioFormat * dest, AudioFormat * src);
+
void getOutputAudioFormat(AudioFormat * inFormat, AudioFormat * outFormat);
int parseAudioConfig(AudioFormat * audioFormat, char * conf);
@@ -55,4 +58,6 @@ int isAudioDeviceOpen();
int isCurrentAudioFormat(AudioFormat * audioFormat);
+void sendMetdataToAudioDevice(MpdTag * tag);
+
#endif
diff --git a/src/audioOutput.c b/src/audioOutput.c
index 24899e814..2963b7497 100644
--- a/src/audioOutput.c
+++ b/src/audioOutput.c
@@ -32,6 +32,7 @@ AudioOutput * newAudioOutput(char * name) {
ret->openDeviceFunc = plugin->openDeviceFunc;
ret->playFunc = plugin->playFunc;
ret->closeDeviceFunc = plugin->closeDeviceFunc;
+ ret->sendMetdataFunc = plugin->sendMetdataFunc;
ret->open = 0;
if(plugin->initDriverFunc(ret) != 0) {
@@ -62,3 +63,8 @@ void finishAudioOutput(AudioOutput * audioOutput) {
audioOutput->finishDriverFunc(audioOutput);
free(audioOutput);
}
+
+void sendMetadataToAudioOutput(AudioOutput * audioOutput, MpdTag * tag) {
+ if(!audioOutput->open || !audioOutput->sendMetdataFunc) return;
+ audioOutput->sendMetdataFunc(audioOutput, tag);
+}
diff --git a/src/audioOutput.h b/src/audioOutput.h
index 92387b7da..ec43e9e7c 100644
--- a/src/audioOutput.h
+++ b/src/audioOutput.h
@@ -23,6 +23,7 @@
#include "mpd_types.h"
#include "audio.h"
+#include "tag.h"
#define AUDIO_AO_DRIVER_DEFAULT "default"
@@ -40,7 +41,8 @@ typedef int (* AudioOutputPlayFunc) (AudioOutput * audioOutput,
typedef void (* AudioOutputCloseDeviceFunc) (AudioOutput * audioOutput);
-typedef int (* AudioOutputKeepAliveFunc) (AudioOutput * audioOutput, int ms);
+typedef void (* AudioOutputSendMetadataFunc) (AudioOutput * audioOutput,
+ MpdTag * tag);
struct _AudioOutput {
int open;
@@ -49,7 +51,7 @@ struct _AudioOutput {
AudioOutputOpenDeviceFunc openDeviceFunc;
AudioOutputPlayFunc playFunc;
AudioOutputCloseDeviceFunc closeDeviceFunc;
- AudioOutputKeepAliveFunc keepAliveFunc;
+ AudioOutputSendMetadataFunc sendMetdataFunc;
void * data;
};
@@ -62,7 +64,7 @@ typedef struct _AudioOutputPlugin {
AudioOutputOpenDeviceFunc openDeviceFunc;
AudioOutputPlayFunc playFunc;
AudioOutputCloseDeviceFunc closeDeviceFunc;
- AudioOutputKeepAliveFunc keepAliveFunc;
+ AudioOutputSendMetadataFunc sendMetdataFunc;
} AudioOutputPlugin;
void initAudioOutputPlugins();
@@ -77,5 +79,6 @@ int playAudioOutput(AudioOutput * audioOutput, char * playChunk, int size);
void closeAudioOutput(AudioOutput * audioOutput);
void finishAudioOutput(AudioOutput * audioOutput);
int keepAudioOutputAlive(AudioOutput * audioOutput, int ms);
+void sendMetadataToAudioOutput(AudioOutput * audioOutput, MpdTag * tag);
#endif
diff --git a/src/audioOutput_ao.c b/src/audioOutput_ao.c
index 95f0f1a98..7c997c99e 100644
--- a/src/audioOutput_ao.c
+++ b/src/audioOutput_ao.c
@@ -225,5 +225,6 @@ AudioOutputPlugin aoPlugin =
audioOutputAo_finishDriver,
audioOutputAo_openDevice,
audioOutputAo_play,
- audioOutputAo_closeDevice
+ audioOutputAo_closeDevice,
+ NULL /* sendMetadataFunc */
};
diff --git a/src/audioOutput_shout.c b/src/audioOutput_shout.c
index c650a74e5..514fbbe68 100644
--- a/src/audioOutput_shout.c
+++ b/src/audioOutput_shout.c
@@ -54,8 +54,6 @@ typedef struct _ShoutData {
vorbis_info vi;
vorbis_comment vc;
- int serialno;
-
float quality;
AudioFormat outAudioFormat;
AudioFormat inAudioFormat;
@@ -72,7 +70,6 @@ static ShoutData * newShoutData() {
ShoutData * ret = malloc(sizeof(ShoutData));
ret->shoutConn = shout_new();
- ret->serialno = rand();
ret->convBuffer = NULL;
ret->convBufferLen = 0;
ret->opened = 0;
@@ -190,6 +187,14 @@ static int shout_initDriver(AudioOutput * audioOutput) {
return 0;
}
+static void clearEncoder(ShoutData * sd) {
+ ogg_stream_clear(&(sd->os));
+ vorbis_block_clear(&(sd->vb));
+ vorbis_dsp_clear(&(sd->vd));
+ vorbis_comment_clear(&(sd->vc));
+ vorbis_info_clear(&(sd->vi));
+}
+
static void shout_closeShoutConn(ShoutData * sd) {
if(sd->opened) {
if(shout_close(sd->shoutConn) != SHOUTERR_SUCCESS) {
@@ -197,11 +202,7 @@ static void shout_closeShoutConn(ShoutData * sd) {
"%s\n", shout_get_error(sd->shoutConn));
}
- ogg_stream_clear(&(sd->os));
- vorbis_block_clear(&(sd->vb));
- vorbis_dsp_clear(&(sd->vd));
- vorbis_comment_clear(&(sd->vc));
- vorbis_info_clear(&(sd->vi));
+ clearEncoder(sd);
}
sd->opened = 0;
@@ -250,6 +251,27 @@ static void write_page(ShoutData * sd) {
/*shout_sync(sd->shoutConn);*/
}
+static int initEncoder(ShoutData * sd) {
+ vorbis_info_init(&(sd->vi));
+
+ if( 0 != vorbis_encode_init_vbr(&(sd->vi), sd->outAudioFormat.channels,
+ sd->outAudioFormat.sampleRate, sd->quality) )
+ {
+ ERROR("problem seting up vorbis encoder for shout\n");
+ vorbis_info_clear(&(sd->vi));
+ return -1;
+ }
+
+ vorbis_analysis_init(&(sd->vd), &(sd->vi));
+ vorbis_block_init (&(sd->vd), &(sd->vb));
+
+ ogg_stream_init(&(sd->os), rand());
+
+ vorbis_comment_init(&(sd->vc));
+
+ return 0;
+}
+
static int shout_openDevice(AudioOutput * audioOutput,
AudioFormat * audioFormat)
{
@@ -277,24 +299,12 @@ static int shout_openDevice(AudioOutput * audioOutput,
return -1;
}
- vorbis_info_init(&(sd->vi));
-
- if( 0 != vorbis_encode_init_vbr(&(sd->vi), sd->outAudioFormat.channels,
- sd->outAudioFormat.sampleRate, sd->quality) )
- {
- ERROR("problem seting up vorbis encoder for shout\n");
- vorbis_info_clear(&(sd->vi));
+ if(initEncoder(sd) < 0) {
shout_close(sd->shoutConn);
- audioOutput->open = 0;
+ audioOutput->open = 1;
return -1;
}
- vorbis_analysis_init(&(sd->vd), &(sd->vi));
- vorbis_block_init (&(sd->vd), &(sd->vb));
-
- ogg_stream_init(&(sd->os), sd->serialno);
-
- vorbis_comment_init(&(sd->vc));
vorbis_analysis_headerout(&(sd->vd), &(sd->vc), &(sd->header_main),
&(sd->header_comments), &(sd->header_codebooks));
@@ -375,6 +385,44 @@ static int shout_play(AudioOutput * audioOutput, char * playChunk, int size) {
return 0;
}
+#define addTag(name, value) { \
+ if(value) vorbis_comment_add_tag(&(sd->vc), name, value); \
+}
+
+static void shout_sendMetadata(AudioOutput * audioOutput, MpdTag * tag) {
+ ShoutData * sd = (ShoutData *)audioOutput->data;
+ ogg_int64_t granulepos = sd->vd.granulepos;
+
+ clearEncoder(sd);
+ if(initEncoder(sd) < 0) return;
+
+ sd->vd.granulepos = granulepos;
+
+ if(tag) {
+ addTag("ARTIST", tag->artist);
+ addTag("ALBUM", tag->album);
+ addTag("TITLE", tag->title);
+
+ }
+
+ DEBUG("shout: got tag\n");
+
+ vorbis_analysis_headerout(&(sd->vd), &(sd->vc), &(sd->header_main),
+ &(sd->header_comments), &(sd->header_codebooks));
+
+ ogg_stream_packetin(&(sd->os), &(sd->header_main));
+ ogg_stream_packetin(&(sd->os), &(sd->header_comments));
+ ogg_stream_packetin(&(sd->os), &(sd->header_codebooks));
+
+ /*vorbis_commentheader_out(&(sd->vc), &(sd->header_comments));
+ ogg_stream_packetin(&(sd->os), &(sd->header_comments));*/
+
+ while(ogg_stream_flush(&(sd->os), &(sd->og)))
+ {
+ write_page(sd);
+ }
+}
+
AudioOutputPlugin shoutPlugin =
{
"shout",
@@ -382,7 +430,8 @@ AudioOutputPlugin shoutPlugin =
shout_finishDriver,
shout_openDevice,
shout_play,
- shout_closeDevice
+ shout_closeDevice,
+ shout_sendMetadata
};
#else
@@ -396,6 +445,7 @@ AudioOutputPlugin shoutPlugin =
NULL,
NULL,
NULL,
+ NULL,
NULL
};
diff --git a/src/decode.c b/src/decode.c
index 7296e154c..55252c46e 100644
--- a/src/decode.c
+++ b/src/decode.c
@@ -145,6 +145,7 @@ int waitOnDecode(PlayerControl * pc, DecoderControl * dc, OutputBuffer * cb,
{
strncpy(pc->currentUrl, pc->utf8url, MAXPATHLEN);
pc->currentUrl[MAXPATHLEN] = '\0';
+ MpdTag * tag = NULL;
while(decode_pid && *decode_pid>0 && dc->start) my_usleep(10000);
@@ -156,8 +157,14 @@ int waitOnDecode(PlayerControl * pc, DecoderControl * dc, OutputBuffer * cb,
return -1;
}
+ if((tag = metadataChunkToMpdTagDup(&(pc->fileMetadataChunk)))) {
+ sendMetdataToAudioDevice(tag);
+ printMpdTag(stdout, tag);
+ freeMpdTag(tag);
+ tag = NULL;
+ }
+
pc->totalTime = pc->fileTime;
- pc->elapsedTime = 0;
pc->bitRate = 0;
pc->sampleRate = 0;
pc->bits = 0;
@@ -465,6 +472,7 @@ void decodeParent(PlayerControl * pc, DecoderControl * dc, OutputBuffer * cb) {
if(waitOnDecode(pc,dc,cb,&decodeWaitedOn)<0) return;
+ pc->elapsedTime = 0;
pc->state = PLAYER_STATE_PLAY;
pc->play = 0;
kill(getppid(),SIGUSR1);
diff --git a/src/metadataChunk.c b/src/metadataChunk.c
index 49cba9d90..84817eb0e 100644
--- a/src/metadataChunk.c
+++ b/src/metadataChunk.c
@@ -38,7 +38,7 @@ void initMetadataChunk(MetadataChunk * chunk) {
MpdTag * metadataChunkToMpdTagDup(MetadataChunk * chunk) {
MpdTag * ret = newMpdTag();
- chunk->buffer[METADATA_BUFFER_LENGTH] = '\0';
+ chunk->buffer[METADATA_BUFFER_LENGTH-1] = '\0';
dupElementToTag(ret->name, chunk->name);
dupElementToTag(ret->title, chunk->title);
@@ -65,6 +65,8 @@ void copyMpdTagToMetadataChunk(MpdTag * tag, MetadataChunk * chunk) {
initMetadataChunk(chunk);
+ if(!tag) return;
+
copyStringToChunk(tag->name, chunk->name);
copyStringToChunk(tag->title, chunk->title);
copyStringToChunk(tag->artist, chunk->artist);
diff --git a/src/player.c b/src/player.c
index 8c9d0df45..f38b9384c 100644
--- a/src/player.c
+++ b/src/player.c
@@ -187,6 +187,8 @@ int playerPlay(FILE * fp, Song * song) {
if(song->tag) pc->fileTime = song->tag->time;
else pc->fileTime = 0;
+ copyMpdTagToMetadataChunk(song->tag, &(pc->fileMetadataChunk));
+
strncpy(pc->utf8url, song->utf8url, MAXPATHLEN);
pc->utf8url[MAXPATHLEN] = '\0';
@@ -338,6 +340,8 @@ int queueSong(Song * song) {
if(song->tag) pc->fileTime = song->tag->time;
else pc->fileTime = 0;
+ copyMpdTagToMetadataChunk(song->tag, &(pc->fileMetadataChunk));
+
pc->queueState = PLAYER_QUEUE_FULL;
return 0;
}
@@ -390,6 +394,8 @@ int playerSeek(FILE * fp, Song * song, float time) {
if(song->tag) pc->fileTime = song->tag->time;
else pc->fileTime = 0;
+ copyMpdTagToMetadataChunk(song->tag, &(pc->fileMetadataChunk));
+
strncpy(pc->utf8url, song->utf8url, MAXPATHLEN);
pc->utf8url[MAXPATHLEN] = '\0';
}
diff --git a/src/player.h b/src/player.h
index e869d1fa9..8ab4a4513 100644
--- a/src/player.h
+++ b/src/player.h
@@ -86,6 +86,7 @@ typedef struct _PlayerControl {
volatile mpd_sint8 cycleLogFiles;
volatile mpd_sint8 metadataState;
MetadataChunk metadataChunk;
+ MetadataChunk fileMetadataChunk;
} PlayerControl;
void clearPlayerPid();