Add mpd-indent.sh

Indent the entire tree, hopefully we can keep
it indented.

git-svn-id: https://svn.musicpd.org/mpd/trunk@4410 09075e82-0dd4-0310-85a5-a0d7c8717e4f
This commit is contained in:
Avuton Olrich
2006-07-20 16:02:40 +00:00
parent 099f0e103f
commit 29a25b9933
92 changed files with 8976 additions and 7978 deletions

View File

@@ -38,8 +38,8 @@
#include <FLAC/format.h>
#include <FLAC/metadata.h>
void init_FlacData (FlacData * data, OutputBuffer * cb,
DecoderControl * dc, InputStream * inStream)
void init_FlacData(FlacData * data, OutputBuffer * cb,
DecoderControl * dc, InputStream * inStream)
{
data->chunk_length = 0;
data->time = 0;
@@ -53,24 +53,24 @@ void init_FlacData (FlacData * data, OutputBuffer * cb,
}
static int flacFindVorbisCommentFloat(const FLAC__StreamMetadata * block,
char * cmnt, float * fl)
char *cmnt, float *fl)
{
int offset = FLAC__metadata_object_vorbiscomment_find_entry_from(
block,0,cmnt);
int offset =
FLAC__metadata_object_vorbiscomment_find_entry_from(block, 0, cmnt);
if(offset >= 0) {
size_t pos = strlen(cmnt)+1; /* 1 is for '=' */
if (offset >= 0) {
size_t pos = strlen(cmnt) + 1; /* 1 is for '=' */
int len = block->data.vorbis_comment.comments[offset].length
-pos;
if(len > 0) {
- pos;
if (len > 0) {
unsigned char tmp;
unsigned char * dup = &(block->data.vorbis_comment.
comments[offset].entry[pos]);
unsigned char *dup = &(block->data.vorbis_comment.
comments[offset].entry[pos]);
tmp = dup[len];
dup[len] = '\0';
*fl = atof((char *)dup);
dup[len] = tmp;
return 1;
}
}
@@ -79,8 +79,9 @@ static int flacFindVorbisCommentFloat(const FLAC__StreamMetadata * block,
}
/* replaygain stuff by AliasMrJones */
static void flacParseReplayGain(const FLAC__StreamMetadata *block,
FlacData * data) {
static void flacParseReplayGain(const FLAC__StreamMetadata * block,
FlacData * data)
{
unsigned int found = 0;
if (data->replayGainInfo)
@@ -88,14 +89,14 @@ static void flacParseReplayGain(const FLAC__StreamMetadata *block,
data->replayGainInfo = newReplayGainInfo();
found &= flacFindVorbisCommentFloat(block,"replaygain_album_gain",
&data->replayGainInfo->albumGain);
found &= flacFindVorbisCommentFloat(block,"replaygain_album_peak",
&data->replayGainInfo->albumPeak);
found &= flacFindVorbisCommentFloat(block,"replaygain_track_gain",
&data->replayGainInfo->trackGain);
found &= flacFindVorbisCommentFloat(block,"replaygain_track_peak",
&data->replayGainInfo->trackPeak);
found &= flacFindVorbisCommentFloat(block, "replaygain_album_gain",
&data->replayGainInfo->albumGain);
found &= flacFindVorbisCommentFloat(block, "replaygain_album_peak",
&data->replayGainInfo->albumPeak);
found &= flacFindVorbisCommentFloat(block, "replaygain_track_gain",
&data->replayGainInfo->trackGain);
found &= flacFindVorbisCommentFloat(block, "replaygain_track_peak",
&data->replayGainInfo->trackPeak);
if (!found) {
freeReplayGainInfo(data->replayGainInfo);
@@ -105,50 +106,55 @@ static void flacParseReplayGain(const FLAC__StreamMetadata *block,
/* tracknumber is used in VCs, MPD uses "track" ..., all the other
* tag names match */
static const char * VORBIS_COMMENT_TRACK_KEY = "tracknumber";
static const char * VORBIS_COMMENT_DISC_KEY = "discnumber";
static const char *VORBIS_COMMENT_TRACK_KEY = "tracknumber";
static const char *VORBIS_COMMENT_DISC_KEY = "discnumber";
static unsigned int commentMatchesAddToTag(
const FLAC__StreamMetadata_VorbisComment_Entry * entry,
unsigned int itemType,
MpdTag ** tag)
static unsigned int commentMatchesAddToTag(const
FLAC__StreamMetadata_VorbisComment_Entry
* entry, unsigned int itemType,
MpdTag ** tag)
{
const char * str;
const char *str;
size_t slen;
int vlen;
switch (itemType) {
case TAG_ITEM_TRACK: str = VORBIS_COMMENT_TRACK_KEY; break;
case TAG_ITEM_DISC: str = VORBIS_COMMENT_DISC_KEY; break;
default: str = mpdTagItemKeys[itemType];
case TAG_ITEM_TRACK:
str = VORBIS_COMMENT_TRACK_KEY;
break;
case TAG_ITEM_DISC:
str = VORBIS_COMMENT_DISC_KEY;
break;
default:
str = mpdTagItemKeys[itemType];
}
slen = strlen(str);
vlen = entry->length - slen - 1;
if ((vlen > 0) && (0 == strncasecmp(str,(char *)entry->entry, slen))
&& (*(entry->entry + slen) == '=')) {
if ((vlen > 0) && (0 == strncasecmp(str, (char *)entry->entry, slen))
&& (*(entry->entry + slen) == '=')) {
if (!*tag)
*tag = newMpdTag();
addItemToMpdTagWithLen(*tag, itemType,
(char *)(entry->entry+slen + 1), vlen);
addItemToMpdTagWithLen(*tag, itemType,
(char *)(entry->entry + slen + 1), vlen);
return 1;
}
return 0;
}
MpdTag * copyVorbisCommentBlockToMpdTag(const FLAC__StreamMetadata * block,
MpdTag * tag)
MpdTag *copyVorbisCommentBlockToMpdTag(const FLAC__StreamMetadata * block,
MpdTag * tag)
{
unsigned int i, j;
FLAC__StreamMetadata_VorbisComment_Entry *comments;
comments = block->data.vorbis_comment.comments;
for (i = block->data.vorbis_comment.num_comments; i != 0; --i) {
for (j = TAG_NUM_OF_ITEM_TYPES; j--; ) {
for (j = TAG_NUM_OF_ITEM_TYPES; j--;) {
if (commentMatchesAddToTag(comments, j, &tag))
break;
}
@@ -158,34 +164,36 @@ MpdTag * copyVorbisCommentBlockToMpdTag(const FLAC__StreamMetadata * block,
return tag;
}
void flac_metadata_common_cb(const FLAC__StreamMetadata *block, FlacData *data)
void flac_metadata_common_cb(const FLAC__StreamMetadata * block,
FlacData * data)
{
DecoderControl *dc = data->dc;
const FLAC__StreamMetadata_StreamInfo *si = &(block->data.stream_info);
switch(block->type) {
switch (block->type) {
case FLAC__METADATA_TYPE_STREAMINFO:
dc->audioFormat.bits = si->bits_per_sample;
dc->audioFormat.sampleRate = si->sample_rate;
dc->audioFormat.channels = si->channels;
dc->totalTime = ((float)si->total_samples) / (si->sample_rate);
getOutputAudioFormat(&(dc->audioFormat),
&(data->cb->audioFormat));
&(data->cb->audioFormat));
break;
case FLAC__METADATA_TYPE_VORBIS_COMMENT:
flacParseReplayGain(block,data);
default:
break;
flacParseReplayGain(block, data);
default:
break;
}
}
void flac_error_common_cb( const char * plugin,
const FLAC__StreamDecoderErrorStatus status,
FlacData *data)
void flac_error_common_cb(const char *plugin,
const FLAC__StreamDecoderErrorStatus status,
FlacData * data)
{
if(data->dc->stop) return;
if (data->dc->stop)
return;
switch(status) {
switch (status) {
case FLAC__STREAM_DECODER_ERROR_STATUS_LOST_SYNC:
ERROR("%s lost sync\n", plugin);
break;
@@ -196,8 +204,8 @@ void flac_error_common_cb( const char * plugin,
ERROR("%s crc mismatch\n", plugin);
break;
default:
ERROR("unknown %s error\n",plugin);
ERROR("unknown %s error\n", plugin);
}
}
#endif /* HAVE_FLAC || HAVE_OGGFLAC */
#endif /* HAVE_FLAC || HAVE_OGGFLAC */

View File

@@ -41,38 +41,38 @@ typedef struct {
float time;
int bitRate;
FLAC__uint64 position;
OutputBuffer * cb;
DecoderControl * dc;
InputStream * inStream;
ReplayGainInfo * replayGainInfo;
MpdTag * tag;
OutputBuffer *cb;
DecoderControl *dc;
InputStream *inStream;
ReplayGainInfo *replayGainInfo;
MpdTag *tag;
} FlacData;
/* initializes a given FlacData struct */
void init_FlacData (FlacData * data, OutputBuffer * cb,
DecoderControl * dc, InputStream * inStream);
void flac_metadata_common_cb( const FLAC__StreamMetadata *block,
FlacData *data);
void flac_error_common_cb( const char * plugin,
FLAC__StreamDecoderErrorStatus status,
FlacData *data);
void init_FlacData(FlacData * data, OutputBuffer * cb,
DecoderControl * dc, InputStream * inStream);
void flac_metadata_common_cb(const FLAC__StreamMetadata * block,
FlacData * data);
void flac_error_common_cb(const char *plugin,
FLAC__StreamDecoderErrorStatus status,
FlacData * data);
MpdTag * copyVorbisCommentBlockToMpdTag(const FLAC__StreamMetadata * block,
MpdTag * tag);
MpdTag *copyVorbisCommentBlockToMpdTag(const FLAC__StreamMetadata * block,
MpdTag * tag);
/* keep this inlined, this is just macro but prettier :) */
static inline int flacSendChunk(FlacData * data)
{
if (sendDataToOutputBuffer(data->cb, NULL, data->dc, 1, data->chunk,
data->chunk_length, data->time, data->bitRate,
data->replayGainInfo) == OUTPUT_BUFFER_DC_STOP)
data->chunk_length, data->time,
data->bitRate,
data->replayGainInfo) ==
OUTPUT_BUFFER_DC_STOP)
return -1;
return 0;
}
#endif /* HAVE_FLAC || HAVE_OGGFLAC */
#endif /* HAVE_FLAC || HAVE_OGGFLAC */
#endif /* _FLAC_COMMON_H */
#endif /* _FLAC_COMMON_H */

View File

@@ -37,29 +37,37 @@ ogg_stream_type ogg_stream_type_detect(InputStream * inStream)
size_t r, to_read = 41;
seekInputStream(inStream, 0, SEEK_SET);
while (to_read) {
r = readFromInputStream(inStream, buf, 1, to_read);
if (r < 0)
break;
to_read -= r;
if (!r && !inputStreamAtEOF(inStream))
if (!r && !inputStreamAtEOF(inStream))
my_usleep(10000);
else
break;
}
seekInputStream(inStream, 0, SEEK_SET);
if (r >= 32 && memcmp(buf, "OggS", 4) == 0 && (
(memcmp(buf+29, "FLAC", 4) == 0
&& memcmp(buf+37, "fLaC", 4) == 0)
|| (memcmp(buf+28, "FLAC", 4) == 0)
|| (memcmp(buf+28, "fLaC", 4) == 0))) {
if (r >= 32 && memcmp(buf, "OggS", 4) == 0 && ((memcmp
(buf + 29, "FLAC",
4) == 0
&& memcmp(buf + 37,
"fLaC",
4) == 0)
||
(memcmp
(buf + 28, "FLAC",
4) == 0)
||
(memcmp
(buf + 28, "fLaC",
4) == 0))) {
return FLAC;
}
return VORBIS;
}
#endif /* defined(HAVE_OGGFLAC || defined(HAVE_OGGVORBIS) */
#endif /* defined(HAVE_OGGFLAC || defined(HAVE_OGGVORBIS) */

View File

@@ -30,6 +30,6 @@ typedef enum _ogg_stream_type { VORBIS, FLAC } ogg_stream_type;
ogg_stream_type ogg_stream_type_detect(InputStream * inStream);
#endif /* defined(HAVE_OGGFLAC || defined(HAVE_OGGVORBIS) */
#endif /* defined(HAVE_OGGFLAC || defined(HAVE_OGGVORBIS) */
#endif /* _OGG_COMMON_H */
#endif /* _OGG_COMMON_H */

View File

@@ -36,7 +36,7 @@
/* all code here is either based on or copied from FAAD2's frontend code */
typedef struct {
InputStream * inStream;
InputStream *inStream;
long bytesIntoBuffer;
long bytesConsumed;
long fileOffset;
@@ -44,163 +44,193 @@ typedef struct {
int atEof;
} AacBuffer;
static void fillAacBuffer(AacBuffer *b) {
if(b->bytesConsumed > 0) {
static void fillAacBuffer(AacBuffer * b)
{
if (b->bytesConsumed > 0) {
int bread;
if(b->bytesIntoBuffer) {
memmove((void *)b->buffer,(void*)(b->buffer+
b->bytesConsumed),b->bytesIntoBuffer);
if (b->bytesIntoBuffer) {
memmove((void *)b->buffer, (void *)(b->buffer +
b->bytesConsumed),
b->bytesIntoBuffer);
}
if(!b->atEof) {
if (!b->atEof) {
bread = readFromInputStream(b->inStream,
(void *)(b->buffer+b->bytesIntoBuffer),
1,b->bytesConsumed);
if(bread!=b->bytesConsumed) b->atEof = 1;
b->bytesIntoBuffer+=bread;
(void *)(b->buffer +
b->
bytesIntoBuffer),
1, b->bytesConsumed);
if (bread != b->bytesConsumed)
b->atEof = 1;
b->bytesIntoBuffer += bread;
}
b->bytesConsumed = 0;
if(b->bytesIntoBuffer > 3) {
if(memcmp(b->buffer,"TAG",3)==0) b->bytesIntoBuffer = 0;
if (b->bytesIntoBuffer > 3) {
if (memcmp(b->buffer, "TAG", 3) == 0)
b->bytesIntoBuffer = 0;
}
if(b->bytesIntoBuffer > 11) {
if(memcmp(b->buffer,"LYRICSBEGIN",11)==0) {
if (b->bytesIntoBuffer > 11) {
if (memcmp(b->buffer, "LYRICSBEGIN", 11) == 0) {
b->bytesIntoBuffer = 0;
}
}
if(b->bytesIntoBuffer > 8) {
if(memcmp(b->buffer,"APETAGEX",8)==0) {
if (b->bytesIntoBuffer > 8) {
if (memcmp(b->buffer, "APETAGEX", 8) == 0) {
b->bytesIntoBuffer = 0;
}
}
}
}
static void advanceAacBuffer(AacBuffer * b, int bytes) {
b->fileOffset+=bytes;
static void advanceAacBuffer(AacBuffer * b, int bytes)
{
b->fileOffset += bytes;
b->bytesConsumed = bytes;
b->bytesIntoBuffer-=bytes;
b->bytesIntoBuffer -= bytes;
}
static int adtsSampleRates[] = {96000,88200,64000,48000,44100,32000,24000,22050,
16000,12000,11025,8000,7350,0,0,0};
static int adtsSampleRates[] =
{ 96000, 88200, 64000, 48000, 44100, 32000, 24000, 22050,
16000, 12000, 11025, 8000, 7350, 0, 0, 0
};
static int adtsParse(AacBuffer * b, float * length) {
static int adtsParse(AacBuffer * b, float *length)
{
int frames, frameLength;
int tFrameLength = 0;
int sampleRate = 0;
float framesPerSec, bytesPerFrame;
/* Read all frames to ensure correct time and bitrate */
for(frames = 0; ;frames++) {
for (frames = 0;; frames++) {
fillAacBuffer(b);
if(b->bytesIntoBuffer > 7) {
if (b->bytesIntoBuffer > 7) {
/* check syncword */
if (!((b->buffer[0] == 0xFF) &&
((b->buffer[1] & 0xF6) == 0xF0)))
{
if (!((b->buffer[0] == 0xFF) &&
((b->buffer[1] & 0xF6) == 0xF0))) {
break;
}
if(frames==0) {
sampleRate = adtsSampleRates[
(b->buffer[2]&0x3c)>>2];
if (frames == 0) {
sampleRate = adtsSampleRates[(b->
buffer[2] & 0x3c)
>> 2];
}
frameLength = ((((unsigned int)b->buffer[3] & 0x3))
<< 11) | (((unsigned int)b->buffer[4])
<< 3) | (b->buffer[5] >> 5);
frameLength = ((((unsigned int)b->buffer[3] & 0x3))
<< 11) | (((unsigned int)b->buffer[4])
<< 3) | (b->buffer[5] >> 5);
tFrameLength+=frameLength;
tFrameLength += frameLength;
if(frameLength > b->bytesIntoBuffer) break;
if (frameLength > b->bytesIntoBuffer)
break;
advanceAacBuffer(b,frameLength);
}
else break;
advanceAacBuffer(b, frameLength);
} else
break;
}
framesPerSec = (float)sampleRate/1024.0;
if(frames!=0) {
bytesPerFrame = (float)tFrameLength/(float)(frames*1000);
}
else bytesPerFrame = 0;
if(framesPerSec!=0) *length = (float)frames/framesPerSec;
framesPerSec = (float)sampleRate / 1024.0;
if (frames != 0) {
bytesPerFrame = (float)tFrameLength / (float)(frames * 1000);
} else
bytesPerFrame = 0;
if (framesPerSec != 0)
*length = (float)frames / framesPerSec;
return 1;
}
static void initAacBuffer(InputStream * inStream, AacBuffer * b, float * length,
size_t * retFileread, size_t * retTagsize)
static void initAacBuffer(InputStream * inStream, AacBuffer * b, float *length,
size_t * retFileread, size_t * retTagsize)
{
size_t fileread;
size_t bread;
size_t tagsize;
if(length) *length = -1;
if (length)
*length = -1;
memset(b,0,sizeof(AacBuffer));
memset(b, 0, sizeof(AacBuffer));
b->inStream = inStream;
fileread = inStream->size;
b->buffer = malloc(FAAD_MIN_STREAMSIZE*AAC_MAX_CHANNELS);
memset(b->buffer,0,FAAD_MIN_STREAMSIZE*AAC_MAX_CHANNELS);
b->buffer = malloc(FAAD_MIN_STREAMSIZE * AAC_MAX_CHANNELS);
memset(b->buffer, 0, FAAD_MIN_STREAMSIZE * AAC_MAX_CHANNELS);
bread = readFromInputStream(inStream,b->buffer,1,
FAAD_MIN_STREAMSIZE*AAC_MAX_CHANNELS);
bread = readFromInputStream(inStream, b->buffer, 1,
FAAD_MIN_STREAMSIZE * AAC_MAX_CHANNELS);
b->bytesIntoBuffer = bread;
b->bytesConsumed = 0;
b->fileOffset = 0;
if(bread!=FAAD_MIN_STREAMSIZE*AAC_MAX_CHANNELS) b->atEof = 1;
if (bread != FAAD_MIN_STREAMSIZE * AAC_MAX_CHANNELS)
b->atEof = 1;
tagsize = 0;
if(!memcmp(b->buffer,"ID3",3)) {
if (!memcmp(b->buffer, "ID3", 3)) {
tagsize = (b->buffer[6] << 21) | (b->buffer[7] << 14) |
(b->buffer[8] << 7) | (b->buffer[9] << 0);
(b->buffer[8] << 7) | (b->buffer[9] << 0);
tagsize+=10;
advanceAacBuffer(b,tagsize);
tagsize += 10;
advanceAacBuffer(b, tagsize);
fillAacBuffer(b);
}
if(retFileread) *retFileread = fileread;
if(retTagsize) *retTagsize = tagsize;
if (retFileread)
*retFileread = fileread;
if (retTagsize)
*retTagsize = tagsize;
if(length==NULL) return;
if (length == NULL)
return;
if((b->buffer[0] == 0xFF) && ((b->buffer[1] & 0xF6) == 0xF0)) {
if ((b->buffer[0] == 0xFF) && ((b->buffer[1] & 0xF6) == 0xF0)) {
adtsParse(b, length);
seekInputStream(b->inStream, tagsize, SEEK_SET);
bread = readFromInputStream(b->inStream, b->buffer, 1,
FAAD_MIN_STREAMSIZE*AAC_MAX_CHANNELS);
if(bread != FAAD_MIN_STREAMSIZE*AAC_MAX_CHANNELS) b->atEof = 1;
else b->atEof = 0;
bread = readFromInputStream(b->inStream, b->buffer, 1,
FAAD_MIN_STREAMSIZE *
AAC_MAX_CHANNELS);
if (bread != FAAD_MIN_STREAMSIZE * AAC_MAX_CHANNELS)
b->atEof = 1;
else
b->atEof = 0;
b->bytesIntoBuffer = bread;
b->bytesConsumed = 0;
b->fileOffset = tagsize;
}
else if(memcmp(b->buffer,"ADIF",4) == 0) {
} else if (memcmp(b->buffer, "ADIF", 4) == 0) {
int bitRate;
int skipSize = (b->buffer[4] & 0x80) ? 9 : 0;
bitRate = ((unsigned int)(b->buffer[4 + skipSize] & 0x0F)<<19) |
((unsigned int)b->buffer[5 + skipSize]<<11) |
((unsigned int)b->buffer[6 + skipSize]<<3) |
((unsigned int)b->buffer[7 + skipSize] & 0xE0);
bitRate =
((unsigned int)(b->
buffer[4 +
skipSize] & 0x0F) << 19) | ((unsigned
int)b->
buffer[5
+
skipSize]
<< 11) |
((unsigned int)b->
buffer[6 + skipSize] << 3) | ((unsigned int)b->buffer[7 +
skipSize]
& 0xE0);
*length = fileread;
if(*length!=0 && bitRate!=0) *length = *length*8.0/bitRate;
if (*length != 0 && bitRate != 0)
*length = *length * 8.0 / bitRate;
}
}
static float getAacFloatTotalTime(char * file) {
static float getAacFloatTotalTime(char *file)
{
AacBuffer b;
float length;
size_t fileread, tagsize;
@@ -211,46 +241,51 @@ static float getAacFloatTotalTime(char * file) {
InputStream inStream;
size_t bread;
if(openInputStream(&inStream,file) < 0) return -1;
if (openInputStream(&inStream, file) < 0)
return -1;
initAacBuffer(&inStream,&b,&length,&fileread,&tagsize);
initAacBuffer(&inStream, &b, &length, &fileread, &tagsize);
if(length < 0) {
if (length < 0) {
decoder = faacDecOpen();
config = faacDecGetCurrentConfiguration(decoder);
config->outputFormat = FAAD_FMT_16BIT;
faacDecSetConfiguration(decoder,config);
faacDecSetConfiguration(decoder, config);
fillAacBuffer(&b);
#ifdef HAVE_FAAD_BUFLEN_FUNCS
bread = faacDecInit(decoder,b.buffer,b.bytesIntoBuffer,
&sampleRate,&channels);
bread = faacDecInit(decoder, b.buffer, b.bytesIntoBuffer,
&sampleRate, &channels);
#else
bread = faacDecInit(decoder,b.buffer,&sampleRate,&channels);
bread = faacDecInit(decoder, b.buffer, &sampleRate, &channels);
#endif
if(bread >= 0 && sampleRate > 0 && channels > 0) length = 0;
if (bread >= 0 && sampleRate > 0 && channels > 0)
length = 0;
faacDecClose(decoder);
}
if(b.buffer) free(b.buffer);
if (b.buffer)
free(b.buffer);
closeInputStream(&inStream);
return length;
}
static int getAacTotalTime(char * file) {
static int getAacTotalTime(char *file)
{
int time = -1;
float length;
if((length = getAacFloatTotalTime(file))>=0) time = length+0.5;
if ((length = getAacFloatTotalTime(file)) >= 0)
time = length + 0.5;
return time;
}
static int aac_decode(OutputBuffer * cb, DecoderControl * dc, char * path) {
static int aac_decode(OutputBuffer * cb, DecoderControl * dc, char *path)
{
float time;
float totalTime;
faacDecHandle decoder;
@@ -261,20 +296,22 @@ static int aac_decode(OutputBuffer * cb, DecoderControl * dc, char * path) {
unsigned char channels;
int eof = 0;
unsigned int sampleCount;
char * sampleBuffer;
char *sampleBuffer;
size_t sampleBufferLen;
/*float * seekTable;
long seekTableEnd = -1;
int seekPositionFound = 0;*/
long seekTableEnd = -1;
int seekPositionFound = 0; */
mpd_uint16 bitRate = 0;
AacBuffer b;
InputStream inStream;
if((totalTime = getAacFloatTotalTime(path)) < 0) return -1;
if ((totalTime = getAacFloatTotalTime(path)) < 0)
return -1;
if(openInputStream(&inStream, path) < 0) return -1;
if (openInputStream(&inStream, path) < 0)
return -1;
initAacBuffer(&inStream,&b,NULL,NULL,NULL);
initAacBuffer(&inStream, &b, NULL, NULL, NULL);
decoder = faacDecOpen();
@@ -286,21 +323,22 @@ static int aac_decode(OutputBuffer * cb, DecoderControl * dc, char * path) {
#ifdef HAVE_FAACDECCONFIGURATION_DONTUPSAMPLEIMPLICITSBR
config->dontUpSampleImplicitSBR = 0;
#endif
faacDecSetConfiguration(decoder,config);
faacDecSetConfiguration(decoder, config);
fillAacBuffer(&b);
#ifdef HAVE_FAAD_BUFLEN_FUNCS
bread = faacDecInit(decoder,b.buffer,b.bytesIntoBuffer,
&sampleRate,&channels);
bread = faacDecInit(decoder, b.buffer, b.bytesIntoBuffer,
&sampleRate, &channels);
#else
bread = faacDecInit(decoder,b.buffer,&sampleRate,&channels);
bread = faacDecInit(decoder, b.buffer, &sampleRate, &channels);
#endif
if(bread < 0) {
if (bread < 0) {
ERROR("Error not a AAC stream.\n");
faacDecClose(decoder);
closeInputStream(b.inStream);
if(b.buffer) free(b.buffer);
if (b.buffer)
free(b.buffer);
return -1;
}
@@ -310,64 +348,62 @@ static int aac_decode(OutputBuffer * cb, DecoderControl * dc, char * path) {
time = 0.0;
advanceAacBuffer(&b,bread);
advanceAacBuffer(&b, bread);
while(!eof) {
while (!eof) {
fillAacBuffer(&b);
if(b.bytesIntoBuffer==0) {
if (b.bytesIntoBuffer == 0) {
eof = 1;
break;
}
#ifdef HAVE_FAAD_BUFLEN_FUNCS
sampleBuffer = faacDecDecode(decoder,&frameInfo,b.buffer,
b.bytesIntoBuffer);
sampleBuffer = faacDecDecode(decoder, &frameInfo, b.buffer,
b.bytesIntoBuffer);
#else
sampleBuffer = faacDecDecode(decoder,&frameInfo,b.buffer);
sampleBuffer = faacDecDecode(decoder, &frameInfo, b.buffer);
#endif
if(frameInfo.error > 0) {
if (frameInfo.error > 0) {
ERROR("error decoding AAC file: %s\n", path);
ERROR("faad2 error: %s\n",
faacDecGetErrorMessage(frameInfo.error));
faacDecGetErrorMessage(frameInfo.error));
eof = 1;
break;
}
#ifdef HAVE_FAACDECFRAMEINFO_SAMPLERATE
sampleRate = frameInfo.samplerate;
#endif
if(dc->state != DECODE_STATE_DECODE) {
if (dc->state != DECODE_STATE_DECODE) {
dc->audioFormat.channels = frameInfo.channels;
dc->audioFormat.sampleRate = sampleRate;
getOutputAudioFormat(&(dc->audioFormat),
&(cb->audioFormat));
getOutputAudioFormat(&(dc->audioFormat),
&(cb->audioFormat));
dc->state = DECODE_STATE_DECODE;
}
advanceAacBuffer(&b,frameInfo.bytesconsumed);
advanceAacBuffer(&b, frameInfo.bytesconsumed);
sampleCount = (unsigned long)(frameInfo.samples);
if(sampleCount>0) {
bitRate = frameInfo.bytesconsumed*8.0*
frameInfo.channels*sampleRate/
frameInfo.samples/1000+0.5;
time+= (float)(frameInfo.samples)/frameInfo.channels/
sampleRate;
if (sampleCount > 0) {
bitRate = frameInfo.bytesconsumed * 8.0 *
frameInfo.channels * sampleRate /
frameInfo.samples / 1000 + 0.5;
time +=
(float)(frameInfo.samples) / frameInfo.channels /
sampleRate;
}
sampleBufferLen = sampleCount*2;
sampleBufferLen = sampleCount * 2;
sendDataToOutputBuffer(cb, NULL, dc, 0, sampleBuffer,
sampleBufferLen, time, bitRate, NULL);
if(dc->seek) {
dc->seekError = 1;
dc->seek = 0;
}
else if(dc->stop) {
sampleBufferLen, time, bitRate, NULL);
if (dc->seek) {
dc->seekError = 1;
dc->seek = 0;
} else if (dc->stop) {
eof = 1;
break;
}
@@ -377,71 +413,73 @@ static int aac_decode(OutputBuffer * cb, DecoderControl * dc, char * path) {
faacDecClose(decoder);
closeInputStream(b.inStream);
if(b.buffer) free(b.buffer);
if (b.buffer)
free(b.buffer);
if(dc->state != DECODE_STATE_DECODE) return -1;
if (dc->state != DECODE_STATE_DECODE)
return -1;
if(dc->seek) {
dc->seekError = 1;
dc->seek = 0;
}
if (dc->seek) {
dc->seekError = 1;
dc->seek = 0;
}
if(dc->stop) {
if (dc->stop) {
dc->state = DECODE_STATE_STOP;
dc->stop = 0;
}
else dc->state = DECODE_STATE_STOP;
} else
dc->state = DECODE_STATE_STOP;
return 0;
}
static MpdTag * aacTagDup(char * file) {
MpdTag * ret = NULL;
static MpdTag *aacTagDup(char *file)
{
MpdTag *ret = NULL;
int time;
time = getAacTotalTime(file);
if(time>=0) {
if((ret = id3Dup(file))==NULL) ret = newMpdTag();
if (time >= 0) {
if ((ret = id3Dup(file)) == NULL)
ret = newMpdTag();
ret->time = time;
}
else {
DEBUG("aacTagDup: Failed to get total song time from: %s\n", file);
} else {
DEBUG("aacTagDup: Failed to get total song time from: %s\n",
file);
}
return ret;
}
static char * aacSuffixes[] = {"aac", NULL};
static char *aacSuffixes[] = { "aac", NULL };
InputPlugin aacPlugin =
{
"aac",
NULL,
NULL,
InputPlugin aacPlugin = {
"aac",
NULL,
NULL,
aac_decode,
aacTagDup,
INPUT_PLUGIN_STREAM_FILE,
aacSuffixes,
NULL
NULL,
NULL,
aac_decode,
aacTagDup,
INPUT_PLUGIN_STREAM_FILE,
aacSuffixes,
NULL
};
#else
InputPlugin aacPlugin =
{
NULL,
NULL,
NULL,
NULL,
NULL,
InputPlugin aacPlugin = {
NULL,
NULL,
NULL,
NULL,
NULL,
NULL,
NULL,
0,
NULL,
NULL,
0,
NULL,
NULL,
};
#endif /* HAVE_FAAD */
#endif /* HAVE_FAAD */

View File

@@ -37,34 +37,35 @@
#include <unistd.h>
#include <audiofile.h>
static int getAudiofileTotalTime(char * file)
static int getAudiofileTotalTime(char *file)
{
int time;
AFfilehandle af_fp = afOpenFile(file, "r", NULL);
if(af_fp == AF_NULL_FILEHANDLE) {
if (af_fp == AF_NULL_FILEHANDLE) {
return -1;
}
time = (int)
((double)afGetFrameCount(af_fp,AF_DEFAULT_TRACK)
/afGetRate(af_fp,AF_DEFAULT_TRACK));
((double)afGetFrameCount(af_fp, AF_DEFAULT_TRACK)
/ afGetRate(af_fp, AF_DEFAULT_TRACK));
afCloseFile(af_fp);
return time;
}
static int audiofile_decode(OutputBuffer * cb, DecoderControl * dc, char * path) {
static int audiofile_decode(OutputBuffer * cb, DecoderControl * dc, char *path)
{
int fs, frame_count;
AFfilehandle af_fp;
int bits;
mpd_uint16 bitRate;
struct stat st;
if(stat(path, &st) < 0) {
if (stat(path, &st) < 0) {
ERROR("failed to stat: %s\n", path);
return -1;
}
af_fp = afOpenFile(path, "r", NULL);
if(af_fp == AF_NULL_FILEHANDLE) {
if (af_fp == AF_NULL_FILEHANDLE) {
ERROR("failed to open: %s\n", path);
return -1;
}
@@ -72,119 +73,125 @@ static int audiofile_decode(OutputBuffer * cb, DecoderControl * dc, char * path)
afGetSampleFormat(af_fp, AF_DEFAULT_TRACK, &fs, &bits);
dc->audioFormat.bits = bits;
dc->audioFormat.sampleRate = afGetRate(af_fp, AF_DEFAULT_TRACK);
dc->audioFormat.channels = afGetChannels(af_fp,AF_DEFAULT_TRACK);
getOutputAudioFormat(&(dc->audioFormat),&(cb->audioFormat));
frame_count = afGetFrameCount(af_fp,AF_DEFAULT_TRACK);
dc->totalTime = ((float)frame_count/(float)dc->audioFormat.sampleRate);
dc->audioFormat.channels = afGetChannels(af_fp, AF_DEFAULT_TRACK);
getOutputAudioFormat(&(dc->audioFormat), &(cb->audioFormat));
frame_count = afGetFrameCount(af_fp, AF_DEFAULT_TRACK);
dc->totalTime =
((float)frame_count / (float)dc->audioFormat.sampleRate);
bitRate = st.st_size * 8.0 / dc->totalTime / 1000.0 + 0.5;
bitRate = st.st_size*8.0/dc->totalTime/1000.0+0.5;
if (dc->audioFormat.bits != 8 && dc->audioFormat.bits != 16) {
ERROR("Only 8 and 16-bit files are supported. %s is %i-bit\n",
path, dc->audioFormat.bits);
path, dc->audioFormat.bits);
afCloseFile(af_fp);
return -1;
}
fs = (int)afGetFrameSize(af_fp, AF_DEFAULT_TRACK,1);
fs = (int)afGetFrameSize(af_fp, AF_DEFAULT_TRACK, 1);
dc->state = DECODE_STATE_DECODE;
{
int ret, eof = 0, current = 0;
char chunk[CHUNK_SIZE];
while(!eof) {
if(dc->seek) {
clearOutputBuffer(cb);
current = dc->seekWhere *
dc->audioFormat.sampleRate;
afSeekFrame(af_fp, AF_DEFAULT_TRACK,current);
while (!eof) {
if (dc->seek) {
clearOutputBuffer(cb);
current = dc->seekWhere *
dc->audioFormat.sampleRate;
afSeekFrame(af_fp, AF_DEFAULT_TRACK, current);
dc->seek = 0;
}
ret = afReadFrames(af_fp, AF_DEFAULT_TRACK, chunk, CHUNK_SIZE/fs);
if(ret<=0) eof = 1;
ret =
afReadFrames(af_fp, AF_DEFAULT_TRACK, chunk,
CHUNK_SIZE / fs);
if (ret <= 0)
eof = 1;
else {
current += ret;
sendDataToOutputBuffer(cb,
NULL,
dc,
1,
chunk,
ret*fs,
(float)current /
(float)dc->audioFormat.sampleRate,
bitRate,
NULL);
if(dc->stop) break;
sendDataToOutputBuffer(cb,
NULL,
dc,
1,
chunk,
ret * fs,
(float)current /
(float)dc->audioFormat.
sampleRate, bitRate,
NULL);
if (dc->stop)
break;
}
}
flushOutputBuffer(cb);
/*if(dc->seek) {
dc->seekError = 1;
dc->seek = 0;
}*/
dc->seekError = 1;
dc->seek = 0;
} */
if(dc->stop) {
if (dc->stop) {
dc->state = DECODE_STATE_STOP;
dc->stop = 0;
}
else dc->state = DECODE_STATE_STOP;
} else
dc->state = DECODE_STATE_STOP;
}
afCloseFile(af_fp);
return 0;
}
static MpdTag * audiofileTagDup(char * file) {
MpdTag * ret = NULL;
static MpdTag *audiofileTagDup(char *file)
{
MpdTag *ret = NULL;
int time = getAudiofileTotalTime(file);
if (time>=0) {
if(!ret) ret = newMpdTag();
if (time >= 0) {
if (!ret)
ret = newMpdTag();
ret->time = time;
}
else {
DEBUG("audiofileTagDup: Failed to get total song time from: %s\n", file);
} else {
DEBUG
("audiofileTagDup: Failed to get total song time from: %s\n",
file);
}
return ret;
}
static char * audiofileSuffixes[] = {"wav", "au", "aiff", "aif", NULL};
static char *audiofileSuffixes[] = { "wav", "au", "aiff", "aif", NULL };
InputPlugin audiofilePlugin =
{
"audiofile",
NULL,
InputPlugin audiofilePlugin = {
"audiofile",
NULL,
NULL,
NULL,
audiofile_decode,
audiofileTagDup,
INPUT_PLUGIN_STREAM_FILE,
audiofileSuffixes,
NULL
NULL,
audiofile_decode,
audiofileTagDup,
INPUT_PLUGIN_STREAM_FILE,
audiofileSuffixes,
NULL
};
#else
InputPlugin audiofilePlugin =
{
NULL,
NULL,
NULL,
NULL,
NULL,
InputPlugin audiofilePlugin = {
NULL,
NULL,
0,
NULL,
NULL
NULL,
NULL,
NULL,
NULL,
NULL,
0,
NULL,
NULL
};
#endif /* HAVE_AUDIOFILE */
#endif /* HAVE_AUDIOFILE */

View File

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

View File

@@ -39,23 +39,26 @@
#define MIKMOD_FRAME_SIZE 4096
static BOOL mod_mpd_Init(void) {
static BOOL mod_mpd_Init(void)
{
return VC_Init();
}
static void mod_mpd_Exit(void) {
static void mod_mpd_Exit(void)
{
VC_Exit();
}
static void mod_mpd_Update(void) {
static void mod_mpd_Update(void)
{
}
static BOOL mod_mpd_IsThere(void) {
static BOOL mod_mpd_IsThere(void)
{
return 1;
}
static MDRIVER drv_mpd =
{
static MDRIVER drv_mpd = {
NULL,
"MPD",
"MPD Output Driver v0.1",
@@ -92,10 +95,12 @@ static MDRIVER drv_mpd =
static int mod_mikModInitiated = 0;
static int mod_mikModInitError = 0;
static int mod_initMikMod(void) {
if(mod_mikModInitError) return -1;
static int mod_initMikMod(void)
{
if (mod_mikModInitError)
return -1;
if(!mod_mikModInitiated) {
if (!mod_mikModInitiated) {
mod_mikModInitiated = 1;
md_device = 0;
@@ -108,11 +113,11 @@ static int mod_initMikMod(void) {
md_pansep = 64;
md_mixfreq = 44100;
md_mode = (DMODE_SOFT_MUSIC | DMODE_INTERP | DMODE_STEREO |
DMODE_16BITS);
DMODE_16BITS);
if(MikMod_Init("")) {
ERROR("Could not init MikMod: %s\n",
MikMod_strerror(MikMod_errno));
if (MikMod_Init("")) {
ERROR("Could not init MikMod: %s\n",
MikMod_strerror(MikMod_errno));
mod_mikModInitError = 1;
return -1;
}
@@ -120,20 +125,23 @@ static int mod_initMikMod(void) {
return 0;
}
static void mod_finishMikMod(void) {
static void mod_finishMikMod(void)
{
MikMod_Exit();
}
typedef struct _mod_Data {
MODULE * moduleHandle;
SBYTE * audio_buffer;
} mod_Data;
MODULE *moduleHandle;
SBYTE *audio_buffer;
} mod_Data;
static mod_Data * mod_open(char * path) {
MODULE * moduleHandle;
mod_Data * data;
static mod_Data *mod_open(char *path)
{
MODULE *moduleHandle;
mod_Data *data;
if(!(moduleHandle = Player_Load(path, 128, 0))) return NULL;
if (!(moduleHandle = Player_Load(path, 128, 0)))
return NULL;
data = malloc(sizeof(mod_Data));
@@ -145,51 +153,57 @@ static mod_Data * mod_open(char * path) {
return data;
}
static void mod_close(mod_Data * data) {
static void mod_close(mod_Data * data)
{
Player_Stop();
Player_Free(data->moduleHandle);
free(data->audio_buffer);
free(data);
}
static int mod_decode(OutputBuffer * cb, DecoderControl * dc, char * path) {
mod_Data * data;
static int mod_decode(OutputBuffer * cb, DecoderControl * dc, char *path)
{
mod_Data *data;
float time = 0.0;
int ret;
float secPerByte;
if(mod_initMikMod() < 0) return -1;
if (mod_initMikMod() < 0)
return -1;
if(!(data = mod_open(path))) {
if (!(data = mod_open(path))) {
ERROR("failed to open mod: %s\n", path);
MikMod_Exit();
return -1;
}
dc->audioFormat.bits = 16;
dc->audioFormat.sampleRate = 44100;
dc->audioFormat.channels = 2;
getOutputAudioFormat(&(dc->audioFormat),&(cb->audioFormat));
getOutputAudioFormat(&(dc->audioFormat), &(cb->audioFormat));
secPerByte =
1.0 / ((dc->audioFormat.bits * dc->audioFormat.channels / 8.0) *
(float)dc->audioFormat.sampleRate);
secPerByte = 1.0/((dc->audioFormat.bits*dc->audioFormat.channels/8.0)*
(float)dc->audioFormat.sampleRate);
dc->state = DECODE_STATE_DECODE;
while(1) {
if(dc->seek) {
while (1) {
if (dc->seek) {
dc->seekError = 1;
dc->seek = 0;
}
if(dc->stop) break;
if (dc->stop)
break;
if(!Player_Active()) break;
if (!Player_Active())
break;
ret = VC_WriteBytes(data->audio_buffer, MIKMOD_FRAME_SIZE);
time += ret*secPerByte;
sendDataToOutputBuffer(cb, NULL, dc, 0,
(char *)data->audio_buffer, ret, time,
0, NULL);
time += ret * secPerByte;
sendDataToOutputBuffer(cb, NULL, dc, 0,
(char *)data->audio_buffer, ret, time,
0, NULL);
}
flushOutputBuffer(cb);
@@ -198,27 +212,28 @@ static int mod_decode(OutputBuffer * cb, DecoderControl * dc, char * path) {
MikMod_Exit();
if(dc->stop) {
if (dc->stop) {
dc->state = DECODE_STATE_STOP;
dc->stop = 0;
}
else dc->state = DECODE_STATE_STOP;
} else
dc->state = DECODE_STATE_STOP;
return 0;
}
static MpdTag * modTagDup(char * file) {
MpdTag * ret = NULL;
MODULE * moduleHandle;
char * title;
static MpdTag *modTagDup(char *file)
{
MpdTag *ret = NULL;
MODULE *moduleHandle;
char *title;
if(mod_initMikMod() < 0) {
if (mod_initMikMod() < 0) {
DEBUG("modTagDup: Failed to initialize MikMod\n");
return NULL;
}
if(!(moduleHandle = Player_Load(file, 128, 0))) {
DEBUG("modTagDup: Failed to open file: %s\n",file);
if (!(moduleHandle = Player_Load(file, 128, 0))) {
DEBUG("modTagDup: Failed to open file: %s\n", file);
MikMod_Exit();
return NULL;
@@ -229,58 +244,58 @@ static MpdTag * modTagDup(char * file) {
ret->time = 0;
title = strdup(Player_LoadTitle(file));
if(title) addItemToMpdTag(ret, TAG_ITEM_TITLE, title);
if (title)
addItemToMpdTag(ret, TAG_ITEM_TITLE, title);
MikMod_Exit();
return ret;
}
static char * modSuffixes[] = {"amf",
"dsm",
"far",
"gdm",
"imf",
"it",
"med",
"mod",
"mtm",
"s3m",
"stm",
"stx",
"ult",
"uni",
"xm",
NULL};
static char *modSuffixes[] = { "amf",
"dsm",
"far",
"gdm",
"imf",
"it",
"med",
"mod",
"mtm",
"s3m",
"stm",
"stx",
"ult",
"uni",
"xm",
NULL
};
InputPlugin modPlugin =
{
"mod",
NULL,
InputPlugin modPlugin = {
"mod",
NULL,
mod_finishMikMod,
NULL,
NULL,
mod_decode,
modTagDup,
INPUT_PLUGIN_STREAM_FILE,
modSuffixes,
NULL
mod_decode,
modTagDup,
INPUT_PLUGIN_STREAM_FILE,
modSuffixes,
NULL
};
#else
InputPlugin modPlugin =
{
NULL,
NULL,
NULL,
NULL,
NULL,
InputPlugin modPlugin = {
NULL,
NULL,
0,
NULL,
NULL
NULL,
NULL,
NULL,
NULL,
NULL,
0,
NULL,
NULL
};
#endif /* HAVE_AUDIOFILE */
#endif /* HAVE_AUDIOFILE */

File diff suppressed because it is too large Load Diff

View File

@@ -37,7 +37,8 @@
/* all code here is either based on or copied from FAAD2's frontend code */
static int mp4_getAACTrack(mp4ff_t *infile) {
static int mp4_getAACTrack(mp4ff_t * infile)
{
/* find AAC track */
int i, rc;
int numTracks = mp4ff_total_tracks(infile);
@@ -50,9 +51,9 @@ static int mp4_getAACTrack(mp4ff_t *infile) {
#else
unsigned long dummy1_32;
unsigned char dummy2_8, dummy3_8, dummy4_8, dummy5_8, dummy6_8,
dummy7_8, dummy8_8;
dummy7_8, dummy8_8;
#endif
mp4ff_get_decoder_config(infile, i, &buff, buff_size);
if (buff) {
@@ -60,11 +61,13 @@ static int mp4_getAACTrack(mp4ff_t *infile) {
rc = AudioSpecificConfig(buff, *buff_size, &mp4ASC);
#else
rc = AudioSpecificConfig(buff, &dummy1_32, &dummy2_8,
&dummy3_8, &dummy4_8, &dummy5_8,
&dummy6_8, &dummy7_8, &dummy8_8);
&dummy3_8, &dummy4_8,
&dummy5_8, &dummy6_8,
&dummy7_8, &dummy8_8);
#endif
free(buff);
if (rc < 0) continue;
if (rc < 0)
continue;
return i;
}
}
@@ -74,16 +77,18 @@ static int mp4_getAACTrack(mp4ff_t *infile) {
}
static uint32_t mp4_inputStreamReadCallback(void *inStream, void *buffer,
uint32_t length)
uint32_t length)
{
return readFromInputStream((InputStream*) inStream, buffer, 1, length);
return readFromInputStream((InputStream *) inStream, buffer, 1, length);
}
static uint32_t mp4_inputStreamSeekCallback(void *inStream, uint64_t position) {
static uint32_t mp4_inputStreamSeekCallback(void *inStream, uint64_t position)
{
return seekInputStream((InputStream *) inStream, position, SEEK_SET);
}
static faacDecHandle * openConfigureFaad() {
static faacDecHandle *openConfigureFaad()
{
faacDecConfigurationPtr config;
faacDecHandle decoder = faacDecOpen();
@@ -95,20 +100,21 @@ static faacDecHandle * openConfigureFaad() {
#ifdef HAVE_FAACDECCONFIGURATION_DONTUPSAMPLEIMPLICITSBR
config->dontUpSampleImplicitSBR = 0;
#endif
faacDecSetConfiguration(decoder,config);
faacDecSetConfiguration(decoder, config);
return decoder;
}
static int mp4_decode(OutputBuffer * cb, DecoderControl * dc, char * path) {
mp4ff_t * mp4fh;
mp4ff_callback_t * mp4cb;
static int mp4_decode(OutputBuffer * cb, DecoderControl * dc, char *path)
{
mp4ff_t *mp4fh;
mp4ff_callback_t *mp4cb;
int32_t track;
float time;
int32_t scale;
faacDecHandle * decoder;
faacDecHandle *decoder;
faacDecFrameInfo frameInfo;
unsigned char * mp4Buffer;
unsigned char *mp4Buffer;
unsigned int mp4BufferSize;
uint32_t sampleRate;
unsigned char channels;
@@ -117,10 +123,10 @@ static int mp4_decode(OutputBuffer * cb, DecoderControl * dc, char * path) {
int eof = 0;
long dur;
unsigned int sampleCount;
char * sampleBuffer;
char *sampleBuffer;
size_t sampleBufferLen;
unsigned int initial = 1;
float * seekTable;
float *seekTable;
long seekTableEnd = -1;
int seekPositionFound = 0;
long offset;
@@ -128,7 +134,7 @@ static int mp4_decode(OutputBuffer * cb, DecoderControl * dc, char * path) {
InputStream inStream;
int seeking = 0;
if(openInputStream(&inStream, path) < 0) {
if (openInputStream(&inStream, path) < 0) {
ERROR("failed to open %s\n", path);
return -1;
}
@@ -139,7 +145,7 @@ static int mp4_decode(OutputBuffer * cb, DecoderControl * dc, char * path) {
mp4cb->user_data = &inStream;
mp4fh = mp4ff_open_read(mp4cb);
if(!mp4fh) {
if (!mp4fh) {
ERROR("Input does not appear to be a mp4 stream.\n");
free(mp4cb);
closeInputStream(&inStream);
@@ -147,7 +153,7 @@ static int mp4_decode(OutputBuffer * cb, DecoderControl * dc, char * path) {
}
track = mp4_getAACTrack(mp4fh);
if(track < 0) {
if (track < 0) {
ERROR("No AAC track found in mp4 stream.\n");
mp4ff_close(mp4fh);
closeInputStream(&inStream);
@@ -161,11 +167,11 @@ static int mp4_decode(OutputBuffer * cb, DecoderControl * dc, char * path) {
mp4Buffer = NULL;
mp4BufferSize = 0;
mp4ff_get_decoder_config(mp4fh,track,&mp4Buffer,&mp4BufferSize);
mp4ff_get_decoder_config(mp4fh, track, &mp4Buffer, &mp4BufferSize);
if(faacDecInit2(decoder,mp4Buffer,mp4BufferSize,&sampleRate,&channels)
< 0)
{
if (faacDecInit2
(decoder, mp4Buffer, mp4BufferSize, &sampleRate, &channels)
< 0) {
ERROR("Error not a AAC stream.\n");
faacDecClose(decoder);
mp4ff_close(mp4fh);
@@ -176,12 +182,13 @@ static int mp4_decode(OutputBuffer * cb, DecoderControl * dc, char * path) {
dc->audioFormat.sampleRate = sampleRate;
dc->audioFormat.channels = channels;
time = mp4ff_get_track_duration_use_offsets(mp4fh,track);
scale = mp4ff_time_scale(mp4fh,track);
time = mp4ff_get_track_duration_use_offsets(mp4fh, track);
scale = mp4ff_time_scale(mp4fh, track);
if(mp4Buffer) free(mp4Buffer);
if (mp4Buffer)
free(mp4Buffer);
if(scale < 0) {
if (scale < 0) {
ERROR("Error getting audio format of mp4 AAC track.\n");
faacDecClose(decoder);
mp4ff_close(mp4fh);
@@ -189,107 +196,111 @@ static int mp4_decode(OutputBuffer * cb, DecoderControl * dc, char * path) {
free(mp4cb);
return -1;
}
dc->totalTime = ((float)time)/scale;
dc->totalTime = ((float)time) / scale;
numSamples = mp4ff_num_samples(mp4fh,track);
numSamples = mp4ff_num_samples(mp4fh, track);
time = 0.0;
seekTable = malloc(sizeof(float)*numSamples);
seekTable = malloc(sizeof(float) * numSamples);
for(sampleId=0; sampleId<numSamples && !eof; sampleId++) {
if(dc->seek) seeking = 1;
for (sampleId = 0; sampleId < numSamples && !eof; sampleId++) {
if (dc->seek)
seeking = 1;
if(seeking && seekTableEnd>1 &&
seekTable[seekTableEnd]>=dc->seekWhere)
{
if (seeking && seekTableEnd > 1 &&
seekTable[seekTableEnd] >= dc->seekWhere) {
int i = 2;
while(seekTable[i]<dc->seekWhere) i++;
sampleId = i-1;
while (seekTable[i] < dc->seekWhere)
i++;
sampleId = i - 1;
time = seekTable[sampleId];
}
dur = mp4ff_get_sample_duration(mp4fh,track,sampleId);
offset = mp4ff_get_sample_offset(mp4fh,track,sampleId);
dur = mp4ff_get_sample_duration(mp4fh, track, sampleId);
offset = mp4ff_get_sample_offset(mp4fh, track, sampleId);
if(sampleId>seekTableEnd) {
if (sampleId > seekTableEnd) {
seekTable[sampleId] = time;
seekTableEnd = sampleId;
}
if(sampleId==0) dur = 0;
if(offset>dur) dur = 0;
else dur-=offset;
time+=((float)dur)/scale;
if (sampleId == 0)
dur = 0;
if (offset > dur)
dur = 0;
else
dur -= offset;
time += ((float)dur) / scale;
if(seeking && time>dc->seekWhere) seekPositionFound = 1;
if (seeking && time > dc->seekWhere)
seekPositionFound = 1;
if(seeking && seekPositionFound) {
if (seeking && seekPositionFound) {
seekPositionFound = 0;
clearOutputBuffer(cb);
clearOutputBuffer(cb);
seeking = 0;
dc->seek = 0;
}
if(seeking) continue;
if(mp4ff_read_sample(mp4fh,track,sampleId,&mp4Buffer,
&mp4BufferSize) == 0)
{
if (seeking)
continue;
if (mp4ff_read_sample(mp4fh, track, sampleId, &mp4Buffer,
&mp4BufferSize) == 0) {
eof = 1;
continue;
}
#ifdef HAVE_FAAD_BUFLEN_FUNCS
sampleBuffer = faacDecDecode(decoder,&frameInfo,mp4Buffer,
mp4BufferSize);
sampleBuffer = faacDecDecode(decoder, &frameInfo, mp4Buffer,
mp4BufferSize);
#else
sampleBuffer = faacDecDecode(decoder,&frameInfo,mp4Buffer);
sampleBuffer = faacDecDecode(decoder, &frameInfo, mp4Buffer);
#endif
if(mp4Buffer) free(mp4Buffer);
if(frameInfo.error > 0) {
if (mp4Buffer)
free(mp4Buffer);
if (frameInfo.error > 0) {
ERROR("error decoding MP4 file: %s\n", path);
ERROR("faad2 error: %s\n",
faacDecGetErrorMessage(frameInfo.error));
faacDecGetErrorMessage(frameInfo.error));
eof = 1;
break;
}
if(dc->state != DECODE_STATE_DECODE) {
if (dc->state != DECODE_STATE_DECODE) {
channels = frameInfo.channels;
#ifdef HAVE_FAACDECFRAMEINFO_SAMPLERATE
scale = frameInfo.samplerate;
#endif
dc->audioFormat.sampleRate = scale;
dc->audioFormat.channels = frameInfo.channels;
getOutputAudioFormat(&(dc->audioFormat),
&(cb->audioFormat));
getOutputAudioFormat(&(dc->audioFormat),
&(cb->audioFormat));
dc->state = DECODE_STATE_DECODE;
}
if(channels*(dur+offset) > frameInfo.samples) {
dur = frameInfo.samples/channels;
if (channels * (dur + offset) > frameInfo.samples) {
dur = frameInfo.samples / channels;
offset = 0;
}
sampleCount = (unsigned long)(dur*channels);
sampleCount = (unsigned long)(dur * channels);
if(sampleCount>0) {
initial =0;
bitRate = frameInfo.bytesconsumed*8.0*
frameInfo.channels*scale/
frameInfo.samples/1000+0.5;
if (sampleCount > 0) {
initial = 0;
bitRate = frameInfo.bytesconsumed * 8.0 *
frameInfo.channels * scale /
frameInfo.samples / 1000 + 0.5;
}
sampleBufferLen = sampleCount*2;
sampleBufferLen = sampleCount * 2;
sampleBuffer+=offset*channels*2;
sampleBuffer += offset * channels * 2;
sendDataToOutputBuffer(cb, NULL, dc, 1, sampleBuffer,
sampleBufferLen, time, bitRate, NULL);
if(dc->stop) {
sampleBufferLen, time, bitRate, NULL);
if (dc->stop) {
eof = 1;
break;
}
@@ -301,33 +312,36 @@ static int mp4_decode(OutputBuffer * cb, DecoderControl * dc, char * path) {
closeInputStream(&inStream);
free(mp4cb);
if(dc->state != DECODE_STATE_DECODE) return -1;
if (dc->state != DECODE_STATE_DECODE)
return -1;
if(dc->seek && seeking) {
clearOutputBuffer(cb);
dc->seek = 0;
}
if (dc->seek && seeking) {
clearOutputBuffer(cb);
dc->seek = 0;
}
flushOutputBuffer(cb);
if(dc->stop) dc->stop = 0;
if (dc->stop)
dc->stop = 0;
dc->state = DECODE_STATE_STOP;
return 0;
}
static MpdTag * mp4DataDup(char * file, int * mp4MetadataFound) {
MpdTag * ret = NULL;
static MpdTag *mp4DataDup(char *file, int *mp4MetadataFound)
{
MpdTag *ret = NULL;
InputStream inStream;
mp4ff_t * mp4fh;
mp4ff_callback_t * cb;
mp4ff_t *mp4fh;
mp4ff_callback_t *cb;
int32_t track;
int32_t time;
int32_t scale;
int i;
*mp4MetadataFound = 0;
if(openInputStream(&inStream, file) < 0) {
if (openInputStream(&inStream, file) < 0) {
DEBUG("mp4DataDup: Failed to open file: %s\n", file);
return NULL;
}
@@ -338,14 +352,14 @@ static MpdTag * mp4DataDup(char * file, int * mp4MetadataFound) {
cb->user_data = &inStream;
mp4fh = mp4ff_open_read(cb);
if(!mp4fh) {
if (!mp4fh) {
free(cb);
closeInputStream(&inStream);
return NULL;
}
track = mp4_getAACTrack(mp4fh);
if(track < 0) {
if (track < 0) {
mp4ff_close(mp4fh);
closeInputStream(&inStream);
free(cb);
@@ -353,48 +367,42 @@ static MpdTag * mp4DataDup(char * file, int * mp4MetadataFound) {
}
ret = newMpdTag();
time = mp4ff_get_track_duration_use_offsets(mp4fh,track);
scale = mp4ff_time_scale(mp4fh,track);
if(scale < 0) {
time = mp4ff_get_track_duration_use_offsets(mp4fh, track);
scale = mp4ff_time_scale(mp4fh, track);
if (scale < 0) {
mp4ff_close(mp4fh);
closeInputStream(&inStream);
free(cb);
freeMpdTag(ret);
return NULL;
}
ret->time = ((float)time)/scale+0.5;
ret->time = ((float)time) / scale + 0.5;
for(i = 0; i < mp4ff_meta_get_num_items(mp4fh); i++) {
char * item;
char * value;
for (i = 0; i < mp4ff_meta_get_num_items(mp4fh); i++) {
char *item;
char *value;
mp4ff_meta_get_by_index(mp4fh, i, &item, &value);
if(0 == strcasecmp("artist", item)) {
if (0 == strcasecmp("artist", item)) {
addItemToMpdTag(ret, TAG_ITEM_ARTIST, value);
*mp4MetadataFound = 1;
}
else if(0 == strcasecmp("title", item)) {
} else if (0 == strcasecmp("title", item)) {
addItemToMpdTag(ret, TAG_ITEM_TITLE, value);
*mp4MetadataFound = 1;
}
else if(0 == strcasecmp("album", item)) {
} else if (0 == strcasecmp("album", item)) {
addItemToMpdTag(ret, TAG_ITEM_ALBUM, value);
*mp4MetadataFound = 1;
}
else if(0 == strcasecmp("track", item)) {
} else if (0 == strcasecmp("track", item)) {
addItemToMpdTag(ret, TAG_ITEM_TRACK, value);
*mp4MetadataFound = 1;
}
else if(0 == strcasecmp("disc", item)) { /* Is that the correct id? */
} else if (0 == strcasecmp("disc", item)) { /* Is that the correct id? */
addItemToMpdTag(ret, TAG_ITEM_DISC, value);
*mp4MetadataFound = 1;
}
else if(0 == strcasecmp("genre", item)) {
} else if (0 == strcasecmp("genre", item)) {
addItemToMpdTag(ret, TAG_ITEM_GENRE, value);
*mp4MetadataFound = 1;
}
else if(0 == strcasecmp("date", item)) {
} else if (0 == strcasecmp("date", item)) {
addItemToMpdTag(ret, TAG_ITEM_DATE, value);
*mp4MetadataFound = 1;
}
@@ -410,15 +418,17 @@ static MpdTag * mp4DataDup(char * file, int * mp4MetadataFound) {
return ret;
}
static MpdTag * mp4TagDup(char * file) {
MpdTag * ret = NULL;
static MpdTag *mp4TagDup(char *file)
{
MpdTag *ret = NULL;
int mp4MetadataFound = 0;
ret = mp4DataDup(file, &mp4MetadataFound);
if(!ret) return NULL;
if(!mp4MetadataFound) {
MpdTag * temp = id3Dup(file);
if(temp) {
if (!ret)
return NULL;
if (!mp4MetadataFound) {
MpdTag *temp = id3Dup(file);
if (temp) {
temp->time = ret->time;
freeMpdTag(ret);
ret = temp;
@@ -428,10 +438,9 @@ static MpdTag * mp4TagDup(char * file) {
return ret;
}
static char * mp4Suffixes[] = {"m4a", "mp4", NULL};
static char *mp4Suffixes[] = { "m4a", "mp4", NULL };
InputPlugin mp4Plugin =
{
InputPlugin mp4Plugin = {
"mp4",
NULL,
NULL,
@@ -446,8 +455,7 @@ InputPlugin mp4Plugin =
#else
InputPlugin mp4Plugin =
{
InputPlugin mp4Plugin = {
NULL,
NULL,
NULL,
@@ -460,4 +468,4 @@ InputPlugin mp4Plugin =
NULL
};
#endif /* HAVE_FAAD */
#endif /* HAVE_FAAD */

View File

@@ -37,66 +37,70 @@
#include <math.h>
typedef struct _MpcCallbackData {
InputStream * inStream;
DecoderControl * dc;
InputStream *inStream;
DecoderControl *dc;
} MpcCallbackData;
static mpc_int32_t mpc_read_cb(void * vdata, void * ptr, mpc_int32_t size) {
static mpc_int32_t mpc_read_cb(void *vdata, void *ptr, mpc_int32_t size)
{
mpc_int32_t ret = 0;
MpcCallbackData * data = (MpcCallbackData *)vdata;
MpcCallbackData *data = (MpcCallbackData *) vdata;
while(1) {
ret = readFromInputStream(data->inStream, ptr, 1, size);
if(ret == 0 && !inputStreamAtEOF(data->inStream) &&
(data->dc && !data->dc->stop))
{
my_usleep(10000);
}
else break;
}
while (1) {
ret = readFromInputStream(data->inStream, ptr, 1, size);
if (ret == 0 && !inputStreamAtEOF(data->inStream) &&
(data->dc && !data->dc->stop)) {
my_usleep(10000);
} else
break;
}
return ret;
}
static mpc_bool_t mpc_seek_cb(void * vdata, mpc_int32_t offset) {
MpcCallbackData * data = (MpcCallbackData *)vdata;
static mpc_bool_t mpc_seek_cb(void *vdata, mpc_int32_t offset)
{
MpcCallbackData *data = (MpcCallbackData *) vdata;
return seekInputStream(data->inStream , offset, SEEK_SET) < 0 ? 0 : 1;
return seekInputStream(data->inStream, offset, SEEK_SET) < 0 ? 0 : 1;
}
static mpc_int32_t mpc_tell_cb(void * vdata) {
MpcCallbackData * data = (MpcCallbackData *)vdata;
static mpc_int32_t mpc_tell_cb(void *vdata)
{
MpcCallbackData *data = (MpcCallbackData *) vdata;
return (long)(data->inStream->offset);
}
static mpc_bool_t mpc_canseek_cb(void * vdata) {
MpcCallbackData * data = (MpcCallbackData *)vdata;
static mpc_bool_t mpc_canseek_cb(void *vdata)
{
MpcCallbackData *data = (MpcCallbackData *) vdata;
return data->inStream->seekable;
}
static mpc_int32_t mpc_getsize_cb(void * vdata) {
MpcCallbackData * data = (MpcCallbackData *)vdata;
static mpc_int32_t mpc_getsize_cb(void *vdata)
{
MpcCallbackData *data = (MpcCallbackData *) vdata;
return data->inStream->size;
}
/* this _looks_ performance-critical, don't de-inline -- eric */
static inline mpd_sint16 convertSample(MPC_SAMPLE_FORMAT sample) {
static inline mpd_sint16 convertSample(MPC_SAMPLE_FORMAT sample)
{
/* only doing 16-bit audio for now */
mpd_sint32 val;
const int clip_min = -1 << (16 - 1);
const int clip_max = (1 << (16 - 1)) - 1;
const int clip_min = -1 << (16 - 1);
const int clip_max = (1 << (16 - 1)) - 1;
#ifdef MPC_FIXED_POINT
const int shift = 16 - MPC_FIXED_POINT_SCALE_SHIFT;
if( ssample > 0 ) {
if (ssample > 0) {
sample <<= shift;
}
else if ( shift < 0 ) {
} else if (shift < 0) {
sample >>= -shift;
}
val = sample;
@@ -106,14 +110,16 @@ static inline mpd_sint16 convertSample(MPC_SAMPLE_FORMAT sample) {
val = sample * float_scale;
#endif
if( val < clip_min) val = clip_min;
else if ( val > clip_max ) val = clip_max;
if (val < clip_min)
val = clip_min;
else if (val > clip_max)
val = clip_max;
return val;
}
static int mpc_decode(OutputBuffer * cb, DecoderControl * dc,
InputStream * inStream)
static int mpc_decode(OutputBuffer * cb, DecoderControl * dc,
InputStream * inStream)
{
mpc_decoder decoder;
mpc_reader reader;
@@ -129,16 +135,16 @@ static int mpc_decode(OutputBuffer * cb, DecoderControl * dc,
char chunk[MPC_CHUNK_SIZE];
int chunkpos = 0;
long bitRate = 0;
mpd_sint16 * s16 = (mpd_sint16 *) chunk;
mpd_sint16 *s16 = (mpd_sint16 *) chunk;
unsigned long samplePos = 0;
mpc_uint32_t vbrUpdateAcc;
mpc_uint32_t vbrUpdateBits;
float time;
int i;
ReplayGainInfo * replayGainInfo = NULL;
ReplayGainInfo *replayGainInfo = NULL;
data.inStream = inStream;
data.dc = dc;
data.inStream = inStream;
data.dc = dc;
reader.read = mpc_read_cb;
reader.seek = mpc_seek_cb;
@@ -148,39 +154,37 @@ static int mpc_decode(OutputBuffer * cb, DecoderControl * dc,
reader.data = &data;
mpc_streaminfo_init(&info);
if((ret = mpc_streaminfo_read(&info, &reader)) != ERROR_CODE_OK) {
if ((ret = mpc_streaminfo_read(&info, &reader)) != ERROR_CODE_OK) {
closeInputStream(inStream);
if(!dc->stop) {
ERROR("Not a valid musepack stream");
if (!dc->stop) {
ERROR("Not a valid musepack stream");
return -1;
}
else {
dc->state = DECODE_STATE_STOP;
dc->stop = 0;
}
return 0;
} else {
dc->state = DECODE_STATE_STOP;
dc->stop = 0;
}
return 0;
}
mpc_decoder_setup(&decoder, &reader);
if(!mpc_decoder_initialize(&decoder, &info)) {
if (!mpc_decoder_initialize(&decoder, &info)) {
closeInputStream(inStream);
if(!dc->stop) {
ERROR("Not a valid musepack stream");
}
else {
dc->state = DECODE_STATE_STOP;
dc->stop = 0;
}
if (!dc->stop) {
ERROR("Not a valid musepack stream");
} else {
dc->state = DECODE_STATE_STOP;
dc->stop = 0;
}
}
dc->totalTime = mpc_streaminfo_get_length(&info);
dc->audioFormat.bits = 16;
dc->audioFormat.channels = info.channels;
dc->audioFormat.sampleRate = info.sample_freq;
getOutputAudioFormat(&(dc->audioFormat), &(cb->audioFormat));
replayGainInfo = newReplayGainInfo();
@@ -191,23 +195,23 @@ static int mpc_decode(OutputBuffer * cb, DecoderControl * dc,
dc->state = DECODE_STATE_DECODE;
while(!eof) {
if(dc->seek) {
while (!eof) {
if (dc->seek) {
samplePos = dc->seekWhere * dc->audioFormat.sampleRate;
if(mpc_decoder_seek_sample(&decoder, samplePos)) {
clearOutputBuffer(cb);
chunkpos = 0;
}
else dc->seekError = 1;
if (mpc_decoder_seek_sample(&decoder, samplePos)) {
clearOutputBuffer(cb);
chunkpos = 0;
} else
dc->seekError = 1;
dc->seek = 0;
}
vbrUpdateAcc = 0;
vbrUpdateBits = 0;
ret = mpc_decoder_decode(&decoder, sample_buffer,
&vbrUpdateAcc, &vbrUpdateBits);
&vbrUpdateAcc, &vbrUpdateBits);
if(ret <= 0 || dc->stop ) {
if (ret <= 0 || dc->stop) {
eof = 1;
break;
}
@@ -217,30 +221,28 @@ static int mpc_decode(OutputBuffer * cb, DecoderControl * dc,
/* ret is in samples, and we have stereo */
ret *= 2;
for(i = 0; i < ret; i++) {
for (i = 0; i < ret; i++) {
/* 16 bit audio again */
*s16 = convertSample(sample_buffer[i]);
chunkpos += 2;
s16++;
if(chunkpos >= MPC_CHUNK_SIZE) {
time = ((float)samplePos) /
dc->audioFormat.sampleRate;
if (chunkpos >= MPC_CHUNK_SIZE) {
time = ((float)samplePos) /
dc->audioFormat.sampleRate;
bitRate = vbrUpdateBits *
dc->audioFormat.sampleRate /
1152 / 1000;
sendDataToOutputBuffer(cb, inStream, dc,
inStream->seekable,
chunk, chunkpos,
time,
bitRate,
replayGainInfo);
bitRate = vbrUpdateBits *
dc->audioFormat.sampleRate / 1152 / 1000;
sendDataToOutputBuffer(cb, inStream, dc,
inStream->seekable,
chunk, chunkpos,
time,
bitRate, replayGainInfo);
chunkpos = 0;
s16 = (mpd_sint16 *)chunk;
if(dc->stop) {
s16 = (mpd_sint16 *) chunk;
if (dc->stop) {
eof = 1;
break;
}
@@ -248,13 +250,14 @@ static int mpc_decode(OutputBuffer * cb, DecoderControl * dc,
}
}
if(!dc->stop && chunkpos > 0) {
time = ((float)samplePos) / dc->audioFormat.sampleRate;
if (!dc->stop && chunkpos > 0) {
time = ((float)samplePos) / dc->audioFormat.sampleRate;
bitRate = vbrUpdateBits * dc->audioFormat.sampleRate / 1152 / 1000;
bitRate =
vbrUpdateBits * dc->audioFormat.sampleRate / 1152 / 1000;
sendDataToOutputBuffer(cb, NULL, dc, inStream->seekable,
chunk, chunkpos, time, bitRate,
chunk, chunkpos, time, bitRate,
replayGainInfo);
}
@@ -264,27 +267,27 @@ static int mpc_decode(OutputBuffer * cb, DecoderControl * dc,
freeReplayGainInfo(replayGainInfo);
if(dc->stop) {
if (dc->stop) {
dc->state = DECODE_STATE_STOP;
dc->stop = 0;
}
else {
} else {
dc->state = DECODE_STATE_STOP;
}
return 0;
}
static float mpcGetTime(char * file) {
static float mpcGetTime(char *file)
{
InputStream inStream;
float time = -1;
mpc_reader reader;
mpc_streaminfo info;
MpcCallbackData data;
data.inStream = &inStream;
data.dc = NULL;
data.inStream = &inStream;
data.dc = NULL;
reader.read = mpc_read_cb;
reader.seek = mpc_seek_cb;
@@ -295,12 +298,12 @@ static float mpcGetTime(char * file) {
mpc_streaminfo_init(&info);
if(openInputStream(&inStream, file) < 0) {
if (openInputStream(&inStream, file) < 0) {
DEBUG("mpcGetTime: Failed to open file: %s\n", file);
return -1;
}
if(mpc_streaminfo_read(&info, &reader) != ERROR_CODE_OK) {
if (mpc_streaminfo_read(&info, &reader) != ERROR_CODE_OK) {
closeInputStream(&inStream);
return -1;
}
@@ -312,54 +315,56 @@ static float mpcGetTime(char * file) {
return time;
}
static MpdTag * mpcTagDup(char * file) {
MpdTag * ret = NULL;
static MpdTag *mpcTagDup(char *file)
{
MpdTag *ret = NULL;
float time = mpcGetTime(file);
if(time < 0) {
DEBUG("mpcTagDup: Failed to get Songlength of file: %s\n",file);
return NULL;
if (time < 0) {
DEBUG("mpcTagDup: Failed to get Songlength of file: %s\n",
file);
return NULL;
}
ret = apeDup(file);
if(!ret) ret = id3Dup(file);
if(!ret) ret = newMpdTag();
if (!ret)
ret = id3Dup(file);
if (!ret)
ret = newMpdTag();
ret->time = time;
return ret;
return ret;
}
static char * mpcSuffixes[] = {"mpc", NULL};
static char * mpcMimeTypes[] = {NULL};
static char *mpcSuffixes[] = { "mpc", NULL };
static char *mpcMimeTypes[] = { NULL };
InputPlugin mpcPlugin =
{
"mpc",
InputPlugin mpcPlugin = {
"mpc",
NULL,
NULL,
NULL,
mpc_decode,
NULL,
mpcTagDup,
INPUT_PLUGIN_STREAM_URL | INPUT_PLUGIN_STREAM_FILE,
mpcSuffixes,
mpcMimeTypes
mpc_decode,
NULL,
mpcTagDup,
INPUT_PLUGIN_STREAM_URL | INPUT_PLUGIN_STREAM_FILE,
mpcSuffixes,
mpcMimeTypes
};
#else
InputPlugin mpcPlugin =
{
InputPlugin mpcPlugin = {
NULL,
NULL,
NULL,
NULL,
NULL,
NULL,
NULL,
0,
NULL,
NULL
NULL,
NULL,
NULL,
0,
NULL,
NULL
};
#endif

View File

@@ -41,8 +41,8 @@
#include <FLAC/metadata.h>
static void oggflac_cleanup(InputStream * inStream,
FlacData * data,
OggFLAC__SeekableStreamDecoder * decoder)
FlacData * data,
OggFLAC__SeekableStreamDecoder * decoder)
{
if (data->replayGainInfo)
freeReplayGainInfo(data->replayGainInfo);
@@ -51,81 +51,93 @@ static void oggflac_cleanup(InputStream * inStream,
closeInputStream(inStream);
}
static OggFLAC__SeekableStreamDecoderReadStatus of_read_cb(
const OggFLAC__SeekableStreamDecoder * decoder,
FLAC__byte buf[], unsigned * bytes, void * fdata) {
FlacData * data = (FlacData *) fdata;
static OggFLAC__SeekableStreamDecoderReadStatus of_read_cb(const
OggFLAC__SeekableStreamDecoder
* decoder,
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 (r == 0 && !inputStreamAtEOF(data->inStream) && !data->dc->stop)
return OggFLAC__SEEKABLE_STREAM_DECODER_READ_STATUS_ERROR;
return OggFLAC__SEEKABLE_STREAM_DECODER_READ_STATUS_OK;
return OggFLAC__SEEKABLE_STREAM_DECODER_READ_STATUS_OK;
}
static OggFLAC__SeekableStreamDecoderSeekStatus of_seek_cb(
const OggFLAC__SeekableStreamDecoder * decoder,
FLAC__uint64 offset, void * fdata)
static OggFLAC__SeekableStreamDecoderSeekStatus of_seek_cb(const
OggFLAC__SeekableStreamDecoder
* decoder,
FLAC__uint64 offset,
void *fdata)
{
FlacData * data = (FlacData *) fdata;
FlacData *data = (FlacData *) fdata;
if(seekInputStream(data->inStream,offset,SEEK_SET)<0) {
return OggFLAC__SEEKABLE_STREAM_DECODER_SEEK_STATUS_ERROR;
}
if (seekInputStream(data->inStream, offset, SEEK_SET) < 0) {
return OggFLAC__SEEKABLE_STREAM_DECODER_SEEK_STATUS_ERROR;
}
return OggFLAC__SEEKABLE_STREAM_DECODER_SEEK_STATUS_OK;
return OggFLAC__SEEKABLE_STREAM_DECODER_SEEK_STATUS_OK;
}
static OggFLAC__SeekableStreamDecoderTellStatus of_tell_cb(
const OggFLAC__SeekableStreamDecoder * decoder,
FLAC__uint64 * offset, void * fdata)
static OggFLAC__SeekableStreamDecoderTellStatus of_tell_cb(const
OggFLAC__SeekableStreamDecoder
* decoder,
FLAC__uint64 *
offset, void *fdata)
{
FlacData * data = (FlacData *) fdata;
FlacData *data = (FlacData *) fdata;
*offset = (long)(data->inStream->offset);
*offset = (long)(data->inStream->offset);
return OggFLAC__SEEKABLE_STREAM_DECODER_TELL_STATUS_OK;
return OggFLAC__SEEKABLE_STREAM_DECODER_TELL_STATUS_OK;
}
static OggFLAC__SeekableStreamDecoderLengthStatus of_length_cb(
const OggFLAC__SeekableStreamDecoder * decoder,
FLAC__uint64 * length, void * fdata)
static OggFLAC__SeekableStreamDecoderLengthStatus of_length_cb(const
OggFLAC__SeekableStreamDecoder
* decoder,
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 OggFLAC__SEEKABLE_STREAM_DECODER_LENGTH_STATUS_OK;
return OggFLAC__SEEKABLE_STREAM_DECODER_LENGTH_STATUS_OK;
}
static FLAC__bool of_EOF_cb(const OggFLAC__SeekableStreamDecoder * decoder,
void * fdata) {
FlacData * data = (FlacData *) fdata;
void *fdata)
{
FlacData *data = (FlacData *) fdata;
if (inputStreamAtEOF(data->inStream) == 1)
return true;
return true;
return false;
}
static void of_error_cb(const OggFLAC__SeekableStreamDecoder * decoder,
FLAC__StreamDecoderErrorStatus status, void *fdata)
static void of_error_cb(const OggFLAC__SeekableStreamDecoder * decoder,
FLAC__StreamDecoderErrorStatus status, void *fdata)
{
flac_error_common_cb("oggflac",status,(FlacData *) fdata);
flac_error_common_cb("oggflac", status, (FlacData *) fdata);
}
static void oggflacPrintErroredState(OggFLAC__SeekableStreamDecoderState state)
static void oggflacPrintErroredState(OggFLAC__SeekableStreamDecoderState state)
{
switch(state) {
switch (state) {
case OggFLAC__SEEKABLE_STREAM_DECODER_MEMORY_ALLOCATION_ERROR:
ERROR("oggflac allocation error\n");
break;
@@ -154,21 +166,23 @@ static void oggflacPrintErroredState(OggFLAC__SeekableStreamDecoderState state)
}
}
static FLAC__StreamDecoderWriteStatus oggflacWrite(
const OggFLAC__SeekableStreamDecoder *decoder,
const FLAC__Frame *frame, const FLAC__int32 * const buf[],
void * vdata)
static FLAC__StreamDecoderWriteStatus oggflacWrite(const
OggFLAC__SeekableStreamDecoder
* decoder,
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;
timeChange = ((float)samples)/frame->header.sample_rate;
data->time+= timeChange;
timeChange = ((float)samples) / frame->header.sample_rate;
data->time += timeChange;
/* ogg123 uses a complicated method of calculating bitrate
* with averaging which I'm not too fond of.
@@ -177,24 +191,26 @@ static FLAC__StreamDecoderWriteStatus oggflacWrite(
*
* this does not give an accurate bitrate:
* (bytes_last_read was set in the read callback)
data->bitRate = ((8.0 * data->bytes_last_read *
frame->header.sample_rate)
/((float)samples * 1000)) + 0.5;
*/
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++) {
data->bitRate = ((8.0 * data->bytes_last_read *
frame->header.sample_rate)
/((float)samples * 1000)) + 0.5;
*/
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++);
@@ -206,106 +222,104 @@ static FLAC__StreamDecoderWriteStatus oggflacWrite(
}
/* used by TagDup */
static void of_metadata_dup_cb(
const OggFLAC__SeekableStreamDecoder * decoder,
const FLAC__StreamMetadata *block, void *vdata)
static void of_metadata_dup_cb(const OggFLAC__SeekableStreamDecoder * decoder,
const FLAC__StreamMetadata * block, void *vdata)
{
FlacData * data = (FlacData *)vdata;
FlacData *data = (FlacData *) vdata;
switch(block->type) {
case FLAC__METADATA_TYPE_STREAMINFO:
if (!data->tag) data->tag = newMpdTag();
switch (block->type) {
case FLAC__METADATA_TYPE_STREAMINFO:
if (!data->tag)
data->tag = newMpdTag();
data->tag->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;
return;
case FLAC__METADATA_TYPE_VORBIS_COMMENT:
copyVorbisCommentBlockToMpdTag(block,data->tag);
case FLAC__METADATA_TYPE_VORBIS_COMMENT:
copyVorbisCommentBlockToMpdTag(block, data->tag);
default:
break;
}
}
}
/* used by decode */
static void of_metadata_decode_cb(const OggFLAC__SeekableStreamDecoder * dec,
const FLAC__StreamMetadata *block, void *vdata)
const FLAC__StreamMetadata * block,
void *vdata)
{
flac_metadata_common_cb(block, (FlacData *)vdata);
flac_metadata_common_cb(block, (FlacData *) vdata);
}
static OggFLAC__SeekableStreamDecoder * full_decoder_init_and_read_metadata(
FlacData * data,
unsigned int metadata_only)
static OggFLAC__SeekableStreamDecoder
*full_decoder_init_and_read_metadata(FlacData * data,
unsigned int metadata_only)
{
OggFLAC__SeekableStreamDecoder * decoder = NULL;
OggFLAC__SeekableStreamDecoder *decoder = NULL;
unsigned int s = 1;
if (!(decoder = OggFLAC__seekable_stream_decoder_new()))
return NULL;
if (metadata_only) {
s &= OggFLAC__seekable_stream_decoder_set_metadata_callback(
decoder, of_metadata_dup_cb);
s &= OggFLAC__seekable_stream_decoder_set_metadata_respond(
decoder,
FLAC__METADATA_TYPE_STREAMINFO);
s &= OggFLAC__seekable_stream_decoder_set_metadata_callback
(decoder, of_metadata_dup_cb);
s &= OggFLAC__seekable_stream_decoder_set_metadata_respond
(decoder, FLAC__METADATA_TYPE_STREAMINFO);
} else {
s &= OggFLAC__seekable_stream_decoder_set_metadata_callback(
decoder, of_metadata_decode_cb);
s &= OggFLAC__seekable_stream_decoder_set_metadata_callback
(decoder, of_metadata_decode_cb);
}
s &= OggFLAC__seekable_stream_decoder_set_read_callback(decoder,
of_read_cb);
of_read_cb);
s &= OggFLAC__seekable_stream_decoder_set_seek_callback(decoder,
of_seek_cb);
of_seek_cb);
s &= OggFLAC__seekable_stream_decoder_set_tell_callback(decoder,
of_tell_cb);
of_tell_cb);
s &= OggFLAC__seekable_stream_decoder_set_length_callback(decoder,
of_length_cb);
of_length_cb);
s &= OggFLAC__seekable_stream_decoder_set_eof_callback(decoder,
of_EOF_cb);
of_EOF_cb);
s &= OggFLAC__seekable_stream_decoder_set_write_callback(decoder,
oggflacWrite);
oggflacWrite);
s &= OggFLAC__seekable_stream_decoder_set_metadata_respond(decoder,
FLAC__METADATA_TYPE_VORBIS_COMMENT);
FLAC__METADATA_TYPE_VORBIS_COMMENT);
s &= OggFLAC__seekable_stream_decoder_set_error_callback(decoder,
of_error_cb);
of_error_cb);
s &= OggFLAC__seekable_stream_decoder_set_client_data(decoder,
(void *)data);
(void *)data);
if (!s) {
ERROR("oggflac problem before init()\n");
goto fail;
}
if (OggFLAC__seekable_stream_decoder_init(decoder) !=
OggFLAC__SEEKABLE_STREAM_DECODER_OK)
{
OggFLAC__SEEKABLE_STREAM_DECODER_OK) {
ERROR("oggflac problem doing init()\n");
goto fail;
}
if (!OggFLAC__seekable_stream_decoder_process_until_end_of_metadata(
decoder)) {
if (!OggFLAC__seekable_stream_decoder_process_until_end_of_metadata
(decoder)) {
ERROR("oggflac problem reading metadata\n");
goto fail;
}
return decoder;
return decoder;
fail:
oggflacPrintErroredState(
OggFLAC__seekable_stream_decoder_get_state(decoder));
fail:
oggflacPrintErroredState(OggFLAC__seekable_stream_decoder_get_state
(decoder));
OggFLAC__seekable_stream_decoder_delete(decoder);
return NULL;
}
/* public functions: */
static MpdTag * oggflac_TagDup(char * file)
static MpdTag *oggflac_TagDup(char *file)
{
InputStream inStream;
OggFLAC__SeekableStreamDecoder * decoder;
OggFLAC__SeekableStreamDecoder *decoder;
FlacData data;
if (openInputStream(&inStream, file) < 0)
return NULL;
if (ogg_stream_type_detect(&inStream) != FLAC) {
@@ -317,10 +331,10 @@ static MpdTag * oggflac_TagDup(char * file)
/* errors here won't matter,
* data.tag will be set or unset, that's all we care about */
decoder = full_decoder_init_and_read_metadata(&data,1);
decoder = full_decoder_init_and_read_metadata(&data, 1);
oggflac_cleanup(&inStream, &data, decoder);
return data.tag;
}
@@ -330,51 +344,49 @@ static unsigned int oggflac_try_decode(InputStream * inStream)
}
static int oggflac_decode(OutputBuffer * cb, DecoderControl * dc,
InputStream * inStream)
InputStream * inStream)
{
OggFLAC__SeekableStreamDecoder * decoder = NULL;
OggFLAC__SeekableStreamDecoder *decoder = NULL;
FlacData data;
int ret = 0;
int ret = 0;
init_FlacData(&data, cb, dc, inStream);
if(!(decoder = full_decoder_init_and_read_metadata(&data,0))){
ret = -1;
goto fail;
}
if (!(decoder = full_decoder_init_and_read_metadata(&data, 0))) {
ret = -1;
goto fail;
}
dc->state = DECODE_STATE_DECODE;
while(1) {
while (1) {
OggFLAC__seekable_stream_decoder_process_single(decoder);
if(OggFLAC__seekable_stream_decoder_get_state(decoder)!=
OggFLAC__SEEKABLE_STREAM_DECODER_OK)
{
if (OggFLAC__seekable_stream_decoder_get_state(decoder) !=
OggFLAC__SEEKABLE_STREAM_DECODER_OK) {
break;
}
if(dc->seek) {
FLAC__uint64 sampleToSeek = dc->seekWhere*
dc->audioFormat.sampleRate+0.5;
if(OggFLAC__seekable_stream_decoder_seek_absolute(
decoder, sampleToSeek))
{
clearOutputBuffer(cb);
data.time = ((float)sampleToSeek)/
dc->audioFormat.sampleRate;
if (dc->seek) {
FLAC__uint64 sampleToSeek = dc->seekWhere *
dc->audioFormat.sampleRate + 0.5;
if (OggFLAC__seekable_stream_decoder_seek_absolute
(decoder, sampleToSeek)) {
clearOutputBuffer(cb);
data.time = ((float)sampleToSeek) /
dc->audioFormat.sampleRate;
data.position = 0;
}
else dc->seekError = 1;
} else
dc->seekError = 1;
dc->seek = 0;
}
}
if(!dc->stop) {
oggflacPrintErroredState(
OggFLAC__seekable_stream_decoder_get_state(decoder));
if (!dc->stop) {
oggflacPrintErroredState
(OggFLAC__seekable_stream_decoder_get_state(decoder));
OggFLAC__seekable_stream_decoder_finish(decoder);
}
/* send last little bit */
if(data.chunk_length>0 && !dc->stop) {
if (data.chunk_length > 0 && !dc->stop) {
flacSendChunk(&data);
flushOutputBuffer(data.cb);
}
@@ -382,17 +394,16 @@ static int oggflac_decode(OutputBuffer * cb, DecoderControl * dc,
dc->state = DECODE_STATE_STOP;
dc->stop = 0;
fail:
fail:
oggflac_cleanup(inStream, &data, decoder);
return ret;
}
static char * oggflac_Suffixes[] = {"ogg", NULL};
static char * oggflac_mime_types[] = {"application/ogg", NULL};
static char *oggflac_Suffixes[] = { "ogg", NULL };
static char *oggflac_mime_types[] = { "application/ogg", NULL };
InputPlugin oggflacPlugin =
{
InputPlugin oggflacPlugin = {
"oggflac",
NULL,
NULL,
@@ -405,10 +416,9 @@ InputPlugin oggflacPlugin =
oggflac_mime_types
};
#else /* !HAVE_FLAC */
#else /* !HAVE_FLAC */
InputPlugin oggflacPlugin =
{
InputPlugin oggflacPlugin = {
NULL,
NULL,
NULL,
@@ -421,5 +431,4 @@ InputPlugin oggflacPlugin =
NULL,
};
#endif /* HAVE_OGGFLAC */
#endif /* HAVE_OGGFLAC */

View File

@@ -50,7 +50,7 @@
#define ov_time_total(VF, I) ((double)ov_time_total(VF, I)/1000)
#define ov_time_tell(VF) ((double)ov_time_tell(VF)/1000)
#define ov_time_seek_page(VF, S) (ov_time_seek_page(VF, (S)*1000))
#endif /* HAVE_TREMOR */
#endif /* HAVE_TREMOR */
#include <errno.h>
@@ -61,158 +61,165 @@
#endif
typedef struct _OggCallbackData {
InputStream * inStream;
DecoderControl * dc;
InputStream *inStream;
DecoderControl *dc;
} OggCallbackData;
static size_t ogg_read_cb(void * ptr, size_t size, size_t nmemb, void * vdata)
static size_t ogg_read_cb(void *ptr, size_t size, size_t nmemb, void *vdata)
{
size_t ret = 0;
OggCallbackData * data = (OggCallbackData *)vdata;
OggCallbackData *data = (OggCallbackData *) vdata;
while(1) {
ret = readFromInputStream(data->inStream,ptr,size,nmemb);
if(ret == 0 && !inputStreamAtEOF(data->inStream) &&
!data->dc->stop)
{
my_usleep(10000);
}
else break;
}
errno = 0;
/*if(ret<0) errno = ((InputStream *)inStream)->error;*/
while (1) {
ret = readFromInputStream(data->inStream, ptr, size, nmemb);
if (ret == 0 && !inputStreamAtEOF(data->inStream) &&
!data->dc->stop) {
my_usleep(10000);
} else
break;
}
errno = 0;
/*if(ret<0) errno = ((InputStream *)inStream)->error; */
return ret;
}
static int ogg_seek_cb(void * vdata, ogg_int64_t offset, int whence) {
OggCallbackData * data = (OggCallbackData *)vdata;
static int ogg_seek_cb(void *vdata, ogg_int64_t offset, int whence)
{
OggCallbackData *data = (OggCallbackData *) vdata;
return seekInputStream(data->inStream,offset,whence);
return seekInputStream(data->inStream, offset, whence);
}
static int ogg_close_cb(void * vdata) {
OggCallbackData * data = (OggCallbackData *)vdata;
static int ogg_close_cb(void *vdata)
{
OggCallbackData *data = (OggCallbackData *) vdata;
return closeInputStream(data->inStream);
}
static long ogg_tell_cb(void * vdata) {
OggCallbackData * data = (OggCallbackData *)vdata;
static long ogg_tell_cb(void *vdata)
{
OggCallbackData *data = (OggCallbackData *) vdata;
return (long)(data->inStream->offset);
}
static char * ogg_parseComment(char * comment, char * needle) {
int len = strlen(needle);
static char *ogg_parseComment(char *comment, char *needle)
{
int len = strlen(needle);
if(strncasecmp(comment, needle, len) == 0 && *(comment+len) == '=') {
return comment+len+1;
if (strncasecmp(comment, needle, len) == 0 && *(comment + len) == '=') {
return comment + len + 1;
}
return NULL;
return NULL;
}
static void ogg_getReplayGainInfo(char ** comments, ReplayGainInfo ** infoPtr) {
char * temp;
static void ogg_getReplayGainInfo(char **comments, ReplayGainInfo ** infoPtr)
{
char *temp;
int found = 0;
if(*infoPtr) freeReplayGainInfo(*infoPtr);
if (*infoPtr)
freeReplayGainInfo(*infoPtr);
*infoPtr = newReplayGainInfo();
while(*comments) {
if((temp = ogg_parseComment(*comments,"replaygain_track_gain")))
{
(*infoPtr)->trackGain = atof(temp);
while (*comments) {
if ((temp =
ogg_parseComment(*comments, "replaygain_track_gain"))) {
(*infoPtr)->trackGain = atof(temp);
found = 1;
}
else if((temp = ogg_parseComment(*comments,
"replaygain_album_gain")))
{
(*infoPtr)->albumGain = atof(temp);
} else if ((temp = ogg_parseComment(*comments,
"replaygain_album_gain"))) {
(*infoPtr)->albumGain = atof(temp);
found = 1;
}
else if((temp = ogg_parseComment(*comments,
"replaygain_track_peak")))
{
(*infoPtr)->trackPeak = atof(temp);
} else if ((temp = ogg_parseComment(*comments,
"replaygain_track_peak"))) {
(*infoPtr)->trackPeak = atof(temp);
found = 1;
}
else if((temp = ogg_parseComment(*comments,
"replaygain_album_peak")))
{
(*infoPtr)->albumPeak = atof(temp);
} else if ((temp = ogg_parseComment(*comments,
"replaygain_album_peak"))) {
(*infoPtr)->albumPeak = atof(temp);
found = 1;
}
}
comments++;
}
comments++;
}
if(!found) {
if (!found) {
freeReplayGainInfo(*infoPtr);
*infoPtr = NULL;
}
}
static const char * VORBIS_COMMENT_TRACK_KEY = "tracknumber";
static const char * VORBIS_COMMENT_DISC_KEY = "discnumber";
static const char *VORBIS_COMMENT_TRACK_KEY = "tracknumber";
static const char *VORBIS_COMMENT_DISC_KEY = "discnumber";
static unsigned int ogg_parseCommentAddToTag(char * comment,
unsigned int itemType, MpdTag ** tag)
static unsigned int ogg_parseCommentAddToTag(char *comment,
unsigned int itemType,
MpdTag ** tag)
{
const char * needle;
const char *needle;
unsigned int len;
switch (itemType) {
case TAG_ITEM_TRACK: needle = VORBIS_COMMENT_TRACK_KEY; break;
case TAG_ITEM_DISC: needle = VORBIS_COMMENT_DISC_KEY; break;
default: needle = mpdTagItemKeys[itemType];
case TAG_ITEM_TRACK:
needle = VORBIS_COMMENT_TRACK_KEY;
break;
case TAG_ITEM_DISC:
needle = VORBIS_COMMENT_DISC_KEY;
break;
default:
needle = mpdTagItemKeys[itemType];
}
len = strlen(needle);
if(strncasecmp(comment, needle, len) == 0 && *(comment+len) == '=') {
if (strncasecmp(comment, needle, len) == 0 && *(comment + len) == '=') {
if (!*tag)
*tag = newMpdTag();
addItemToMpdTag(*tag, itemType, comment+len+1);
addItemToMpdTag(*tag, itemType, comment + len + 1);
return 1;
}
return 0;
}
static MpdTag * oggCommentsParse(char ** comments) {
MpdTag * tag = NULL;
while(*comments) {
static MpdTag *oggCommentsParse(char **comments)
{
MpdTag *tag = NULL;
while (*comments) {
int j;
for (j = TAG_NUM_OF_ITEM_TYPES; --j >= 0; ) {
for (j = TAG_NUM_OF_ITEM_TYPES; --j >= 0;) {
if (ogg_parseCommentAddToTag(*comments, j, &tag))
break;
}
comments++;
}
return tag;
}
static void putOggCommentsIntoOutputBuffer(OutputBuffer * cb, char * streamName,
char ** comments)
static void putOggCommentsIntoOutputBuffer(OutputBuffer * cb, char *streamName,
char **comments)
{
MpdTag * tag;
MpdTag *tag;
tag = oggCommentsParse(comments);
if(!tag && streamName) {
if (!tag && streamName) {
tag = newMpdTag();
}
if(!tag) return;
if (!tag)
return;
/*if(tag->artist) printf("Artist: %s\n", tag->artist);
if(tag->album) printf("Album: %s\n", tag->album);
if(tag->track) printf("Track: %s\n", tag->track);
if(tag->title) printf("Title: %s\n", tag->title);*/
if(tag->album) printf("Album: %s\n", tag->album);
if(tag->track) printf("Track: %s\n", tag->track);
if(tag->title) printf("Title: %s\n", tag->title); */
if(streamName) {
if (streamName) {
clearItemsFromMpdTag(tag, TAG_ITEM_NAME);
addItemToMpdTag(tag, TAG_ITEM_NAME, streamName);
}
@@ -224,11 +231,11 @@ static void putOggCommentsIntoOutputBuffer(OutputBuffer * cb, char * streamName,
/* public */
static int oggvorbis_decode(OutputBuffer * cb, DecoderControl * dc,
InputStream * inStream)
InputStream * inStream)
{
OggVorbis_File vf;
ov_callbacks callbacks;
OggCallbackData data;
OggCallbackData data;
int current_section;
int prev_section = -1;
int eof = 0;
@@ -238,22 +245,22 @@ static int oggvorbis_decode(OutputBuffer * cb, DecoderControl * dc,
int chunkpos = 0;
long bitRate = 0;
long test;
ReplayGainInfo * replayGainInfo = NULL;
char ** comments;
char * errorStr;
ReplayGainInfo *replayGainInfo = NULL;
char **comments;
char *errorStr;
data.inStream = inStream;
data.dc = dc;
data.inStream = inStream;
data.dc = dc;
callbacks.read_func = ogg_read_cb;
callbacks.seek_func = ogg_seek_cb;
callbacks.close_func = ogg_close_cb;
callbacks.tell_func = ogg_tell_cb;
if((ret = ov_open_callbacks(&data, &vf, NULL, 0, callbacks)) < 0) {
if ((ret = ov_open_callbacks(&data, &vf, NULL, 0, callbacks)) < 0) {
closeInputStream(inStream);
if(!dc->stop) {
switch(ret) {
if (!dc->stop) {
switch (ret) {
case OV_EREAD:
errorStr = "read error";
break;
@@ -273,123 +280,127 @@ static int oggvorbis_decode(OutputBuffer * cb, DecoderControl * dc,
errorStr = "unknown error";
break;
}
ERROR("Error decoding Ogg Vorbis stream: %s\n",
ERROR("Error decoding Ogg Vorbis stream: %s\n",
errorStr);
return -1;
}
else {
dc->state = DECODE_STATE_STOP;
dc->stop = 0;
}
return 0;
return -1;
} else {
dc->state = DECODE_STATE_STOP;
dc->stop = 0;
}
return 0;
}
dc->totalTime = ov_time_total(&vf,-1);
if(dc->totalTime < 0) dc->totalTime = 0;
dc->totalTime = ov_time_total(&vf, -1);
if (dc->totalTime < 0)
dc->totalTime = 0;
dc->audioFormat.bits = 16;
while(!eof) {
if(dc->seek) {
if(0 == ov_time_seek_page(&vf,dc->seekWhere)) {
clearOutputBuffer(cb);
chunkpos = 0;
}
else dc->seekError = 1;
while (!eof) {
if (dc->seek) {
if (0 == ov_time_seek_page(&vf, dc->seekWhere)) {
clearOutputBuffer(cb);
chunkpos = 0;
} else
dc->seekError = 1;
dc->seek = 0;
}
ret = ov_read(&vf, chunk+chunkpos,
OGG_CHUNK_SIZE-chunkpos,
OGG_DECODE_USE_BIGENDIAN,
2, 1, &current_section);
ret = ov_read(&vf, chunk + chunkpos,
OGG_CHUNK_SIZE - chunkpos,
OGG_DECODE_USE_BIGENDIAN, 2, 1, &current_section);
if(current_section!=prev_section) {
/*printf("new song!\n");*/
vorbis_info *vi=ov_info(&vf,-1);
if (current_section != prev_section) {
/*printf("new song!\n"); */
vorbis_info *vi = ov_info(&vf, -1);
dc->audioFormat.channels = vi->channels;
dc->audioFormat.sampleRate = vi->rate;
if(dc->state == DECODE_STATE_START) {
getOutputAudioFormat(&(dc->audioFormat),
&(cb->audioFormat));
if (dc->state == DECODE_STATE_START) {
getOutputAudioFormat(&(dc->audioFormat),
&(cb->audioFormat));
dc->state = DECODE_STATE_DECODE;
}
comments = ov_comment(&vf, -1)->user_comments;
putOggCommentsIntoOutputBuffer(cb, inStream->metaName,
comments);
ogg_getReplayGainInfo(comments, &replayGainInfo);
comments);
ogg_getReplayGainInfo(comments, &replayGainInfo);
}
prev_section = current_section;
if(ret <= 0 && ret != OV_HOLE) {
if (ret <= 0 && ret != OV_HOLE) {
eof = 1;
break;
}
if(ret == OV_HOLE) ret = 0;
if (ret == OV_HOLE)
ret = 0;
chunkpos+=ret;
chunkpos += ret;
if(chunkpos >= OGG_CHUNK_SIZE) {
if((test = ov_bitrate_instant(&vf))>0) {
bitRate = test/1000;
if (chunkpos >= OGG_CHUNK_SIZE) {
if ((test = ov_bitrate_instant(&vf)) > 0) {
bitRate = test / 1000;
}
sendDataToOutputBuffer(cb, inStream, dc,
inStream->seekable,
chunk, chunkpos,
ov_pcm_tell(&vf)/
dc->audioFormat.sampleRate,
bitRate,
replayGainInfo);
sendDataToOutputBuffer(cb, inStream, dc,
inStream->seekable,
chunk, chunkpos,
ov_pcm_tell(&vf) /
dc->audioFormat.sampleRate,
bitRate, replayGainInfo);
chunkpos = 0;
if(dc->stop) break;
if (dc->stop)
break;
}
}
if(!dc->stop && chunkpos > 0) {
if (!dc->stop && chunkpos > 0) {
sendDataToOutputBuffer(cb, NULL, dc, inStream->seekable,
chunk, chunkpos,
ov_time_tell(&vf), bitRate, replayGainInfo);
chunk, chunkpos,
ov_time_tell(&vf), bitRate,
replayGainInfo);
}
if(replayGainInfo) freeReplayGainInfo(replayGainInfo);
if (replayGainInfo)
freeReplayGainInfo(replayGainInfo);
ov_clear(&vf);
flushOutputBuffer(cb);
if(dc->stop) {
if (dc->stop) {
dc->state = DECODE_STATE_STOP;
dc->stop = 0;
}
else dc->state = DECODE_STATE_STOP;
} else
dc->state = DECODE_STATE_STOP;
return 0;
}
static MpdTag * oggvorbis_TagDup(char * file) {
MpdTag * ret = NULL;
FILE * fp;
static MpdTag *oggvorbis_TagDup(char *file)
{
MpdTag *ret = NULL;
FILE *fp;
OggVorbis_File vf;
fp = fopen(file,"r");
if(!fp)
{
DEBUG("oggTagDup: Failed to open file: '%s', %s\n", file, strerror(errno));
return NULL;
fp = fopen(file, "r");
if (!fp) {
DEBUG("oggTagDup: Failed to open file: '%s', %s\n", file,
strerror(errno));
return NULL;
}
if(ov_open(fp,&vf,NULL,0)<0) {
if (ov_open(fp, &vf, NULL, 0) < 0) {
fclose(fp);
return NULL;
}
ret = oggCommentsParse(ov_comment(&vf,-1)->user_comments);
ret = oggCommentsParse(ov_comment(&vf, -1)->user_comments);
if(!ret) ret = newMpdTag();
ret->time = (int)(ov_time_total(&vf,-1)+0.5);
if (!ret)
ret = newMpdTag();
ret->time = (int)(ov_time_total(&vf, -1) + 0.5);
ov_clear(&vf);
return ret;
return ret;
}
static unsigned int oggvorbis_try_decode(InputStream * inStream)
@@ -397,12 +408,10 @@ static unsigned int oggvorbis_try_decode(InputStream * inStream)
return (ogg_stream_type_detect(inStream) == VORBIS) ? 1 : 0;
}
static char *oggvorbis_Suffixes[] = { "ogg", NULL };
static char *oggvorbis_MimeTypes[] = { "application/ogg", NULL };
static char * oggvorbis_Suffixes[] = {"ogg", NULL};
static char * oggvorbis_MimeTypes[] = {"application/ogg", NULL};
InputPlugin oggvorbisPlugin =
{
InputPlugin oggvorbisPlugin = {
"oggvorbis",
NULL,
NULL,
@@ -415,10 +424,9 @@ InputPlugin oggvorbisPlugin =
oggvorbis_MimeTypes
};
#else /* !HAVE_OGGVORBIS */
#else /* !HAVE_OGGVORBIS */
InputPlugin oggvorbisPlugin =
{
InputPlugin oggvorbisPlugin = {
NULL,
NULL,
NULL,
@@ -431,4 +439,4 @@ InputPlugin oggvorbisPlugin =
NULL,
};
#endif /* HAVE_OGGVORBIS */
#endif /* HAVE_OGGVORBIS */