aboutsummaryrefslogtreecommitdiffstats
path: root/src/inputPlugins/flac_plugin.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/inputPlugins/flac_plugin.c')
-rw-r--r--src/inputPlugins/flac_plugin.c419
1 files changed, 231 insertions, 188 deletions
diff --git a/src/inputPlugins/flac_plugin.c b/src/inputPlugins/flac_plugin.c
index ca3f196ce..737cdbcd4 100644
--- a/src/inputPlugins/flac_plugin.c
+++ b/src/inputPlugins/flac_plugin.c
@@ -39,211 +39,240 @@
/* this code is based on flac123, from flac-tools */
static void flacError(const FLAC__SeekableStreamDecoder *,
- FLAC__StreamDecoderErrorStatus, void *);
+ FLAC__StreamDecoderErrorStatus, void *);
static void flacPrintErroredState(FLAC__SeekableStreamDecoderState state);
static void flacMetadata(const FLAC__SeekableStreamDecoder *,
- const FLAC__StreamMetadata *, void *);
-static FLAC__StreamDecoderWriteStatus flacWrite(const FLAC__SeekableStreamDecoder *,
- const FLAC__Frame *, const FLAC__int32 * const buf[], void *);
-static FLAC__SeekableStreamDecoderReadStatus flacRead(
- const FLAC__SeekableStreamDecoder *, FLAC__byte buf[],
- unsigned *, void *);
-static FLAC__SeekableStreamDecoderSeekStatus flacSeek(
- const FLAC__SeekableStreamDecoder *, FLAC__uint64, void *);
-static FLAC__SeekableStreamDecoderTellStatus flacTell(
- const FLAC__SeekableStreamDecoder *, FLAC__uint64 *, void *);
-static FLAC__SeekableStreamDecoderLengthStatus flacLength(
- const FLAC__SeekableStreamDecoder *, FLAC__uint64 *, void *);
+ const FLAC__StreamMetadata *, void *);
+static FLAC__StreamDecoderWriteStatus flacWrite(const
+ FLAC__SeekableStreamDecoder *,
+ const FLAC__Frame *,
+ const FLAC__int32 * const buf[],
+ void *);
+static FLAC__SeekableStreamDecoderReadStatus flacRead(const
+ FLAC__SeekableStreamDecoder
+ *, FLAC__byte buf[],
+ unsigned *, void *);
+static FLAC__SeekableStreamDecoderSeekStatus flacSeek(const
+ FLAC__SeekableStreamDecoder
+ *, FLAC__uint64, void *);
+static FLAC__SeekableStreamDecoderTellStatus flacTell(const
+ FLAC__SeekableStreamDecoder
+ *, FLAC__uint64 *,
+ void *);
+static FLAC__SeekableStreamDecoderLengthStatus flacLength(const
+ FLAC__SeekableStreamDecoder
+ *, FLAC__uint64 *,
+ void *);
static FLAC__bool flacEOF(const FLAC__SeekableStreamDecoder *, void *);
-static int flac_decode(OutputBuffer * cb, DecoderControl * dc, InputStream * inStream)
+static int flac_decode(OutputBuffer * cb, DecoderControl * dc,
+ InputStream * inStream)
{
- FLAC__SeekableStreamDecoder * flacDec = NULL;
+ FLAC__SeekableStreamDecoder *flacDec = NULL;
FlacData data;
int status = 1;
- int ret =0;
+ int ret = 0;
init_FlacData(&data, cb, dc, inStream);
- if(!(flacDec = FLAC__seekable_stream_decoder_new())) {
- ret = -1;
- goto fail;
- }
- /*status&=FLAC__file_decoder_set_md5_checking(flacDec,1);*/
- status&=FLAC__seekable_stream_decoder_set_read_callback(flacDec,
- flacRead);
- status&=FLAC__seekable_stream_decoder_set_seek_callback(flacDec,
- flacSeek);
- status&=FLAC__seekable_stream_decoder_set_tell_callback(flacDec,
- flacTell);
- status&=FLAC__seekable_stream_decoder_set_length_callback(flacDec,
- flacLength);
- status&=FLAC__seekable_stream_decoder_set_eof_callback(flacDec,flacEOF);
- status&=FLAC__seekable_stream_decoder_set_write_callback(flacDec,
- flacWrite);
- status&=FLAC__seekable_stream_decoder_set_metadata_callback(flacDec,
- flacMetadata);
- status&=FLAC__seekable_stream_decoder_set_metadata_respond(flacDec,
- FLAC__METADATA_TYPE_VORBIS_COMMENT);
- status&=FLAC__seekable_stream_decoder_set_error_callback(flacDec,
- flacError);
- status&=FLAC__seekable_stream_decoder_set_client_data(flacDec,
- (void *)&data);
- if(!status) {
+ if (!(flacDec = FLAC__seekable_stream_decoder_new())) {
+ ret = -1;
+ goto fail;
+ }
+ /*status&=FLAC__file_decoder_set_md5_checking(flacDec,1); */
+ status &= FLAC__seekable_stream_decoder_set_read_callback(flacDec,
+ flacRead);
+ status &= FLAC__seekable_stream_decoder_set_seek_callback(flacDec,
+ flacSeek);
+ status &= FLAC__seekable_stream_decoder_set_tell_callback(flacDec,
+ flacTell);
+ status &= FLAC__seekable_stream_decoder_set_length_callback(flacDec,
+ flacLength);
+ status &=
+ FLAC__seekable_stream_decoder_set_eof_callback(flacDec, flacEOF);
+ status &=
+ FLAC__seekable_stream_decoder_set_write_callback(flacDec,
+ flacWrite);
+ status &=
+ FLAC__seekable_stream_decoder_set_metadata_callback(flacDec,
+ flacMetadata);
+ status &=
+ FLAC__seekable_stream_decoder_set_metadata_respond(flacDec,
+ FLAC__METADATA_TYPE_VORBIS_COMMENT);
+ status &=
+ FLAC__seekable_stream_decoder_set_error_callback(flacDec,
+ flacError);
+ status &=
+ FLAC__seekable_stream_decoder_set_client_data(flacDec,
+ (void *)&data);
+ if (!status) {
ERROR("flac problem before init()\n");
- flacPrintErroredState(
- FLAC__seekable_stream_decoder_get_state(flacDec));
+ flacPrintErroredState(FLAC__seekable_stream_decoder_get_state
+ (flacDec));
ret = -1;
- goto fail;
+ goto fail;
}
- if(FLAC__seekable_stream_decoder_init(flacDec)!=
- FLAC__SEEKABLE_STREAM_DECODER_OK)
- {
+ if (FLAC__seekable_stream_decoder_init(flacDec) !=
+ FLAC__SEEKABLE_STREAM_DECODER_OK) {
ERROR("flac problem doing init()\n");
- flacPrintErroredState(
- FLAC__seekable_stream_decoder_get_state(flacDec));
- ret = -1;
- goto fail;
+ flacPrintErroredState(FLAC__seekable_stream_decoder_get_state
+ (flacDec));
+ ret = -1;
+ goto fail;
}
- if(!FLAC__seekable_stream_decoder_process_until_end_of_metadata(flacDec)) {
+ if (!FLAC__seekable_stream_decoder_process_until_end_of_metadata
+ (flacDec)) {
ERROR("flac problem reading metadata\n");
- flacPrintErroredState(
- FLAC__seekable_stream_decoder_get_state(flacDec));
+ flacPrintErroredState(FLAC__seekable_stream_decoder_get_state
+ (flacDec));
ret = -1;
- goto fail;
+ goto fail;
}
dc->state = DECODE_STATE_DECODE;
- while(1) {
+ while (1) {
FLAC__seekable_stream_decoder_process_single(flacDec);
- if(FLAC__seekable_stream_decoder_get_state(flacDec)!=
- FLAC__SEEKABLE_STREAM_DECODER_OK)
- {
+ if (FLAC__seekable_stream_decoder_get_state(flacDec) !=
+ FLAC__SEEKABLE_STREAM_DECODER_OK) {
break;
}
- if(dc->seek) {
- FLAC__uint64 sampleToSeek = dc->seekWhere*
- dc->audioFormat.sampleRate+0.5;
- if(FLAC__seekable_stream_decoder_seek_absolute(flacDec,
- sampleToSeek))
+ if (dc->seek) {
+ FLAC__uint64 sampleToSeek = dc->seekWhere *
+ dc->audioFormat.sampleRate + 0.5;
+ if (FLAC__seekable_stream_decoder_seek_absolute(flacDec,
+ sampleToSeek))
{
- clearOutputBuffer(cb);
- data.time = ((float)sampleToSeek)/
- dc->audioFormat.sampleRate;
+ clearOutputBuffer(cb);
+ data.time = ((float)sampleToSeek) /
+ dc->audioFormat.sampleRate;
data.position = 0;
- }
- else dc->seekError = 1;
+ } else
+ dc->seekError = 1;
dc->seek = 0;
}
}
/* I don't think we need this bit here! -shank */
- /*FLAC__file_decoder_process_until_end_of_file(flacDec);*/
- if(!dc->stop) {
- flacPrintErroredState(
- FLAC__seekable_stream_decoder_get_state(flacDec));
+ /*FLAC__file_decoder_process_until_end_of_file(flacDec); */
+ if (!dc->stop) {
+ flacPrintErroredState(FLAC__seekable_stream_decoder_get_state
+ (flacDec));
FLAC__seekable_stream_decoder_finish(flacDec);
}
/* send last little bit */
- if(data.chunk_length>0 && !dc->stop) {
+ if (data.chunk_length > 0 && !dc->stop) {
flacSendChunk(&data);
flushOutputBuffer(data.cb);
}
/*if(dc->seek) {
- dc->seekError = 1;
- dc->seek = 0;
- } */
-
+ dc->seekError = 1;
+ dc->seek = 0;
+ } */
+
dc->state = DECODE_STATE_STOP;
dc->stop = 0;
-fail:
- if(data.replayGainInfo) freeReplayGainInfo(data.replayGainInfo);
+ fail:
+ if (data.replayGainInfo)
+ freeReplayGainInfo(data.replayGainInfo);
- if(flacDec) FLAC__seekable_stream_decoder_delete(flacDec);
+ if (flacDec)
+ FLAC__seekable_stream_decoder_delete(flacDec);
closeInputStream(inStream);
-
+
return ret;
}
-static FLAC__SeekableStreamDecoderReadStatus flacRead(
- const FLAC__SeekableStreamDecoder * flacDec, FLAC__byte buf[],
- unsigned * bytes, void * fdata) {
- FlacData * data = (FlacData *) fdata;
+static FLAC__SeekableStreamDecoderReadStatus flacRead(const
+ FLAC__SeekableStreamDecoder
+ * flacDec,
+ FLAC__byte buf[],
+ unsigned *bytes,
+ void *fdata)
+{
+ FlacData *data = (FlacData *) fdata;
size_t r;
while (1) {
- r = readFromInputStream(data->inStream,(void *)buf,1,*bytes);
+ r = readFromInputStream(data->inStream, (void *)buf, 1, *bytes);
if (r == 0 && !inputStreamAtEOF(data->inStream) &&
- !data->dc->stop)
+ !data->dc->stop)
my_usleep(10000);
else
break;
}
*bytes = r;
-
- if (*bytes==0 && !inputStreamAtEOF(data->inStream) && !data->dc->stop)
+
+ if (*bytes == 0 && !inputStreamAtEOF(data->inStream) && !data->dc->stop)
return FLAC__SEEKABLE_STREAM_DECODER_READ_STATUS_ERROR;
-
- return FLAC__SEEKABLE_STREAM_DECODER_READ_STATUS_OK;
+
+ return FLAC__SEEKABLE_STREAM_DECODER_READ_STATUS_OK;
}
-static FLAC__SeekableStreamDecoderSeekStatus flacSeek(
- const FLAC__SeekableStreamDecoder * flacDec,
- FLAC__uint64 offset, void * fdata)
+static FLAC__SeekableStreamDecoderSeekStatus flacSeek(const
+ FLAC__SeekableStreamDecoder
+ * flacDec,
+ FLAC__uint64 offset,
+ void *fdata)
{
- FlacData * data = (FlacData *) fdata;
+ FlacData *data = (FlacData *) fdata;
- if(seekInputStream(data->inStream,offset,SEEK_SET)<0) {
- return FLAC__SEEKABLE_STREAM_DECODER_SEEK_STATUS_ERROR;
- }
+ if (seekInputStream(data->inStream, offset, SEEK_SET) < 0) {
+ return FLAC__SEEKABLE_STREAM_DECODER_SEEK_STATUS_ERROR;
+ }
- return FLAC__SEEKABLE_STREAM_DECODER_SEEK_STATUS_OK;
+ return FLAC__SEEKABLE_STREAM_DECODER_SEEK_STATUS_OK;
}
-static FLAC__SeekableStreamDecoderTellStatus flacTell(
- const FLAC__SeekableStreamDecoder * flacDec,
- FLAC__uint64 * offset, void * fdata)
+static FLAC__SeekableStreamDecoderTellStatus flacTell(const
+ FLAC__SeekableStreamDecoder
+ * flacDec,
+ FLAC__uint64 * offset,
+ void *fdata)
{
- FlacData * data = (FlacData *) fdata;
+ FlacData *data = (FlacData *) fdata;
- *offset = (long)(data->inStream->offset);
+ *offset = (long)(data->inStream->offset);
- return FLAC__SEEKABLE_STREAM_DECODER_TELL_STATUS_OK;
+ return FLAC__SEEKABLE_STREAM_DECODER_TELL_STATUS_OK;
}
-static FLAC__SeekableStreamDecoderLengthStatus flacLength(
- const FLAC__SeekableStreamDecoder * flacDec,
- FLAC__uint64 * length, void * fdata)
+static FLAC__SeekableStreamDecoderLengthStatus flacLength(const
+ FLAC__SeekableStreamDecoder
+ * flacDec,
+ FLAC__uint64 * length,
+ void *fdata)
{
- FlacData * data = (FlacData *) fdata;
+ FlacData *data = (FlacData *) fdata;
- *length = (size_t)(data->inStream->size);
+ *length = (size_t) (data->inStream->size);
- return FLAC__SEEKABLE_STREAM_DECODER_LENGTH_STATUS_OK;
+ return FLAC__SEEKABLE_STREAM_DECODER_LENGTH_STATUS_OK;
}
-static FLAC__bool flacEOF(const FLAC__SeekableStreamDecoder * flacDec, void * fdata) {
- FlacData * data = (FlacData *) fdata;
-
+static FLAC__bool flacEOF(const FLAC__SeekableStreamDecoder * flacDec,
+ void *fdata)
+{
+ FlacData *data = (FlacData *) fdata;
+
if (inputStreamAtEOF(data->inStream) == 1)
- return true;
+ return true;
return false;
}
-static void flacError(const FLAC__SeekableStreamDecoder *dec,
- FLAC__StreamDecoderErrorStatus status, void *fdata)
+static void flacError(const FLAC__SeekableStreamDecoder * dec,
+ FLAC__StreamDecoderErrorStatus status, void *fdata)
{
- flac_error_common_cb("flac",status,(FlacData *) fdata);
+ flac_error_common_cb("flac", status, (FlacData *) fdata);
}
static void flacPrintErroredState(FLAC__SeekableStreamDecoderState state)
{
- switch(state) {
+ switch (state) {
case FLAC__SEEKABLE_STREAM_DECODER_MEMORY_ALLOCATION_ERROR:
ERROR("flac allocation error\n");
break;
@@ -272,48 +301,53 @@ static void flacPrintErroredState(FLAC__SeekableStreamDecoderState state)
}
}
-static void flacMetadata(const FLAC__SeekableStreamDecoder *dec,
- const FLAC__StreamMetadata *block, void *vdata)
+static void flacMetadata(const FLAC__SeekableStreamDecoder * dec,
+ const FLAC__StreamMetadata * block, void *vdata)
{
- flac_metadata_common_cb(block, (FlacData *)vdata);
+ flac_metadata_common_cb(block, (FlacData *) vdata);
}
-static FLAC__StreamDecoderWriteStatus flacWrite(const FLAC__SeekableStreamDecoder *dec,
- const FLAC__Frame *frame, const FLAC__int32 * const buf[],
- void * vdata)
+static FLAC__StreamDecoderWriteStatus flacWrite(const
+ FLAC__SeekableStreamDecoder *
+ dec, const FLAC__Frame * frame,
+ const FLAC__int32 * const buf[],
+ void *vdata)
{
- FlacData * data = (FlacData *)vdata;
+ FlacData *data = (FlacData *) vdata;
FLAC__uint32 samples = frame->header.blocksize;
FLAC__uint16 u16;
- unsigned char * uc;
+ unsigned char *uc;
int c_samp, c_chan, d_samp;
int i;
float timeChange;
FLAC__uint64 newPosition = 0;
-
- timeChange = ((float)samples)/frame->header.sample_rate;
- data->time+= timeChange;
-
- FLAC__seekable_stream_decoder_get_decode_position(dec,&newPosition);
- if(data->position) {
- data->bitRate = ((newPosition-data->position)*8.0/timeChange)
- /1000+0.5;
+
+ timeChange = ((float)samples) / frame->header.sample_rate;
+ data->time += timeChange;
+
+ FLAC__seekable_stream_decoder_get_decode_position(dec, &newPosition);
+ if (data->position) {
+ data->bitRate =
+ ((newPosition - data->position) * 8.0 / timeChange)
+ / 1000 + 0.5;
}
data->position = newPosition;
- for(c_samp = d_samp = 0; c_samp < frame->header.blocksize; c_samp++) {
- for(c_chan = 0; c_chan < frame->header.channels;
- c_chan++, d_samp++) {
+ for (c_samp = d_samp = 0; c_samp < frame->header.blocksize; c_samp++) {
+ for (c_chan = 0; c_chan < frame->header.channels;
+ c_chan++, d_samp++) {
u16 = buf[c_chan][c_samp];
uc = (unsigned char *)&u16;
- for(i=0;i<(data->dc->audioFormat.bits/8);i++) {
- if(data->chunk_length>=FLAC_CHUNK_SIZE) {
- if(flacSendChunk(data)<0) {
- return FLAC__STREAM_DECODER_WRITE_STATUS_ABORT;
+ for (i = 0; i < (data->dc->audioFormat.bits / 8); i++) {
+ if (data->chunk_length >= FLAC_CHUNK_SIZE) {
+ if (flacSendChunk(data) < 0) {
+ return
+ FLAC__STREAM_DECODER_WRITE_STATUS_ABORT;
}
data->chunk_length = 0;
- if(data->dc->seek) {
- return FLAC__STREAM_DECODER_WRITE_STATUS_CONTINUE;
+ if (data->dc->seek) {
+ return
+ FLAC__STREAM_DECODER_WRITE_STATUS_CONTINUE;
}
}
data->chunk[data->chunk_length++] = *(uc++);
@@ -324,66 +358,77 @@ static FLAC__StreamDecoderWriteStatus flacWrite(const FLAC__SeekableStreamDecode
return FLAC__STREAM_DECODER_WRITE_STATUS_CONTINUE;
}
-static MpdTag * flacMetadataDup(char * file, int * vorbisCommentFound) {
- MpdTag * ret = NULL;
- FLAC__Metadata_SimpleIterator * it;
- FLAC__StreamMetadata * block = NULL;
+static MpdTag *flacMetadataDup(char *file, int *vorbisCommentFound)
+{
+ MpdTag *ret = NULL;
+ FLAC__Metadata_SimpleIterator *it;
+ FLAC__StreamMetadata *block = NULL;
*vorbisCommentFound = 0;
it = FLAC__metadata_simple_iterator_new();
- if(!FLAC__metadata_simple_iterator_init(it, file ,1,0)) {
- switch(FLAC__metadata_simple_iterator_status(it)) {
- case FLAC__METADATA_SIMPLE_ITERATOR_STATUS_ILLEGAL_INPUT:
- DEBUG("flacMetadataDup: Reading '%s' metadata gave the following error: Illegal Input\n",file);
- break;
- case FLAC__METADATA_SIMPLE_ITERATOR_STATUS_ERROR_OPENING_FILE:
- DEBUG("flacMetadataDup: Reading '%s' metadata gave the following error: Error Opening File\n",file);
- break;
- case FLAC__METADATA_SIMPLE_ITERATOR_STATUS_NOT_A_FLAC_FILE:
- DEBUG("flacMetadataDup: Reading '%s' metadata gave the following error: Not A Flac File\n",file);
- break;
- default:
- DEBUG("flacMetadataDup: Reading '%s' metadata failed\n",file);
+ if (!FLAC__metadata_simple_iterator_init(it, file, 1, 0)) {
+ switch (FLAC__metadata_simple_iterator_status(it)) {
+ case FLAC__METADATA_SIMPLE_ITERATOR_STATUS_ILLEGAL_INPUT:
+ DEBUG
+ ("flacMetadataDup: Reading '%s' metadata gave the following error: Illegal Input\n",
+ file);
+ break;
+ case FLAC__METADATA_SIMPLE_ITERATOR_STATUS_ERROR_OPENING_FILE:
+ DEBUG
+ ("flacMetadataDup: Reading '%s' metadata gave the following error: Error Opening File\n",
+ file);
+ break;
+ case FLAC__METADATA_SIMPLE_ITERATOR_STATUS_NOT_A_FLAC_FILE:
+ DEBUG
+ ("flacMetadataDup: Reading '%s' metadata gave the following error: Not A Flac File\n",
+ file);
+ break;
+ default:
+ DEBUG("flacMetadataDup: Reading '%s' metadata failed\n",
+ file);
}
FLAC__metadata_simple_iterator_delete(it);
return ret;
}
-
+
do {
block = FLAC__metadata_simple_iterator_get_block(it);
- if(!block) break;
- if(block->type == FLAC__METADATA_TYPE_VORBIS_COMMENT) {
+ if (!block)
+ break;
+ if (block->type == FLAC__METADATA_TYPE_VORBIS_COMMENT) {
ret = copyVorbisCommentBlockToMpdTag(block, ret);
- if(ret) *vorbisCommentFound = 1;
- }
- else if(block->type == FLAC__METADATA_TYPE_STREAMINFO) {
- if(!ret) ret = newMpdTag();
+ if (ret)
+ *vorbisCommentFound = 1;
+ } else if (block->type == FLAC__METADATA_TYPE_STREAMINFO) {
+ if (!ret)
+ ret = newMpdTag();
ret->time = ((float)block->data.stream_info.
- total_samples) /
- block->data.stream_info.sample_rate +
- 0.5;
+ total_samples) /
+ block->data.stream_info.sample_rate + 0.5;
}
FLAC__metadata_object_delete(block);
- } while(FLAC__metadata_simple_iterator_next(it));
+ } while (FLAC__metadata_simple_iterator_next(it));
FLAC__metadata_simple_iterator_delete(it);
return ret;
}
-static MpdTag * flacTagDup(char * file) {
- MpdTag * ret = NULL;
+static MpdTag *flacTagDup(char *file)
+{
+ MpdTag *ret = NULL;
int foundVorbisComment = 0;
ret = flacMetadataDup(file, &foundVorbisComment);
- if(!ret) {
- DEBUG("flacTagDup: Failed to grab information from: %s\n", file);
+ if (!ret) {
+ DEBUG("flacTagDup: Failed to grab information from: %s\n",
+ file);
return NULL;
}
- if(!foundVorbisComment) {
- MpdTag * temp = id3Dup(file);
- if(temp) {
+ if (!foundVorbisComment) {
+ MpdTag *temp = id3Dup(file);
+ if (temp) {
temp->time = ret->time;
freeMpdTag(ret);
ret = temp;
@@ -393,11 +438,10 @@ static MpdTag * flacTagDup(char * file) {
return ret;
}
-static char * flacSuffixes[] = {"flac", NULL};
-static char * flac_mime_types[] = {"application/x-flac", NULL};
+static char *flacSuffixes[] = { "flac", NULL };
+static char *flac_mime_types[] = { "application/x-flac", NULL };
-InputPlugin flacPlugin =
-{
+InputPlugin flacPlugin = {
"flac",
NULL,
NULL,
@@ -410,10 +454,9 @@ InputPlugin flacPlugin =
flac_mime_types
};
-#else /* !HAVE_FLAC */
+#else /* !HAVE_FLAC */
-InputPlugin flacPlugin =
-{
+InputPlugin flacPlugin = {
NULL,
NULL,
NULL,
@@ -426,4 +469,4 @@ InputPlugin flacPlugin =
NULL,
};
-#endif /* HAVE_FLAC */
+#endif /* HAVE_FLAC */