fix a big time bug in metadataChunk (off by one in an array assignment)

also, now we have metadata in our streams

git-svn-id: https://svn.musicpd.org/mpd/trunk@2337 09075e82-0dd4-0310-85a5-a0d7c8717e4f
This commit is contained in:
Warren Dukes 2004-10-25 20:09:03 +00:00
parent b6bcc65a45
commit ce10ba4b11
10 changed files with 116 additions and 30 deletions

View File

@ -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);
}

View File

@ -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

View File

@ -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);
}

View File

@ -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

View File

@ -225,5 +225,6 @@ AudioOutputPlugin aoPlugin =
audioOutputAo_finishDriver,
audioOutputAo_openDevice,
audioOutputAo_play,
audioOutputAo_closeDevice
audioOutputAo_closeDevice,
NULL /* sendMetadataFunc */
};

View File

@ -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
};

View File

@ -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);

View File

@ -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);

View File

@ -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';
}

View File

@ -86,6 +86,7 @@ typedef struct _PlayerControl {
volatile mpd_sint8 cycleLogFiles;
volatile mpd_sint8 metadataState;
MetadataChunk metadataChunk;
MetadataChunk fileMetadataChunk;
} PlayerControl;
void clearPlayerPid();