Stop passing our single DecoderControl object everywhere
This at least makes the argument list to a lot of our plugin functions shorter and removes a good amount of line nois^W^Wcode, hopefully making things easier to read and follow. git-svn-id: https://svn.musicpd.org/mpd/trunk@7353 09075e82-0dd4-0310-85a5-a0d7c8717e4f
This commit is contained in:
parent
98acfa8ac5
commit
dec6b1612e
190
src/decode.c
190
src/decode.c
@ -32,37 +32,37 @@ void decoder_wakeup_player(void)
|
|||||||
wakeup_player_nb();
|
wakeup_player_nb();
|
||||||
}
|
}
|
||||||
|
|
||||||
void decoder_sleep(DecoderControl * dc)
|
void decoder_sleep(void)
|
||||||
{
|
{
|
||||||
notifyWait(&dc->notify);
|
notifyWait(&dc.notify);
|
||||||
wakeup_player_nb();
|
wakeup_player_nb();
|
||||||
}
|
}
|
||||||
|
|
||||||
static void player_wakeup_decoder_nb(DecoderControl * dc)
|
static void player_wakeup_decoder_nb(void)
|
||||||
{
|
{
|
||||||
notifySignal(&dc->notify);
|
notifySignal(&dc.notify);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* called from player_task */
|
/* called from player_task */
|
||||||
static void player_wakeup_decoder(DecoderControl * dc)
|
static void player_wakeup_decoder(void)
|
||||||
{
|
{
|
||||||
notifySignal(&dc->notify);
|
notifySignal(&dc.notify);
|
||||||
player_sleep();
|
player_sleep();
|
||||||
}
|
}
|
||||||
|
|
||||||
static void stopDecode(DecoderControl * dc)
|
static void stopDecode(void)
|
||||||
{
|
{
|
||||||
if (dc->start || dc->state != DECODE_STATE_STOP) {
|
if (dc.start || dc.state != DECODE_STATE_STOP) {
|
||||||
dc->stop = 1;
|
dc.stop = 1;
|
||||||
do { player_wakeup_decoder_nb(dc); } while (dc->stop);
|
do { player_wakeup_decoder_nb(); } while (dc.stop);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void quitDecode(DecoderControl * dc)
|
static void quitDecode(void)
|
||||||
{
|
{
|
||||||
stopDecode(dc);
|
stopDecode();
|
||||||
pc.state = PLAYER_STATE_STOP;
|
pc.state = PLAYER_STATE_STOP;
|
||||||
dc->seek = 0;
|
dc.seek = 0;
|
||||||
pc.play = 0;
|
pc.play = 0;
|
||||||
pc.stop = 0;
|
pc.stop = 0;
|
||||||
pc.pause = 0;
|
pc.pause = 0;
|
||||||
@ -93,16 +93,15 @@ static unsigned calculateCrossFadeChunks(AudioFormat * af, float totalTime)
|
|||||||
return chunks;
|
return chunks;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int waitOnDecode(DecoderControl * dc,
|
static int waitOnDecode(OutputBuffer * cb, int *decodeWaitedOn)
|
||||||
OutputBuffer * cb, int *decodeWaitedOn)
|
|
||||||
{
|
{
|
||||||
while (dc->start)
|
while (dc.start)
|
||||||
player_wakeup_decoder(dc);
|
player_wakeup_decoder();
|
||||||
|
|
||||||
if (dc->error != DECODE_ERROR_NOERROR) {
|
if (dc.error != DECODE_ERROR_NOERROR) {
|
||||||
pc.errored_song = pc.current_song;
|
pc.errored_song = pc.current_song;
|
||||||
pc.error = PLAYER_ERROR_FILE;
|
pc.error = PLAYER_ERROR_FILE;
|
||||||
quitDecode(dc);
|
quitDecode();
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -116,31 +115,30 @@ static int waitOnDecode(DecoderControl * dc,
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int decodeSeek(DecoderControl * dc,
|
static int decodeSeek(OutputBuffer * cb, int *decodeWaitedOn, int *next)
|
||||||
OutputBuffer * cb, int *decodeWaitedOn, int *next)
|
|
||||||
{
|
{
|
||||||
int ret = -1;
|
int ret = -1;
|
||||||
|
|
||||||
if (dc->state == DECODE_STATE_STOP ||
|
if (dc.state == DECODE_STATE_STOP ||
|
||||||
dc->error != DECODE_ERROR_NOERROR ||
|
dc.error != DECODE_ERROR_NOERROR ||
|
||||||
dc->current_song != pc.current_song) {
|
dc.current_song != pc.current_song) {
|
||||||
stopDecode(dc);
|
stopDecode();
|
||||||
*next = -1;
|
*next = -1;
|
||||||
clearOutputBuffer(cb);
|
clearOutputBuffer(cb);
|
||||||
dc->error = DECODE_ERROR_NOERROR;
|
dc.error = DECODE_ERROR_NOERROR;
|
||||||
dc->start = 1;
|
dc.start = 1;
|
||||||
waitOnDecode(dc, cb, decodeWaitedOn);
|
waitOnDecode(cb, decodeWaitedOn);
|
||||||
}
|
}
|
||||||
if (dc->state != DECODE_STATE_STOP && dc->seekable) {
|
if (dc.state != DECODE_STATE_STOP && dc.seekable) {
|
||||||
*next = -1;
|
*next = -1;
|
||||||
dc->seekWhere = pc.seekWhere > pc.totalTime - 0.1 ?
|
dc.seekWhere = pc.seekWhere > pc.totalTime - 0.1 ?
|
||||||
pc.totalTime - 0.1 : pc.seekWhere;
|
pc.totalTime - 0.1 : pc.seekWhere;
|
||||||
dc->seekWhere = 0 > dc->seekWhere ? 0 : dc->seekWhere;
|
dc.seekWhere = 0 > dc.seekWhere ? 0 : dc.seekWhere;
|
||||||
dc->seekError = 0;
|
dc.seekError = 0;
|
||||||
dc->seek = 1;
|
dc.seek = 1;
|
||||||
do { player_wakeup_decoder(dc); } while (dc->seek);
|
do { player_wakeup_decoder(); } while (dc.seek);
|
||||||
if (!dc->seekError) {
|
if (!dc.seekError) {
|
||||||
pc.elapsedTime = dc->seekWhere;
|
pc.elapsedTime = dc.seekWhere;
|
||||||
ret = 0;
|
ret = 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -150,8 +148,7 @@ static int decodeSeek(DecoderControl * dc,
|
|||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void processDecodeInput(DecoderControl * dc,
|
static void processDecodeInput(OutputBuffer * cb,
|
||||||
OutputBuffer * cb,
|
|
||||||
int *pause_r, unsigned int *bbp_r,
|
int *pause_r, unsigned int *bbp_r,
|
||||||
int *doCrossFade_r,
|
int *doCrossFade_r,
|
||||||
int *decodeWaitedOn_r,
|
int *decodeWaitedOn_r,
|
||||||
@ -195,14 +192,14 @@ static void processDecodeInput(DecoderControl * dc,
|
|||||||
}
|
}
|
||||||
if(pc.seek) {
|
if(pc.seek) {
|
||||||
dropBufferedAudio();
|
dropBufferedAudio();
|
||||||
if(decodeSeek(dc,cb,decodeWaitedOn_r,next_r) == 0) {
|
if (decodeSeek(cb, decodeWaitedOn_r, next_r) == 0) {
|
||||||
*doCrossFade_r = 0;
|
*doCrossFade_r = 0;
|
||||||
*bbp_r = 0;
|
*bbp_r = 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void decodeStart(OutputBuffer * cb, DecoderControl * dc)
|
static void decodeStart(OutputBuffer * cb)
|
||||||
{
|
{
|
||||||
int ret;
|
int ret;
|
||||||
int close_instream = 1;
|
int close_instream = 1;
|
||||||
@ -212,7 +209,7 @@ static void decodeStart(OutputBuffer * cb, DecoderControl * dc)
|
|||||||
char path_max_utf8[MPD_PATH_MAX];
|
char path_max_utf8[MPD_PATH_MAX];
|
||||||
|
|
||||||
if (!get_song_url(path_max_utf8, pc.current_song)) {
|
if (!get_song_url(path_max_utf8, pc.current_song)) {
|
||||||
dc->error = DECODE_ERROR_FILE;
|
dc.error = DECODE_ERROR_FILE;
|
||||||
goto stop_no_close;
|
goto stop_no_close;
|
||||||
}
|
}
|
||||||
if (!isRemoteUrl(path_max_utf8)) {
|
if (!isRemoteUrl(path_max_utf8)) {
|
||||||
@ -220,19 +217,19 @@ static void decodeStart(OutputBuffer * cb, DecoderControl * dc)
|
|||||||
utf8_to_fs_charset(path_max_fs, path_max_utf8));
|
utf8_to_fs_charset(path_max_fs, path_max_utf8));
|
||||||
}
|
}
|
||||||
|
|
||||||
dc->current_song = pc.current_song; /* NEED LOCK */
|
dc.current_song = pc.current_song; /* NEED LOCK */
|
||||||
if (openInputStream(&inStream, path_max_fs) < 0) {
|
if (openInputStream(&inStream, path_max_fs) < 0) {
|
||||||
dc->error = DECODE_ERROR_FILE;
|
dc.error = DECODE_ERROR_FILE;
|
||||||
goto stop_no_close;
|
goto stop_no_close;
|
||||||
}
|
}
|
||||||
|
|
||||||
dc->state = DECODE_STATE_START;
|
dc.state = DECODE_STATE_START;
|
||||||
dc->start = 0;
|
dc.start = 0;
|
||||||
|
|
||||||
/* for http streams, seekable is determined in bufferInputStream */
|
/* for http streams, seekable is determined in bufferInputStream */
|
||||||
dc->seekable = inStream.seekable;
|
dc.seekable = inStream.seekable;
|
||||||
|
|
||||||
if (dc->stop)
|
if (dc.stop)
|
||||||
goto stop;
|
goto stop;
|
||||||
|
|
||||||
ret = DECODE_ERROR_UNKTYPE;
|
ret = DECODE_ERROR_UNKTYPE;
|
||||||
@ -248,7 +245,7 @@ static void decodeStart(OutputBuffer * cb, DecoderControl * dc)
|
|||||||
if (plugin->tryDecodeFunc
|
if (plugin->tryDecodeFunc
|
||||||
&& !plugin->tryDecodeFunc(&inStream))
|
&& !plugin->tryDecodeFunc(&inStream))
|
||||||
continue;
|
continue;
|
||||||
ret = plugin->streamDecodeFunc(cb, dc, &inStream);
|
ret = plugin->streamDecodeFunc(cb, &inStream);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -265,7 +262,7 @@ static void decodeStart(OutputBuffer * cb, DecoderControl * dc)
|
|||||||
if (plugin->tryDecodeFunc &&
|
if (plugin->tryDecodeFunc &&
|
||||||
!plugin->tryDecodeFunc(&inStream))
|
!plugin->tryDecodeFunc(&inStream))
|
||||||
continue;
|
continue;
|
||||||
ret = plugin->streamDecodeFunc(cb, dc, &inStream);
|
ret = plugin->streamDecodeFunc(cb, &inStream);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -276,8 +273,7 @@ static void decodeStart(OutputBuffer * cb, DecoderControl * dc)
|
|||||||
/* we already know our mp3Plugin supports streams, no
|
/* we already know our mp3Plugin supports streams, no
|
||||||
* need to check for stream{Types,DecodeFunc} */
|
* need to check for stream{Types,DecodeFunc} */
|
||||||
if ((plugin = getInputPluginFromName("mp3"))) {
|
if ((plugin = getInputPluginFromName("mp3"))) {
|
||||||
ret = plugin->streamDecodeFunc(cb, dc,
|
ret = plugin->streamDecodeFunc(cb, &inStream);
|
||||||
&inStream);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
@ -294,11 +290,10 @@ static void decodeStart(OutputBuffer * cb, DecoderControl * dc)
|
|||||||
if (plugin->fileDecodeFunc) {
|
if (plugin->fileDecodeFunc) {
|
||||||
closeInputStream(&inStream);
|
closeInputStream(&inStream);
|
||||||
close_instream = 0;
|
close_instream = 0;
|
||||||
ret = plugin->fileDecodeFunc(cb, dc,
|
ret = plugin->fileDecodeFunc(cb, path_max_fs);
|
||||||
path_max_fs);
|
|
||||||
break;
|
break;
|
||||||
} else if (plugin->streamDecodeFunc) {
|
} else if (plugin->streamDecodeFunc) {
|
||||||
ret = plugin->streamDecodeFunc(cb, dc, &inStream);
|
ret = plugin->streamDecodeFunc(cb, &inStream);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -307,49 +302,48 @@ static void decodeStart(OutputBuffer * cb, DecoderControl * dc)
|
|||||||
if (ret < 0 || ret == DECODE_ERROR_UNKTYPE) {
|
if (ret < 0 || ret == DECODE_ERROR_UNKTYPE) {
|
||||||
pc.errored_song = pc.current_song;
|
pc.errored_song = pc.current_song;
|
||||||
if (ret != DECODE_ERROR_UNKTYPE)
|
if (ret != DECODE_ERROR_UNKTYPE)
|
||||||
dc->error = DECODE_ERROR_FILE;
|
dc.error = DECODE_ERROR_FILE;
|
||||||
else
|
else
|
||||||
dc->error = DECODE_ERROR_UNKTYPE;
|
dc.error = DECODE_ERROR_UNKTYPE;
|
||||||
}
|
}
|
||||||
|
|
||||||
stop:
|
stop:
|
||||||
if (close_instream)
|
if (close_instream)
|
||||||
closeInputStream(&inStream);
|
closeInputStream(&inStream);
|
||||||
stop_no_close:
|
stop_no_close:
|
||||||
dc->state = DECODE_STATE_STOP;
|
dc.state = DECODE_STATE_STOP;
|
||||||
dc->stop = 0;
|
dc.stop = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void * decoder_task(void *arg)
|
static void * decoder_task(mpd_unused void *arg)
|
||||||
{
|
{
|
||||||
DecoderControl *dc = arg;
|
|
||||||
OutputBuffer *cb = &(getPlayerData()->buffer);
|
OutputBuffer *cb = &(getPlayerData()->buffer);
|
||||||
|
|
||||||
notifyEnter(&dc->notify);
|
notifyEnter(&dc.notify);
|
||||||
|
|
||||||
while (1) {
|
while (1) {
|
||||||
if (dc->start || dc->seek) {
|
if (dc.start || dc.seek) {
|
||||||
decodeStart(cb, dc);
|
decodeStart(cb);
|
||||||
} else if (dc->stop) {
|
} else if (dc.stop) {
|
||||||
dc->state = DECODE_STATE_STOP;
|
dc.state = DECODE_STATE_STOP;
|
||||||
dc->stop = 0;
|
dc.stop = 0;
|
||||||
decoder_wakeup_player();
|
decoder_wakeup_player();
|
||||||
} else {
|
} else {
|
||||||
decoder_sleep(dc);
|
decoder_sleep();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
void decoderInit(DecoderControl * dc)
|
void decoderInit(void)
|
||||||
{
|
{
|
||||||
pthread_attr_t attr;
|
pthread_attr_t attr;
|
||||||
pthread_t decoder_thread;
|
pthread_t decoder_thread;
|
||||||
|
|
||||||
pthread_attr_init(&attr);
|
pthread_attr_init(&attr);
|
||||||
pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);
|
pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);
|
||||||
if (pthread_create(&decoder_thread, &attr, decoder_task, dc))
|
if (pthread_create(&decoder_thread, &attr, decoder_task, NULL))
|
||||||
FATAL("Failed to spawn decoder task: %s\n", strerror(errno));
|
FATAL("Failed to spawn decoder task: %s\n", strerror(errno));
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -387,7 +381,7 @@ static int playChunk(OutputBufferChunk * chunk,
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void decodeParent(DecoderControl * dc, OutputBuffer * cb)
|
static void decodeParent(OutputBuffer * cb)
|
||||||
{
|
{
|
||||||
int do_pause = 0;
|
int do_pause = 0;
|
||||||
int buffering = 1;
|
int buffering = 1;
|
||||||
@ -405,7 +399,7 @@ static void decodeParent(DecoderControl * dc, OutputBuffer * cb)
|
|||||||
/** the position of the first chunk in the next song */
|
/** the position of the first chunk in the next song */
|
||||||
int next = -1;
|
int next = -1;
|
||||||
|
|
||||||
if (waitOnDecode(dc, cb, &decodeWaitedOn) < 0)
|
if (waitOnDecode(cb, &decodeWaitedOn) < 0)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
pc.elapsedTime = 0;
|
pc.elapsedTime = 0;
|
||||||
@ -414,7 +408,7 @@ static void decodeParent(DecoderControl * dc, OutputBuffer * cb)
|
|||||||
wakeup_main_task();
|
wakeup_main_task();
|
||||||
|
|
||||||
while (1) {
|
while (1) {
|
||||||
processDecodeInput(dc, cb,
|
processDecodeInput(cb,
|
||||||
&do_pause, &bbp, &doCrossFade,
|
&do_pause, &bbp, &doCrossFade,
|
||||||
&decodeWaitedOn, &next);
|
&decodeWaitedOn, &next);
|
||||||
if (pc.stop) {
|
if (pc.stop) {
|
||||||
@ -433,8 +427,8 @@ static void decodeParent(DecoderControl * dc, OutputBuffer * cb)
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (decodeWaitedOn) {
|
if (decodeWaitedOn) {
|
||||||
if(dc->state!=DECODE_STATE_START &&
|
if(dc.state!=DECODE_STATE_START &&
|
||||||
dc->error==DECODE_ERROR_NOERROR) {
|
dc.error==DECODE_ERROR_NOERROR) {
|
||||||
/* the decoder is ready and ok */
|
/* the decoder is ready and ok */
|
||||||
decodeWaitedOn = 0;
|
decodeWaitedOn = 0;
|
||||||
if(openAudioDevice(&(cb->audioFormat))<0) {
|
if(openAudioDevice(&(cb->audioFormat))<0) {
|
||||||
@ -446,19 +440,19 @@ static void decodeParent(DecoderControl * dc, OutputBuffer * cb)
|
|||||||
get_song_url(tmp, pc.current_song));
|
get_song_url(tmp, pc.current_song));
|
||||||
break;
|
break;
|
||||||
} else {
|
} else {
|
||||||
player_wakeup_decoder(dc);
|
player_wakeup_decoder();
|
||||||
}
|
}
|
||||||
if (do_pause) {
|
if (do_pause) {
|
||||||
dropBufferedAudio();
|
dropBufferedAudio();
|
||||||
closeAudioDevice();
|
closeAudioDevice();
|
||||||
}
|
}
|
||||||
pc.totalTime = dc->totalTime;
|
pc.totalTime = dc.totalTime;
|
||||||
pc.sampleRate = dc->audioFormat.sampleRate;
|
pc.sampleRate = dc.audioFormat.sampleRate;
|
||||||
pc.bits = dc->audioFormat.bits;
|
pc.bits = dc.audioFormat.bits;
|
||||||
pc.channels = dc->audioFormat.channels;
|
pc.channels = dc.audioFormat.channels;
|
||||||
sizeToTime = audioFormatSizeToTime(&cb->audioFormat);
|
sizeToTime = audioFormatSizeToTime(&cb->audioFormat);
|
||||||
}
|
}
|
||||||
else if(dc->state!=DECODE_STATE_START) {
|
else if(dc.state!=DECODE_STATE_START) {
|
||||||
/* the decoder failed */
|
/* the decoder failed */
|
||||||
pc.errored_song = pc.current_song;
|
pc.errored_song = pc.current_song;
|
||||||
pc.error = PLAYER_ERROR_FILE;
|
pc.error = PLAYER_ERROR_FILE;
|
||||||
@ -472,25 +466,25 @@ static void decodeParent(DecoderControl * dc, OutputBuffer * cb)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (dc->state == DECODE_STATE_STOP &&
|
if (dc.state == DECODE_STATE_STOP &&
|
||||||
pc.queueState == PLAYER_QUEUE_FULL &&
|
pc.queueState == PLAYER_QUEUE_FULL &&
|
||||||
pc.queueLockState == PLAYER_QUEUE_UNLOCKED) {
|
pc.queueLockState == PLAYER_QUEUE_UNLOCKED) {
|
||||||
/* the decoder has finished the current song;
|
/* the decoder has finished the current song;
|
||||||
make it decode the next song */
|
make it decode the next song */
|
||||||
next = cb->end;
|
next = cb->end;
|
||||||
dc->start = 1;
|
dc.start = 1;
|
||||||
pc.queueState = PLAYER_QUEUE_DECODE;
|
pc.queueState = PLAYER_QUEUE_DECODE;
|
||||||
wakeup_main_task();
|
wakeup_main_task();
|
||||||
player_wakeup_decoder_nb(dc);
|
player_wakeup_decoder_nb();
|
||||||
}
|
}
|
||||||
if (next >= 0 && doCrossFade == 0 && !dc->start &&
|
if (next >= 0 && doCrossFade == 0 && !dc.start &&
|
||||||
dc->state != DECODE_STATE_START) {
|
dc.state != DECODE_STATE_START) {
|
||||||
/* enable cross fading in this song? if yes,
|
/* enable cross fading in this song? if yes,
|
||||||
calculate how many chunks will be required
|
calculate how many chunks will be required
|
||||||
for it */
|
for it */
|
||||||
crossFadeChunks =
|
crossFadeChunks =
|
||||||
calculateCrossFadeChunks(&(cb->audioFormat),
|
calculateCrossFadeChunks(&(cb->audioFormat),
|
||||||
dc->totalTime);
|
dc.totalTime);
|
||||||
if (crossFadeChunks > 0) {
|
if (crossFadeChunks > 0) {
|
||||||
doCrossFade = 1;
|
doCrossFade = 1;
|
||||||
nextChunk = -1;
|
nextChunk = -1;
|
||||||
@ -528,7 +522,7 @@ static void decodeParent(DecoderControl * dc, OutputBuffer * cb)
|
|||||||
} else {
|
} else {
|
||||||
/* there are not enough
|
/* there are not enough
|
||||||
decoded chunks yet */
|
decoded chunks yet */
|
||||||
if (dc->state == DECODE_STATE_STOP) {
|
if (dc.state == DECODE_STATE_STOP) {
|
||||||
/* the decoder isn't
|
/* the decoder isn't
|
||||||
running, abort
|
running, abort
|
||||||
cross fading */
|
cross fading */
|
||||||
@ -547,7 +541,7 @@ static void decodeParent(DecoderControl * dc, OutputBuffer * cb)
|
|||||||
sizeToTime) < 0)
|
sizeToTime) < 0)
|
||||||
break;
|
break;
|
||||||
outputBufferShift(cb);
|
outputBufferShift(cb);
|
||||||
player_wakeup_decoder_nb(dc);
|
player_wakeup_decoder_nb();
|
||||||
} else if (!outputBufferEmpty(cb) && (int)cb->begin == next) {
|
} else if (!outputBufferEmpty(cb) && (int)cb->begin == next) {
|
||||||
/* at the beginning of a new song */
|
/* at the beginning of a new song */
|
||||||
|
|
||||||
@ -570,12 +564,12 @@ static void decodeParent(DecoderControl * dc, OutputBuffer * cb)
|
|||||||
break;
|
break;
|
||||||
|
|
||||||
next = -1;
|
next = -1;
|
||||||
if (waitOnDecode(dc, cb, &decodeWaitedOn) < 0)
|
if (waitOnDecode(cb, &decodeWaitedOn) < 0)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
pc.queueState = PLAYER_QUEUE_EMPTY;
|
pc.queueState = PLAYER_QUEUE_EMPTY;
|
||||||
wakeup_main_task();
|
wakeup_main_task();
|
||||||
} else if (dc->state == DECODE_STATE_STOP && !dc->start) {
|
} else if (dc.state == DECODE_STATE_STOP && !dc.start) {
|
||||||
break;
|
break;
|
||||||
} else {
|
} else {
|
||||||
/*DEBUG("waiting for decoded audio, play silence\n");*/
|
/*DEBUG("waiting for decoded audio, play silence\n");*/
|
||||||
@ -584,7 +578,7 @@ static void decodeParent(DecoderControl * dc, OutputBuffer * cb)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
quitDecode(dc);
|
quitDecode();
|
||||||
}
|
}
|
||||||
|
|
||||||
/* decode w/ buffering
|
/* decode w/ buffering
|
||||||
@ -595,17 +589,15 @@ static void decodeParent(DecoderControl * dc, OutputBuffer * cb)
|
|||||||
void decode(void)
|
void decode(void)
|
||||||
{
|
{
|
||||||
OutputBuffer *cb;
|
OutputBuffer *cb;
|
||||||
DecoderControl *dc;
|
|
||||||
|
|
||||||
cb = &(getPlayerData()->buffer);
|
cb = &(getPlayerData()->buffer);
|
||||||
clearOutputBuffer(cb);
|
clearOutputBuffer(cb);
|
||||||
|
|
||||||
dc = &(getPlayerData()->decoderControl);
|
dc.error = DECODE_ERROR_NOERROR;
|
||||||
dc->error = DECODE_ERROR_NOERROR;
|
dc.seek = 0;
|
||||||
dc->seek = 0;
|
dc.stop = 0;
|
||||||
dc->stop = 0;
|
dc.start = 1;
|
||||||
dc->start = 1;
|
do { player_wakeup_decoder(); } while (dc.start);
|
||||||
do { player_wakeup_decoder(dc); } while (dc->start);
|
|
||||||
|
|
||||||
decodeParent(dc, cb);
|
decodeParent(cb);
|
||||||
}
|
}
|
||||||
|
@ -55,8 +55,8 @@ void decode(void);
|
|||||||
|
|
||||||
void decoder_wakeup_player(void);
|
void decoder_wakeup_player(void);
|
||||||
|
|
||||||
void decoder_sleep(DecoderControl * dc);
|
void decoder_sleep(void);
|
||||||
|
|
||||||
void decoderInit(DecoderControl * dc);
|
void decoderInit(void);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
@ -21,6 +21,7 @@
|
|||||||
|
|
||||||
#include "inputStream.h"
|
#include "inputStream.h"
|
||||||
#include "outputBuffer.h"
|
#include "outputBuffer.h"
|
||||||
|
#include "playerData.h"
|
||||||
|
|
||||||
/* valid values for streamTypes in the InputPlugin struct: */
|
/* valid values for streamTypes in the InputPlugin struct: */
|
||||||
#define INPUT_PLUGIN_STREAM_FILE 0x01
|
#define INPUT_PLUGIN_STREAM_FILE 0x01
|
||||||
@ -41,16 +42,14 @@ typedef unsigned int (*InputPlugin_tryDecodeFunc) (InputStream *);
|
|||||||
* and networked (HTTP) connections.
|
* and networked (HTTP) connections.
|
||||||
*
|
*
|
||||||
* returns -1 on error, 0 on success */
|
* returns -1 on error, 0 on success */
|
||||||
typedef int (*InputPlugin_streamDecodeFunc) (OutputBuffer *, DecoderControl *,
|
typedef int (*InputPlugin_streamDecodeFunc) (OutputBuffer *, InputStream *);
|
||||||
InputStream *);
|
|
||||||
|
|
||||||
/* use this if and only if your InputPlugin can only be passed a filename or
|
/* use this if and only if your InputPlugin can only be passed a filename or
|
||||||
* handle as input, and will not allow callbacks to be set (like Ogg-Vorbis
|
* handle as input, and will not allow callbacks to be set (like Ogg-Vorbis
|
||||||
* and FLAC libraries allow)
|
* and FLAC libraries allow)
|
||||||
*
|
*
|
||||||
* returns -1 on error, 0 on success */
|
* returns -1 on error, 0 on success */
|
||||||
typedef int (*InputPlugin_fileDecodeFunc) (OutputBuffer *, DecoderControl *,
|
typedef int (*InputPlugin_fileDecodeFunc) (OutputBuffer *, char *path);
|
||||||
char *path);
|
|
||||||
|
|
||||||
/* file should be the full path! Returns NULL if a tag cannot be found
|
/* file should be the full path! Returns NULL if a tag cannot be found
|
||||||
* or read */
|
* or read */
|
||||||
|
@ -36,15 +36,13 @@
|
|||||||
#include <FLAC/format.h>
|
#include <FLAC/format.h>
|
||||||
#include <FLAC/metadata.h>
|
#include <FLAC/metadata.h>
|
||||||
|
|
||||||
void init_FlacData(FlacData * data, OutputBuffer * cb,
|
void init_FlacData(FlacData * data, OutputBuffer * cb, InputStream * inStream)
|
||||||
DecoderControl * dc, InputStream * inStream)
|
|
||||||
{
|
{
|
||||||
data->chunk_length = 0;
|
data->chunk_length = 0;
|
||||||
data->time = 0;
|
data->time = 0;
|
||||||
data->position = 0;
|
data->position = 0;
|
||||||
data->bitRate = 0;
|
data->bitRate = 0;
|
||||||
data->cb = cb;
|
data->cb = cb;
|
||||||
data->dc = dc;
|
|
||||||
data->inStream = inStream;
|
data->inStream = inStream;
|
||||||
data->replayGainInfo = NULL;
|
data->replayGainInfo = NULL;
|
||||||
data->tag = NULL;
|
data->tag = NULL;
|
||||||
@ -165,16 +163,15 @@ MpdTag *copyVorbisCommentBlockToMpdTag(const FLAC__StreamMetadata * block,
|
|||||||
void flac_metadata_common_cb(const FLAC__StreamMetadata * block,
|
void flac_metadata_common_cb(const FLAC__StreamMetadata * block,
|
||||||
FlacData * data)
|
FlacData * data)
|
||||||
{
|
{
|
||||||
DecoderControl *dc = data->dc;
|
|
||||||
const FLAC__StreamMetadata_StreamInfo *si = &(block->data.stream_info);
|
const FLAC__StreamMetadata_StreamInfo *si = &(block->data.stream_info);
|
||||||
|
|
||||||
switch (block->type) {
|
switch (block->type) {
|
||||||
case FLAC__METADATA_TYPE_STREAMINFO:
|
case FLAC__METADATA_TYPE_STREAMINFO:
|
||||||
dc->audioFormat.bits = (mpd_sint8)si->bits_per_sample;
|
dc.audioFormat.bits = (mpd_sint8)si->bits_per_sample;
|
||||||
dc->audioFormat.sampleRate = si->sample_rate;
|
dc.audioFormat.sampleRate = si->sample_rate;
|
||||||
dc->audioFormat.channels = (mpd_sint8)si->channels;
|
dc.audioFormat.channels = (mpd_sint8)si->channels;
|
||||||
dc->totalTime = ((float)si->total_samples) / (si->sample_rate);
|
dc.totalTime = ((float)si->total_samples) / (si->sample_rate);
|
||||||
getOutputAudioFormat(&(dc->audioFormat),
|
getOutputAudioFormat(&(dc.audioFormat),
|
||||||
&(data->cb->audioFormat));
|
&(data->cb->audioFormat));
|
||||||
break;
|
break;
|
||||||
case FLAC__METADATA_TYPE_VORBIS_COMMENT:
|
case FLAC__METADATA_TYPE_VORBIS_COMMENT:
|
||||||
@ -188,7 +185,7 @@ void flac_error_common_cb(const char *plugin,
|
|||||||
const FLAC__StreamDecoderErrorStatus status,
|
const FLAC__StreamDecoderErrorStatus status,
|
||||||
FlacData * data)
|
FlacData * data)
|
||||||
{
|
{
|
||||||
if (data->dc->stop)
|
if (dc.stop)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
switch (status) {
|
switch (status) {
|
||||||
|
@ -149,15 +149,13 @@ typedef struct {
|
|||||||
unsigned int bitRate;
|
unsigned int bitRate;
|
||||||
FLAC__uint64 position;
|
FLAC__uint64 position;
|
||||||
OutputBuffer *cb;
|
OutputBuffer *cb;
|
||||||
DecoderControl *dc;
|
|
||||||
InputStream *inStream;
|
InputStream *inStream;
|
||||||
ReplayGainInfo *replayGainInfo;
|
ReplayGainInfo *replayGainInfo;
|
||||||
MpdTag *tag;
|
MpdTag *tag;
|
||||||
} FlacData;
|
} FlacData;
|
||||||
|
|
||||||
/* initializes a given FlacData struct */
|
/* initializes a given FlacData struct */
|
||||||
void init_FlacData(FlacData * data, OutputBuffer * cb,
|
void init_FlacData(FlacData * data, OutputBuffer * cb, InputStream * inStream);
|
||||||
DecoderControl * dc, InputStream * inStream);
|
|
||||||
void flac_metadata_common_cb(const FLAC__StreamMetadata * block,
|
void flac_metadata_common_cb(const FLAC__StreamMetadata * block,
|
||||||
FlacData * data);
|
FlacData * data);
|
||||||
void flac_error_common_cb(const char *plugin,
|
void flac_error_common_cb(const char *plugin,
|
||||||
@ -171,7 +169,7 @@ MpdTag *copyVorbisCommentBlockToMpdTag(const FLAC__StreamMetadata * block,
|
|||||||
static inline int flacSendChunk(FlacData * data)
|
static inline int flacSendChunk(FlacData * data)
|
||||||
{
|
{
|
||||||
if (sendDataToOutputBuffer(data->cb, data->inStream,
|
if (sendDataToOutputBuffer(data->cb, data->inStream,
|
||||||
data->dc, 1, data->chunk,
|
1, data->chunk,
|
||||||
data->chunk_length, data->time,
|
data->chunk_length, data->time,
|
||||||
data->bitRate,
|
data->bitRate,
|
||||||
data->replayGainInfo) ==
|
data->replayGainInfo) ==
|
||||||
|
@ -282,7 +282,7 @@ static int getAacTotalTime(char *file)
|
|||||||
return file_time;
|
return file_time;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int aac_decode(OutputBuffer * cb, DecoderControl * dc, char *path)
|
static int aac_decode(OutputBuffer * cb, char *path)
|
||||||
{
|
{
|
||||||
float file_time;
|
float file_time;
|
||||||
float totalTime;
|
float totalTime;
|
||||||
@ -339,9 +339,9 @@ static int aac_decode(OutputBuffer * cb, DecoderControl * dc, char *path)
|
|||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
dc->audioFormat.bits = 16;
|
dc.audioFormat.bits = 16;
|
||||||
|
|
||||||
dc->totalTime = totalTime;
|
dc.totalTime = totalTime;
|
||||||
|
|
||||||
file_time = 0.0;
|
file_time = 0.0;
|
||||||
|
|
||||||
@ -372,12 +372,12 @@ static int aac_decode(OutputBuffer * cb, DecoderControl * dc, char *path)
|
|||||||
sampleRate = frameInfo.samplerate;
|
sampleRate = frameInfo.samplerate;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
if (dc->state != DECODE_STATE_DECODE) {
|
if (dc.state != DECODE_STATE_DECODE) {
|
||||||
dc->audioFormat.channels = frameInfo.channels;
|
dc.audioFormat.channels = frameInfo.channels;
|
||||||
dc->audioFormat.sampleRate = sampleRate;
|
dc.audioFormat.sampleRate = sampleRate;
|
||||||
getOutputAudioFormat(&(dc->audioFormat),
|
getOutputAudioFormat(&(dc.audioFormat),
|
||||||
&(cb->audioFormat));
|
&(cb->audioFormat));
|
||||||
dc->state = DECODE_STATE_DECODE;
|
dc.state = DECODE_STATE_DECODE;
|
||||||
}
|
}
|
||||||
|
|
||||||
advanceAacBuffer(&b, frameInfo.bytesconsumed);
|
advanceAacBuffer(&b, frameInfo.bytesconsumed);
|
||||||
@ -395,14 +395,14 @@ static int aac_decode(OutputBuffer * cb, DecoderControl * dc, char *path)
|
|||||||
|
|
||||||
sampleBufferLen = sampleCount * 2;
|
sampleBufferLen = sampleCount * 2;
|
||||||
|
|
||||||
sendDataToOutputBuffer(cb, NULL, dc, 0, sampleBuffer,
|
sendDataToOutputBuffer(cb, NULL, 0, sampleBuffer,
|
||||||
sampleBufferLen, file_time,
|
sampleBufferLen, file_time,
|
||||||
bitRate, NULL);
|
bitRate, NULL);
|
||||||
if (dc->seek) {
|
if (dc.seek) {
|
||||||
dc->seekError = 1;
|
dc.seekError = 1;
|
||||||
dc->seek = 0;
|
dc.seek = 0;
|
||||||
decoder_wakeup_player();
|
decoder_wakeup_player();
|
||||||
} else if (dc->stop) {
|
} else if (dc.stop) {
|
||||||
eof = 1;
|
eof = 1;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@ -414,12 +414,12 @@ static int aac_decode(OutputBuffer * cb, DecoderControl * dc, char *path)
|
|||||||
if (b.buffer)
|
if (b.buffer)
|
||||||
free(b.buffer);
|
free(b.buffer);
|
||||||
|
|
||||||
if (dc->state != DECODE_STATE_DECODE)
|
if (dc.state != DECODE_STATE_DECODE)
|
||||||
return -1;
|
return -1;
|
||||||
|
|
||||||
if (dc->seek) {
|
if (dc.seek) {
|
||||||
dc->seekError = 1;
|
dc.seekError = 1;
|
||||||
dc->seek = 0;
|
dc.seek = 0;
|
||||||
decoder_wakeup_player();
|
decoder_wakeup_player();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -45,7 +45,7 @@ static int getAudiofileTotalTime(char *file)
|
|||||||
return total_time;
|
return total_time;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int audiofile_decode(OutputBuffer * cb, DecoderControl * dc, char *path)
|
static int audiofile_decode(OutputBuffer * cb, char *path)
|
||||||
{
|
{
|
||||||
int fs, frame_count;
|
int fs, frame_count;
|
||||||
AFfilehandle af_fp;
|
AFfilehandle af_fp;
|
||||||
@ -67,41 +67,41 @@ static int audiofile_decode(OutputBuffer * cb, DecoderControl * dc, char *path)
|
|||||||
afSetVirtualSampleFormat(af_fp, AF_DEFAULT_TRACK,
|
afSetVirtualSampleFormat(af_fp, AF_DEFAULT_TRACK,
|
||||||
AF_SAMPFMT_TWOSCOMP, 16);
|
AF_SAMPFMT_TWOSCOMP, 16);
|
||||||
afGetVirtualSampleFormat(af_fp, AF_DEFAULT_TRACK, &fs, &bits);
|
afGetVirtualSampleFormat(af_fp, AF_DEFAULT_TRACK, &fs, &bits);
|
||||||
dc->audioFormat.bits = (mpd_uint8)bits;
|
dc.audioFormat.bits = (mpd_uint8)bits;
|
||||||
dc->audioFormat.sampleRate =
|
dc.audioFormat.sampleRate =
|
||||||
(unsigned int)afGetRate(af_fp, AF_DEFAULT_TRACK);
|
(unsigned int)afGetRate(af_fp, AF_DEFAULT_TRACK);
|
||||||
dc->audioFormat.channels =
|
dc.audioFormat.channels =
|
||||||
(mpd_uint8)afGetVirtualChannels(af_fp, AF_DEFAULT_TRACK);
|
(mpd_uint8)afGetVirtualChannels(af_fp, AF_DEFAULT_TRACK);
|
||||||
getOutputAudioFormat(&(dc->audioFormat), &(cb->audioFormat));
|
getOutputAudioFormat(&(dc.audioFormat), &(cb->audioFormat));
|
||||||
|
|
||||||
frame_count = afGetFrameCount(af_fp, AF_DEFAULT_TRACK);
|
frame_count = afGetFrameCount(af_fp, AF_DEFAULT_TRACK);
|
||||||
|
|
||||||
dc->totalTime =
|
dc.totalTime =
|
||||||
((float)frame_count / (float)dc->audioFormat.sampleRate);
|
((float)frame_count / (float)dc.audioFormat.sampleRate);
|
||||||
|
|
||||||
bitRate = (mpd_uint16)(st.st_size * 8.0 / dc->totalTime / 1000.0 + 0.5);
|
bitRate = (mpd_uint16)(st.st_size * 8.0 / dc.totalTime / 1000.0 + 0.5);
|
||||||
|
|
||||||
if (dc->audioFormat.bits != 8 && dc->audioFormat.bits != 16) {
|
if (dc.audioFormat.bits != 8 && dc.audioFormat.bits != 16) {
|
||||||
ERROR("Only 8 and 16-bit files are supported. %s is %i-bit\n",
|
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);
|
afCloseFile(af_fp);
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
fs = (int)afGetVirtualFrameSize(af_fp, AF_DEFAULT_TRACK, 1);
|
fs = (int)afGetVirtualFrameSize(af_fp, AF_DEFAULT_TRACK, 1);
|
||||||
|
|
||||||
dc->state = DECODE_STATE_DECODE;
|
dc.state = DECODE_STATE_DECODE;
|
||||||
{
|
{
|
||||||
int ret, eof = 0, current = 0;
|
int ret, eof = 0, current = 0;
|
||||||
char chunk[CHUNK_SIZE];
|
char chunk[CHUNK_SIZE];
|
||||||
|
|
||||||
while (!eof) {
|
while (!eof) {
|
||||||
if (dc->seek) {
|
if (dc.seek) {
|
||||||
clearOutputBuffer(cb);
|
clearOutputBuffer(cb);
|
||||||
current = dc->seekWhere *
|
current = dc.seekWhere *
|
||||||
dc->audioFormat.sampleRate;
|
dc.audioFormat.sampleRate;
|
||||||
afSeekFrame(af_fp, AF_DEFAULT_TRACK, current);
|
afSeekFrame(af_fp, AF_DEFAULT_TRACK, current);
|
||||||
dc->seek = 0;
|
dc.seek = 0;
|
||||||
decoder_wakeup_player();
|
decoder_wakeup_player();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -114,15 +114,14 @@ static int audiofile_decode(OutputBuffer * cb, DecoderControl * dc, char *path)
|
|||||||
current += ret;
|
current += ret;
|
||||||
sendDataToOutputBuffer(cb,
|
sendDataToOutputBuffer(cb,
|
||||||
NULL,
|
NULL,
|
||||||
dc,
|
|
||||||
1,
|
1,
|
||||||
chunk,
|
chunk,
|
||||||
ret * fs,
|
ret * fs,
|
||||||
(float)current /
|
(float)current /
|
||||||
(float)dc->audioFormat.
|
(float)dc.audioFormat.
|
||||||
sampleRate, bitRate,
|
sampleRate, bitRate,
|
||||||
NULL);
|
NULL);
|
||||||
if (dc->stop)
|
if (dc.stop)
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -41,15 +41,14 @@ static flac_read_status flacRead(const flac_decoder * flacDec,
|
|||||||
|
|
||||||
while (1) {
|
while (1) {
|
||||||
r = readFromInputStream(data->inStream, (void *)buf, 1, *bytes);
|
r = readFromInputStream(data->inStream, (void *)buf, 1, *bytes);
|
||||||
if (r == 0 && !inputStreamAtEOF(data->inStream) &&
|
if (r == 0 && !inputStreamAtEOF(data->inStream) && !dc.stop)
|
||||||
!data->dc->stop)
|
|
||||||
my_usleep(10000);
|
my_usleep(10000);
|
||||||
else
|
else
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
*bytes = r;
|
*bytes = r;
|
||||||
|
|
||||||
if (r == 0 && !data->dc->stop) {
|
if (r == 0 && !dc.stop) {
|
||||||
if (inputStreamAtEOF(data->inStream))
|
if (inputStreamAtEOF(data->inStream))
|
||||||
return flac_read_status_eof;
|
return flac_read_status_eof;
|
||||||
else
|
else
|
||||||
@ -248,7 +247,7 @@ static FLAC__StreamDecoderWriteStatus flacWrite(const flac_decoder *dec,
|
|||||||
FLAC__uint32 samples = frame->header.blocksize;
|
FLAC__uint32 samples = frame->header.blocksize;
|
||||||
unsigned int c_samp;
|
unsigned int c_samp;
|
||||||
const unsigned int num_channels = frame->header.channels;
|
const unsigned int num_channels = frame->header.channels;
|
||||||
const unsigned int bytes_per_sample = (data->dc->audioFormat.bits / 8);
|
const unsigned int bytes_per_sample = (dc.audioFormat.bits / 8);
|
||||||
const unsigned int bytes_per_channel =
|
const unsigned int bytes_per_channel =
|
||||||
bytes_per_sample * frame->header.channels;
|
bytes_per_sample * frame->header.channels;
|
||||||
const unsigned int max_samples = FLAC_CHUNK_SIZE / bytes_per_channel;
|
const unsigned int max_samples = FLAC_CHUNK_SIZE / bytes_per_channel;
|
||||||
@ -256,7 +255,7 @@ static FLAC__StreamDecoderWriteStatus flacWrite(const flac_decoder *dec,
|
|||||||
float timeChange;
|
float timeChange;
|
||||||
FLAC__uint64 newPosition = 0;
|
FLAC__uint64 newPosition = 0;
|
||||||
|
|
||||||
assert(data->dc->audioFormat.bits > 0);
|
assert(dc.audioFormat.bits > 0);
|
||||||
|
|
||||||
timeChange = ((float)samples) / frame->header.sample_rate;
|
timeChange = ((float)samples) / frame->header.sample_rate;
|
||||||
data->time += timeChange;
|
data->time += timeChange;
|
||||||
@ -292,7 +291,7 @@ static FLAC__StreamDecoderWriteStatus flacWrite(const flac_decoder *dec,
|
|||||||
FLAC__STREAM_DECODER_WRITE_STATUS_ABORT;
|
FLAC__STREAM_DECODER_WRITE_STATUS_ABORT;
|
||||||
}
|
}
|
||||||
data->chunk_length = 0;
|
data->chunk_length = 0;
|
||||||
if (data->dc->seek) {
|
if (dc.seek) {
|
||||||
return
|
return
|
||||||
FLAC__STREAM_DECODER_WRITE_STATUS_CONTINUE;
|
FLAC__STREAM_DECODER_WRITE_STATUS_CONTINUE;
|
||||||
}
|
}
|
||||||
@ -382,7 +381,7 @@ static MpdTag *flacTagDup(char *file)
|
|||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int flac_decode_internal(OutputBuffer * cb, DecoderControl * dc,
|
static int flac_decode_internal(OutputBuffer * cb,
|
||||||
InputStream * inStream, int is_ogg)
|
InputStream * inStream, int is_ogg)
|
||||||
{
|
{
|
||||||
flac_decoder *flacDec;
|
flac_decoder *flacDec;
|
||||||
@ -391,7 +390,7 @@ static int flac_decode_internal(OutputBuffer * cb, DecoderControl * dc,
|
|||||||
|
|
||||||
if (!(flacDec = flac_new()))
|
if (!(flacDec = flac_new()))
|
||||||
return -1;
|
return -1;
|
||||||
init_FlacData(&data, cb, dc, inStream);
|
init_FlacData(&data, cb, inStream);
|
||||||
|
|
||||||
#if defined(FLAC_API_VERSION_CURRENT) && FLAC_API_VERSION_CURRENT > 7
|
#if defined(FLAC_API_VERSION_CURRENT) && FLAC_API_VERSION_CURRENT > 7
|
||||||
if(!FLAC__stream_decoder_set_metadata_respond(flacDec, FLAC__METADATA_TYPE_VORBIS_COMMENT))
|
if(!FLAC__stream_decoder_set_metadata_respond(flacDec, FLAC__METADATA_TYPE_VORBIS_COMMENT))
|
||||||
@ -421,33 +420,33 @@ static int flac_decode_internal(OutputBuffer * cb, DecoderControl * dc,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
dc->state = DECODE_STATE_DECODE;
|
dc.state = DECODE_STATE_DECODE;
|
||||||
|
|
||||||
while (1) {
|
while (1) {
|
||||||
if (!flac_process_single(flacDec))
|
if (!flac_process_single(flacDec))
|
||||||
break;
|
break;
|
||||||
if (flac_get_state(flacDec) == flac_decoder_eof)
|
if (flac_get_state(flacDec) == flac_decoder_eof)
|
||||||
break;
|
break;
|
||||||
if (dc->seek) {
|
if (dc.seek) {
|
||||||
FLAC__uint64 sampleToSeek = dc->seekWhere *
|
FLAC__uint64 sampleToSeek = dc.seekWhere *
|
||||||
dc->audioFormat.sampleRate + 0.5;
|
dc.audioFormat.sampleRate + 0.5;
|
||||||
if (flac_seek_absolute(flacDec, sampleToSeek)) {
|
if (flac_seek_absolute(flacDec, sampleToSeek)) {
|
||||||
clearOutputBuffer(cb);
|
clearOutputBuffer(cb);
|
||||||
data.time = ((float)sampleToSeek) /
|
data.time = ((float)sampleToSeek) /
|
||||||
dc->audioFormat.sampleRate;
|
dc.audioFormat.sampleRate;
|
||||||
data.position = 0;
|
data.position = 0;
|
||||||
} else
|
} else
|
||||||
dc->seekError = 1;
|
dc.seekError = 1;
|
||||||
dc->seek = 0;
|
dc.seek = 0;
|
||||||
decoder_wakeup_player();
|
decoder_wakeup_player();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (!dc->stop) {
|
if (!dc.stop) {
|
||||||
flacPrintErroredState(flac_get_state(flacDec));
|
flacPrintErroredState(flac_get_state(flacDec));
|
||||||
flac_finish(flacDec);
|
flac_finish(flacDec);
|
||||||
}
|
}
|
||||||
/* send last little bit */
|
/* send last little bit */
|
||||||
if (data.chunk_length > 0 && !dc->stop) {
|
if (data.chunk_length > 0 && !dc.stop) {
|
||||||
flacSendChunk(&data);
|
flacSendChunk(&data);
|
||||||
flushOutputBuffer(data.cb);
|
flushOutputBuffer(data.cb);
|
||||||
}
|
}
|
||||||
@ -466,10 +465,9 @@ fail:
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int flac_decode(OutputBuffer * cb, DecoderControl * dc,
|
static int flac_decode(OutputBuffer * cb, InputStream * inStream)
|
||||||
InputStream * inStream)
|
|
||||||
{
|
{
|
||||||
return flac_decode_internal(cb, dc, inStream, 0);
|
return flac_decode_internal(cb, inStream, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
#if !defined(FLAC_API_VERSION_CURRENT) || FLAC_API_VERSION_CURRENT <= 7
|
#if !defined(FLAC_API_VERSION_CURRENT) || FLAC_API_VERSION_CURRENT <= 7
|
||||||
@ -508,10 +506,9 @@ out:
|
|||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int oggflac_decode(OutputBuffer * cb, DecoderControl * dc,
|
static int oggflac_decode(OutputBuffer * cb, InputStream * inStream)
|
||||||
InputStream * inStream)
|
|
||||||
{
|
{
|
||||||
return flac_decode_internal(cb, dc, inStream, 1);
|
return flac_decode_internal(cb, inStream, 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
static unsigned int oggflac_try_decode(InputStream * inStream)
|
static unsigned int oggflac_try_decode(InputStream * inStream)
|
||||||
|
@ -163,7 +163,7 @@ static void mod_close(mod_Data * data)
|
|||||||
free(data);
|
free(data);
|
||||||
}
|
}
|
||||||
|
|
||||||
static int mod_decode(OutputBuffer * cb, DecoderControl * dc, char *path)
|
static int mod_decode(OutputBuffer * cb, char *path)
|
||||||
{
|
{
|
||||||
mod_Data *data;
|
mod_Data *data;
|
||||||
float total_time = 0.0;
|
float total_time = 0.0;
|
||||||
@ -179,25 +179,25 @@ static int mod_decode(OutputBuffer * cb, DecoderControl * dc, char *path)
|
|||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
dc->totalTime = 0;
|
dc.totalTime = 0;
|
||||||
dc->audioFormat.bits = 16;
|
dc.audioFormat.bits = 16;
|
||||||
dc->audioFormat.sampleRate = 44100;
|
dc.audioFormat.sampleRate = 44100;
|
||||||
dc->audioFormat.channels = 2;
|
dc.audioFormat.channels = 2;
|
||||||
getOutputAudioFormat(&(dc->audioFormat), &(cb->audioFormat));
|
getOutputAudioFormat(&(dc.audioFormat), &(cb->audioFormat));
|
||||||
|
|
||||||
secPerByte =
|
secPerByte =
|
||||||
1.0 / ((dc->audioFormat.bits * dc->audioFormat.channels / 8.0) *
|
1.0 / ((dc.audioFormat.bits * dc.audioFormat.channels / 8.0) *
|
||||||
(float)dc->audioFormat.sampleRate);
|
(float)dc.audioFormat.sampleRate);
|
||||||
|
|
||||||
dc->state = DECODE_STATE_DECODE;
|
dc.state = DECODE_STATE_DECODE;
|
||||||
while (1) {
|
while (1) {
|
||||||
if (dc->seek) {
|
if (dc.seek) {
|
||||||
dc->seekError = 1;
|
dc.seekError = 1;
|
||||||
dc->seek = 0;
|
dc.seek = 0;
|
||||||
decoder_wakeup_player();
|
decoder_wakeup_player();
|
||||||
}
|
}
|
||||||
|
|
||||||
if (dc->stop)
|
if (dc.stop)
|
||||||
break;
|
break;
|
||||||
|
|
||||||
if (!Player_Active())
|
if (!Player_Active())
|
||||||
@ -205,7 +205,7 @@ static int mod_decode(OutputBuffer * cb, DecoderControl * dc, char *path)
|
|||||||
|
|
||||||
ret = VC_WriteBytes(data->audio_buffer, MIKMOD_FRAME_SIZE);
|
ret = VC_WriteBytes(data->audio_buffer, MIKMOD_FRAME_SIZE);
|
||||||
total_time += ret * secPerByte;
|
total_time += ret * secPerByte;
|
||||||
sendDataToOutputBuffer(cb, NULL, dc, 0,
|
sendDataToOutputBuffer(cb, NULL, 0,
|
||||||
(char *)data->audio_buffer, ret,
|
(char *)data->audio_buffer, ret,
|
||||||
total_time, 0, NULL);
|
total_time, 0, NULL);
|
||||||
}
|
}
|
||||||
|
@ -674,7 +674,7 @@ static int parse_lame(struct lame *lame, struct mad_bitptr *ptr, int *bitlen)
|
|||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int decodeFirstFrame(mp3DecodeData * data, DecoderControl * dc,
|
static int decodeFirstFrame(mp3DecodeData * data,
|
||||||
MpdTag ** tag, ReplayGainInfo ** replayGainInfo)
|
MpdTag ** tag, ReplayGainInfo ** replayGainInfo)
|
||||||
{
|
{
|
||||||
struct xing xing;
|
struct xing xing;
|
||||||
@ -689,13 +689,13 @@ static int decodeFirstFrame(mp3DecodeData * data, DecoderControl * dc,
|
|||||||
|
|
||||||
while (1) {
|
while (1) {
|
||||||
while ((ret = decodeNextFrameHeader(data, tag, replayGainInfo)) == DECODE_CONT &&
|
while ((ret = decodeNextFrameHeader(data, tag, replayGainInfo)) == DECODE_CONT &&
|
||||||
(!dc || !dc->stop));
|
!dc.stop);
|
||||||
if (ret == DECODE_BREAK || (dc && dc->stop)) return -1;
|
if (ret == DECODE_BREAK || dc.stop) return -1;
|
||||||
if (ret == DECODE_SKIP) continue;
|
if (ret == DECODE_SKIP) continue;
|
||||||
|
|
||||||
while ((ret = decodeNextFrame(data)) == DECODE_CONT &&
|
while ((ret = decodeNextFrame(data)) == DECODE_CONT &&
|
||||||
(!dc || !dc->stop));
|
!dc.stop);
|
||||||
if (ret == DECODE_BREAK || (dc && dc->stop)) return -1;
|
if (ret == DECODE_BREAK || dc.stop) return -1;
|
||||||
if (ret == DECODE_OK) break;
|
if (ret == DECODE_OK) break;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -787,7 +787,7 @@ static int getMp3TotalTime(char *file)
|
|||||||
if (openInputStream(&inStream, file) < 0)
|
if (openInputStream(&inStream, file) < 0)
|
||||||
return -1;
|
return -1;
|
||||||
initMp3DecodeData(&data, &inStream);
|
initMp3DecodeData(&data, &inStream);
|
||||||
if (decodeFirstFrame(&data, NULL, NULL, NULL) < 0)
|
if (decodeFirstFrame(&data, NULL, NULL) < 0)
|
||||||
ret = -1;
|
ret = -1;
|
||||||
else
|
else
|
||||||
ret = data.totalTime + 0.5;
|
ret = data.totalTime + 0.5;
|
||||||
@ -798,12 +798,12 @@ static int getMp3TotalTime(char *file)
|
|||||||
}
|
}
|
||||||
|
|
||||||
static int openMp3FromInputStream(InputStream * inStream, mp3DecodeData * data,
|
static int openMp3FromInputStream(InputStream * inStream, mp3DecodeData * data,
|
||||||
DecoderControl * dc, MpdTag ** tag,
|
MpdTag ** tag,
|
||||||
ReplayGainInfo ** replayGainInfo)
|
ReplayGainInfo ** replayGainInfo)
|
||||||
{
|
{
|
||||||
initMp3DecodeData(data, inStream);
|
initMp3DecodeData(data, inStream);
|
||||||
*tag = NULL;
|
*tag = NULL;
|
||||||
if (decodeFirstFrame(data, dc, tag, replayGainInfo) < 0) {
|
if (decodeFirstFrame(data, tag, replayGainInfo) < 0) {
|
||||||
mp3DecodeDataFinalize(data);
|
mp3DecodeDataFinalize(data);
|
||||||
if (tag && *tag)
|
if (tag && *tag)
|
||||||
freeMpdTag(*tag);
|
freeMpdTag(*tag);
|
||||||
@ -813,7 +813,7 @@ static int openMp3FromInputStream(InputStream * inStream, mp3DecodeData * data,
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int mp3Read(mp3DecodeData * data, OutputBuffer * cb, DecoderControl * dc,
|
static int mp3Read(mp3DecodeData * data, OutputBuffer * cb,
|
||||||
ReplayGainInfo ** replayGainInfo)
|
ReplayGainInfo ** replayGainInfo)
|
||||||
{
|
{
|
||||||
int samplesPerFrame;
|
int samplesPerFrame;
|
||||||
@ -852,11 +852,11 @@ static int mp3Read(mp3DecodeData * data, OutputBuffer * cb, DecoderControl * dc,
|
|||||||
data->muteFrame = 0;
|
data->muteFrame = 0;
|
||||||
break;
|
break;
|
||||||
case MUTEFRAME_SEEK:
|
case MUTEFRAME_SEEK:
|
||||||
if (dc->seekWhere <= data->elapsedTime) {
|
if (dc.seekWhere <= data->elapsedTime) {
|
||||||
data->outputPtr = data->outputBuffer;
|
data->outputPtr = data->outputBuffer;
|
||||||
clearOutputBuffer(cb);
|
clearOutputBuffer(cb);
|
||||||
data->muteFrame = 0;
|
data->muteFrame = 0;
|
||||||
dc->seek = 0;
|
dc.seek = 0;
|
||||||
decoder_wakeup_player();
|
decoder_wakeup_player();
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
@ -931,7 +931,6 @@ static int mp3Read(mp3DecodeData * data, OutputBuffer * cb, DecoderControl * dc,
|
|||||||
if (data->outputPtr >= data->outputBufferEnd) {
|
if (data->outputPtr >= data->outputBufferEnd) {
|
||||||
ret = sendDataToOutputBuffer(cb,
|
ret = sendDataToOutputBuffer(cb,
|
||||||
data->inStream,
|
data->inStream,
|
||||||
dc,
|
|
||||||
data->inStream->seekable,
|
data->inStream->seekable,
|
||||||
data->outputBuffer,
|
data->outputBuffer,
|
||||||
data->outputPtr - data->outputBuffer,
|
data->outputPtr - data->outputBuffer,
|
||||||
@ -952,10 +951,10 @@ static int mp3Read(mp3DecodeData * data, OutputBuffer * cb, DecoderControl * dc,
|
|||||||
|
|
||||||
data->decodedFirstFrame = 1;
|
data->decodedFirstFrame = 1;
|
||||||
|
|
||||||
if (dc->seek && data->inStream->seekable) {
|
if (dc.seek && data->inStream->seekable) {
|
||||||
long j = 0;
|
long j = 0;
|
||||||
data->muteFrame = MUTEFRAME_SEEK;
|
data->muteFrame = MUTEFRAME_SEEK;
|
||||||
while (j < data->highestFrame && dc->seekWhere >
|
while (j < data->highestFrame && dc.seekWhere >
|
||||||
((float)mad_timer_count(data->times[j],
|
((float)mad_timer_count(data->times[j],
|
||||||
MAD_UNITS_MILLISECONDS))
|
MAD_UNITS_MILLISECONDS))
|
||||||
/ 1000) {
|
/ 1000) {
|
||||||
@ -969,14 +968,14 @@ static int mp3Read(mp3DecodeData * data, OutputBuffer * cb, DecoderControl * dc,
|
|||||||
clearOutputBuffer(cb);
|
clearOutputBuffer(cb);
|
||||||
data->currentFrame = j;
|
data->currentFrame = j;
|
||||||
} else
|
} else
|
||||||
dc->seekError = 1;
|
dc.seekError = 1;
|
||||||
data->muteFrame = 0;
|
data->muteFrame = 0;
|
||||||
dc->seek = 0;
|
dc.seek = 0;
|
||||||
decoder_wakeup_player();
|
decoder_wakeup_player();
|
||||||
}
|
}
|
||||||
} else if (dc->seek && !data->inStream->seekable) {
|
} else if (dc.seek && !data->inStream->seekable) {
|
||||||
dc->seek = 0;
|
dc.seek = 0;
|
||||||
dc->seekError = 1;
|
dc.seekError = 1;
|
||||||
decoder_wakeup_player();
|
decoder_wakeup_player();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -986,22 +985,22 @@ static int mp3Read(mp3DecodeData * data, OutputBuffer * cb, DecoderControl * dc,
|
|||||||
while ((ret =
|
while ((ret =
|
||||||
decodeNextFrameHeader(data, NULL,
|
decodeNextFrameHeader(data, NULL,
|
||||||
replayGainInfo)) == DECODE_CONT
|
replayGainInfo)) == DECODE_CONT
|
||||||
&& !dc->stop) ;
|
&& !dc.stop) ;
|
||||||
if (ret == DECODE_BREAK || dc->stop || dc->seek)
|
if (ret == DECODE_BREAK || dc.stop || dc.seek)
|
||||||
break;
|
break;
|
||||||
else if (ret == DECODE_SKIP)
|
else if (ret == DECODE_SKIP)
|
||||||
skip = 1;
|
skip = 1;
|
||||||
if (!data->muteFrame) {
|
if (!data->muteFrame) {
|
||||||
while ((ret = decodeNextFrame(data)) == DECODE_CONT &&
|
while ((ret = decodeNextFrame(data)) == DECODE_CONT &&
|
||||||
!dc->stop && !dc->seek) ;
|
!dc.stop && !dc.seek) ;
|
||||||
if (ret == DECODE_BREAK || dc->stop || dc->seek)
|
if (ret == DECODE_BREAK || dc.stop || dc.seek)
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
if (!skip && ret == DECODE_OK)
|
if (!skip && ret == DECODE_OK)
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (dc->stop)
|
if (dc.stop)
|
||||||
return DECODE_BREAK;
|
return DECODE_BREAK;
|
||||||
|
|
||||||
return ret;
|
return ret;
|
||||||
@ -1015,16 +1014,15 @@ static void initAudioFormatFromMp3DecodeData(mp3DecodeData * data,
|
|||||||
af->channels = MAD_NCHANNELS(&(data->frame).header);
|
af->channels = MAD_NCHANNELS(&(data->frame).header);
|
||||||
}
|
}
|
||||||
|
|
||||||
static int mp3_decode(OutputBuffer * cb, DecoderControl * dc,
|
static int mp3_decode(OutputBuffer * cb, InputStream * inStream)
|
||||||
InputStream * inStream)
|
|
||||||
{
|
{
|
||||||
mp3DecodeData data;
|
mp3DecodeData data;
|
||||||
MpdTag *tag = NULL;
|
MpdTag *tag = NULL;
|
||||||
ReplayGainInfo *replayGainInfo = NULL;
|
ReplayGainInfo *replayGainInfo = NULL;
|
||||||
|
|
||||||
if (openMp3FromInputStream(inStream, &data, dc, &tag, &replayGainInfo) <
|
if (openMp3FromInputStream(inStream, &data, &tag, &replayGainInfo) <
|
||||||
0) {
|
0) {
|
||||||
if (!dc->stop) {
|
if (!dc.stop) {
|
||||||
ERROR
|
ERROR
|
||||||
("Input does not appear to be a mp3 bit stream.\n");
|
("Input does not appear to be a mp3 bit stream.\n");
|
||||||
return -1;
|
return -1;
|
||||||
@ -1032,10 +1030,10 @@ static int mp3_decode(OutputBuffer * cb, DecoderControl * dc,
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
initAudioFormatFromMp3DecodeData(&data, &(dc->audioFormat));
|
initAudioFormatFromMp3DecodeData(&data, &(dc.audioFormat));
|
||||||
getOutputAudioFormat(&(dc->audioFormat), &(cb->audioFormat));
|
getOutputAudioFormat(&(dc.audioFormat), &(cb->audioFormat));
|
||||||
|
|
||||||
dc->totalTime = data.totalTime;
|
dc.totalTime = data.totalTime;
|
||||||
|
|
||||||
if (inStream->metaTitle) {
|
if (inStream->metaTitle) {
|
||||||
if (tag)
|
if (tag)
|
||||||
@ -1062,12 +1060,12 @@ static int mp3_decode(OutputBuffer * cb, DecoderControl * dc,
|
|||||||
freeMpdTag(tag);
|
freeMpdTag(tag);
|
||||||
}
|
}
|
||||||
|
|
||||||
dc->state = DECODE_STATE_DECODE;
|
dc.state = DECODE_STATE_DECODE;
|
||||||
|
|
||||||
while (mp3Read(&data, cb, dc, &replayGainInfo) != DECODE_BREAK) ;
|
while (mp3Read(&data, cb, &replayGainInfo) != DECODE_BREAK) ;
|
||||||
/* send last little bit if not dc->stop */
|
/* send last little bit if not dc.stop */
|
||||||
if (!dc->stop && data.outputPtr != data.outputBuffer && data.flush) {
|
if (!dc.stop && data.outputPtr != data.outputBuffer && data.flush) {
|
||||||
sendDataToOutputBuffer(cb, NULL, dc,
|
sendDataToOutputBuffer(cb, NULL,
|
||||||
data.inStream->seekable,
|
data.inStream->seekable,
|
||||||
data.outputBuffer,
|
data.outputBuffer,
|
||||||
data.outputPtr - data.outputBuffer,
|
data.outputPtr - data.outputBuffer,
|
||||||
@ -1078,9 +1076,9 @@ static int mp3_decode(OutputBuffer * cb, DecoderControl * dc,
|
|||||||
if (replayGainInfo)
|
if (replayGainInfo)
|
||||||
freeReplayGainInfo(replayGainInfo);
|
freeReplayGainInfo(replayGainInfo);
|
||||||
|
|
||||||
if (dc->seek && data.muteFrame == MUTEFRAME_SEEK) {
|
if (dc.seek && data.muteFrame == MUTEFRAME_SEEK) {
|
||||||
clearOutputBuffer(cb);
|
clearOutputBuffer(cb);
|
||||||
dc->seek = 0;
|
dc.seek = 0;
|
||||||
decoder_wakeup_player();
|
decoder_wakeup_player();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -84,8 +84,7 @@ static uint32_t mp4_inputStreamSeekCallback(void *inStream, uint64_t position)
|
|||||||
return seekInputStream((InputStream *) inStream, position, SEEK_SET);
|
return seekInputStream((InputStream *) inStream, position, SEEK_SET);
|
||||||
}
|
}
|
||||||
|
|
||||||
static int mp4_decode(OutputBuffer * cb, DecoderControl * dc,
|
static int mp4_decode(OutputBuffer * cb, InputStream * inStream)
|
||||||
InputStream * inStream)
|
|
||||||
{
|
{
|
||||||
mp4ff_t *mp4fh;
|
mp4ff_t *mp4fh;
|
||||||
mp4ff_callback_t *mp4cb;
|
mp4ff_callback_t *mp4cb;
|
||||||
@ -146,7 +145,7 @@ static int mp4_decode(OutputBuffer * cb, DecoderControl * dc,
|
|||||||
#endif
|
#endif
|
||||||
faacDecSetConfiguration(decoder, config);
|
faacDecSetConfiguration(decoder, config);
|
||||||
|
|
||||||
dc->audioFormat.bits = 16;
|
dc.audioFormat.bits = 16;
|
||||||
|
|
||||||
mp4Buffer = NULL;
|
mp4Buffer = NULL;
|
||||||
mp4BufferSize = 0;
|
mp4BufferSize = 0;
|
||||||
@ -161,8 +160,8 @@ static int mp4_decode(OutputBuffer * cb, DecoderControl * dc,
|
|||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
dc->audioFormat.sampleRate = sampleRate;
|
dc.audioFormat.sampleRate = sampleRate;
|
||||||
dc->audioFormat.channels = channels;
|
dc.audioFormat.channels = channels;
|
||||||
file_time = mp4ff_get_track_duration_use_offsets(mp4fh, track);
|
file_time = mp4ff_get_track_duration_use_offsets(mp4fh, track);
|
||||||
scale = mp4ff_time_scale(mp4fh, track);
|
scale = mp4ff_time_scale(mp4fh, track);
|
||||||
|
|
||||||
@ -176,7 +175,7 @@ static int mp4_decode(OutputBuffer * cb, DecoderControl * dc,
|
|||||||
free(mp4cb);
|
free(mp4cb);
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
dc->totalTime = ((float)file_time) / scale;
|
dc.totalTime = ((float)file_time) / scale;
|
||||||
|
|
||||||
numSamples = mp4ff_num_samples(mp4fh, track);
|
numSamples = mp4ff_num_samples(mp4fh, track);
|
||||||
|
|
||||||
@ -185,13 +184,13 @@ static int mp4_decode(OutputBuffer * cb, DecoderControl * dc,
|
|||||||
seekTable = xmalloc(sizeof(float) * numSamples);
|
seekTable = xmalloc(sizeof(float) * numSamples);
|
||||||
|
|
||||||
for (sampleId = 0; sampleId < numSamples && !eof; sampleId++) {
|
for (sampleId = 0; sampleId < numSamples && !eof; sampleId++) {
|
||||||
if (dc->seek)
|
if (dc.seek)
|
||||||
seeking = 1;
|
seeking = 1;
|
||||||
|
|
||||||
if (seeking && seekTableEnd > 1 &&
|
if (seeking && seekTableEnd > 1 &&
|
||||||
seekTable[seekTableEnd] >= dc->seekWhere) {
|
seekTable[seekTableEnd] >= dc.seekWhere) {
|
||||||
int i = 2;
|
int i = 2;
|
||||||
while (seekTable[i] < dc->seekWhere)
|
while (seekTable[i] < dc.seekWhere)
|
||||||
i++;
|
i++;
|
||||||
sampleId = i - 1;
|
sampleId = i - 1;
|
||||||
file_time = seekTable[sampleId];
|
file_time = seekTable[sampleId];
|
||||||
@ -213,14 +212,14 @@ static int mp4_decode(OutputBuffer * cb, DecoderControl * dc,
|
|||||||
dur -= offset;
|
dur -= offset;
|
||||||
file_time += ((float)dur) / scale;
|
file_time += ((float)dur) / scale;
|
||||||
|
|
||||||
if (seeking && file_time > dc->seekWhere)
|
if (seeking && file_time > dc.seekWhere)
|
||||||
seekPositionFound = 1;
|
seekPositionFound = 1;
|
||||||
|
|
||||||
if (seeking && seekPositionFound) {
|
if (seeking && seekPositionFound) {
|
||||||
seekPositionFound = 0;
|
seekPositionFound = 0;
|
||||||
clearOutputBuffer(cb);
|
clearOutputBuffer(cb);
|
||||||
seeking = 0;
|
seeking = 0;
|
||||||
dc->seek = 0;
|
dc.seek = 0;
|
||||||
decoder_wakeup_player();
|
decoder_wakeup_player();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -248,16 +247,16 @@ static int mp4_decode(OutputBuffer * cb, DecoderControl * dc,
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (dc->state != DECODE_STATE_DECODE) {
|
if (dc.state != DECODE_STATE_DECODE) {
|
||||||
channels = frameInfo.channels;
|
channels = frameInfo.channels;
|
||||||
#ifdef HAVE_FAACDECFRAMEINFO_SAMPLERATE
|
#ifdef HAVE_FAACDECFRAMEINFO_SAMPLERATE
|
||||||
scale = frameInfo.samplerate;
|
scale = frameInfo.samplerate;
|
||||||
#endif
|
#endif
|
||||||
dc->audioFormat.sampleRate = scale;
|
dc.audioFormat.sampleRate = scale;
|
||||||
dc->audioFormat.channels = frameInfo.channels;
|
dc.audioFormat.channels = frameInfo.channels;
|
||||||
getOutputAudioFormat(&(dc->audioFormat),
|
getOutputAudioFormat(&(dc.audioFormat),
|
||||||
&(cb->audioFormat));
|
&(cb->audioFormat));
|
||||||
dc->state = DECODE_STATE_DECODE;
|
dc.state = DECODE_STATE_DECODE;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (channels * (unsigned long)(dur + offset) > frameInfo.samples) {
|
if (channels * (unsigned long)(dur + offset) > frameInfo.samples) {
|
||||||
@ -278,10 +277,10 @@ static int mp4_decode(OutputBuffer * cb, DecoderControl * dc,
|
|||||||
|
|
||||||
sampleBuffer += offset * channels * 2;
|
sampleBuffer += offset * channels * 2;
|
||||||
|
|
||||||
sendDataToOutputBuffer(cb, inStream, dc, 1, sampleBuffer,
|
sendDataToOutputBuffer(cb, inStream, 1, sampleBuffer,
|
||||||
sampleBufferLen, file_time,
|
sampleBufferLen, file_time,
|
||||||
bitRate, NULL);
|
bitRate, NULL);
|
||||||
if (dc->stop) {
|
if (dc.stop) {
|
||||||
eof = 1;
|
eof = 1;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@ -292,12 +291,12 @@ static int mp4_decode(OutputBuffer * cb, DecoderControl * dc,
|
|||||||
mp4ff_close(mp4fh);
|
mp4ff_close(mp4fh);
|
||||||
free(mp4cb);
|
free(mp4cb);
|
||||||
|
|
||||||
if (dc->state != DECODE_STATE_DECODE)
|
if (dc.state != DECODE_STATE_DECODE)
|
||||||
return -1;
|
return -1;
|
||||||
|
|
||||||
if (dc->seek && seeking) {
|
if (dc.seek && seeking) {
|
||||||
clearOutputBuffer(cb);
|
clearOutputBuffer(cb);
|
||||||
dc->seek = 0;
|
dc.seek = 0;
|
||||||
decoder_wakeup_player();
|
decoder_wakeup_player();
|
||||||
}
|
}
|
||||||
flushOutputBuffer(cb);
|
flushOutputBuffer(cb);
|
||||||
|
@ -33,7 +33,6 @@
|
|||||||
|
|
||||||
typedef struct _MpcCallbackData {
|
typedef struct _MpcCallbackData {
|
||||||
InputStream *inStream;
|
InputStream *inStream;
|
||||||
DecoderControl *dc;
|
|
||||||
} MpcCallbackData;
|
} 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)
|
||||||
@ -43,10 +42,9 @@ static mpc_int32_t mpc_read_cb(void *vdata, void *ptr, mpc_int32_t size)
|
|||||||
|
|
||||||
while (1) {
|
while (1) {
|
||||||
ret = readFromInputStream(data->inStream, ptr, 1, size);
|
ret = readFromInputStream(data->inStream, ptr, 1, size);
|
||||||
if (ret == 0 && !inputStreamAtEOF(data->inStream) &&
|
if (ret == 0 && !inputStreamAtEOF(data->inStream) && !dc.stop)
|
||||||
(data->dc && !data->dc->stop)) {
|
|
||||||
my_usleep(10000);
|
my_usleep(10000);
|
||||||
} else
|
else
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -113,8 +111,7 @@ static inline mpd_sint16 convertSample(MPC_SAMPLE_FORMAT sample)
|
|||||||
return val;
|
return val;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int mpc_decode(OutputBuffer * cb, DecoderControl * dc,
|
static int mpc_decode(OutputBuffer * cb, InputStream * inStream)
|
||||||
InputStream * inStream)
|
|
||||||
{
|
{
|
||||||
mpc_decoder decoder;
|
mpc_decoder decoder;
|
||||||
mpc_reader reader;
|
mpc_reader reader;
|
||||||
@ -139,7 +136,6 @@ static int mpc_decode(OutputBuffer * cb, DecoderControl * dc,
|
|||||||
ReplayGainInfo *replayGainInfo = NULL;
|
ReplayGainInfo *replayGainInfo = NULL;
|
||||||
|
|
||||||
data.inStream = inStream;
|
data.inStream = inStream;
|
||||||
data.dc = dc;
|
|
||||||
|
|
||||||
reader.read = mpc_read_cb;
|
reader.read = mpc_read_cb;
|
||||||
reader.seek = mpc_seek_cb;
|
reader.seek = mpc_seek_cb;
|
||||||
@ -151,7 +147,7 @@ static int mpc_decode(OutputBuffer * cb, DecoderControl * dc,
|
|||||||
mpc_streaminfo_init(&info);
|
mpc_streaminfo_init(&info);
|
||||||
|
|
||||||
if ((ret = mpc_streaminfo_read(&info, &reader)) != ERROR_CODE_OK) {
|
if ((ret = mpc_streaminfo_read(&info, &reader)) != ERROR_CODE_OK) {
|
||||||
if (!dc->stop) {
|
if (!dc.stop) {
|
||||||
ERROR("Not a valid musepack stream\n");
|
ERROR("Not a valid musepack stream\n");
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
@ -161,20 +157,20 @@ static int mpc_decode(OutputBuffer * cb, DecoderControl * dc,
|
|||||||
mpc_decoder_setup(&decoder, &reader);
|
mpc_decoder_setup(&decoder, &reader);
|
||||||
|
|
||||||
if (!mpc_decoder_initialize(&decoder, &info)) {
|
if (!mpc_decoder_initialize(&decoder, &info)) {
|
||||||
if (!dc->stop) {
|
if (!dc.stop) {
|
||||||
ERROR("Not a valid musepack stream\n");
|
ERROR("Not a valid musepack stream\n");
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
dc->totalTime = mpc_streaminfo_get_length(&info);
|
dc.totalTime = mpc_streaminfo_get_length(&info);
|
||||||
|
|
||||||
dc->audioFormat.bits = 16;
|
dc.audioFormat.bits = 16;
|
||||||
dc->audioFormat.channels = info.channels;
|
dc.audioFormat.channels = info.channels;
|
||||||
dc->audioFormat.sampleRate = info.sample_freq;
|
dc.audioFormat.sampleRate = info.sample_freq;
|
||||||
|
|
||||||
getOutputAudioFormat(&(dc->audioFormat), &(cb->audioFormat));
|
getOutputAudioFormat(&(dc.audioFormat), &(cb->audioFormat));
|
||||||
|
|
||||||
replayGainInfo = newReplayGainInfo();
|
replayGainInfo = newReplayGainInfo();
|
||||||
replayGainInfo->albumGain = info.gain_album * 0.01;
|
replayGainInfo->albumGain = info.gain_album * 0.01;
|
||||||
@ -182,18 +178,18 @@ static int mpc_decode(OutputBuffer * cb, DecoderControl * dc,
|
|||||||
replayGainInfo->trackGain = info.gain_title * 0.01;
|
replayGainInfo->trackGain = info.gain_title * 0.01;
|
||||||
replayGainInfo->trackPeak = info.peak_title / 32767.0;
|
replayGainInfo->trackPeak = info.peak_title / 32767.0;
|
||||||
|
|
||||||
dc->state = DECODE_STATE_DECODE;
|
dc.state = DECODE_STATE_DECODE;
|
||||||
|
|
||||||
while (!eof) {
|
while (!eof) {
|
||||||
if (dc->seek) {
|
if (dc.seek) {
|
||||||
samplePos = dc->seekWhere * dc->audioFormat.sampleRate;
|
samplePos = dc.seekWhere * dc.audioFormat.sampleRate;
|
||||||
if (mpc_decoder_seek_sample(&decoder, samplePos)) {
|
if (mpc_decoder_seek_sample(&decoder, samplePos)) {
|
||||||
clearOutputBuffer(cb);
|
clearOutputBuffer(cb);
|
||||||
s16 = (mpd_sint16 *) chunk;
|
s16 = (mpd_sint16 *) chunk;
|
||||||
chunkpos = 0;
|
chunkpos = 0;
|
||||||
} else
|
} else
|
||||||
dc->seekError = 1;
|
dc.seekError = 1;
|
||||||
dc->seek = 0;
|
dc.seek = 0;
|
||||||
decoder_wakeup_player();
|
decoder_wakeup_player();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -202,7 +198,7 @@ static int mpc_decode(OutputBuffer * cb, DecoderControl * dc,
|
|||||||
ret = mpc_decoder_decode(&decoder, sample_buffer,
|
ret = mpc_decoder_decode(&decoder, sample_buffer,
|
||||||
&vbrUpdateAcc, &vbrUpdateBits);
|
&vbrUpdateAcc, &vbrUpdateBits);
|
||||||
|
|
||||||
if (ret <= 0 || dc->stop) {
|
if (ret <= 0 || dc.stop) {
|
||||||
eof = 1;
|
eof = 1;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@ -220,12 +216,12 @@ static int mpc_decode(OutputBuffer * cb, DecoderControl * dc,
|
|||||||
|
|
||||||
if (chunkpos >= MPC_CHUNK_SIZE) {
|
if (chunkpos >= MPC_CHUNK_SIZE) {
|
||||||
total_time = ((float)samplePos) /
|
total_time = ((float)samplePos) /
|
||||||
dc->audioFormat.sampleRate;
|
dc.audioFormat.sampleRate;
|
||||||
|
|
||||||
bitRate = vbrUpdateBits *
|
bitRate = vbrUpdateBits *
|
||||||
dc->audioFormat.sampleRate / 1152 / 1000;
|
dc.audioFormat.sampleRate / 1152 / 1000;
|
||||||
|
|
||||||
sendDataToOutputBuffer(cb, inStream, dc,
|
sendDataToOutputBuffer(cb, inStream,
|
||||||
inStream->seekable,
|
inStream->seekable,
|
||||||
chunk, chunkpos,
|
chunk, chunkpos,
|
||||||
total_time,
|
total_time,
|
||||||
@ -233,7 +229,7 @@ static int mpc_decode(OutputBuffer * cb, DecoderControl * dc,
|
|||||||
|
|
||||||
chunkpos = 0;
|
chunkpos = 0;
|
||||||
s16 = (mpd_sint16 *) chunk;
|
s16 = (mpd_sint16 *) chunk;
|
||||||
if (dc->stop) {
|
if (dc.stop) {
|
||||||
eof = 1;
|
eof = 1;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@ -241,13 +237,13 @@ static int mpc_decode(OutputBuffer * cb, DecoderControl * dc,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!dc->stop && chunkpos > 0) {
|
if (!dc.stop && chunkpos > 0) {
|
||||||
total_time = ((float)samplePos) / dc->audioFormat.sampleRate;
|
total_time = ((float)samplePos) / dc.audioFormat.sampleRate;
|
||||||
|
|
||||||
bitRate =
|
bitRate =
|
||||||
vbrUpdateBits * dc->audioFormat.sampleRate / 1152 / 1000;
|
vbrUpdateBits * dc.audioFormat.sampleRate / 1152 / 1000;
|
||||||
|
|
||||||
sendDataToOutputBuffer(cb, NULL, dc, inStream->seekable,
|
sendDataToOutputBuffer(cb, NULL, inStream->seekable,
|
||||||
chunk, chunkpos, total_time, bitRate,
|
chunk, chunkpos, total_time, bitRate,
|
||||||
replayGainInfo);
|
replayGainInfo);
|
||||||
}
|
}
|
||||||
@ -269,7 +265,6 @@ static float mpcGetTime(char *file)
|
|||||||
MpcCallbackData data;
|
MpcCallbackData data;
|
||||||
|
|
||||||
data.inStream = &inStream;
|
data.inStream = &inStream;
|
||||||
data.dc = NULL;
|
|
||||||
|
|
||||||
reader.read = mpc_read_cb;
|
reader.read = mpc_read_cb;
|
||||||
reader.seek = mpc_seek_cb;
|
reader.seek = mpc_seek_cb;
|
||||||
|
@ -56,14 +56,14 @@ static OggFLAC__SeekableStreamDecoderReadStatus of_read_cb(const
|
|||||||
while (1) {
|
while (1) {
|
||||||
r = readFromInputStream(data->inStream, (void *)buf, 1, *bytes);
|
r = readFromInputStream(data->inStream, (void *)buf, 1, *bytes);
|
||||||
if (r == 0 && !inputStreamAtEOF(data->inStream) &&
|
if (r == 0 && !inputStreamAtEOF(data->inStream) &&
|
||||||
!data->dc->stop)
|
!dc.stop)
|
||||||
my_usleep(10000);
|
my_usleep(10000);
|
||||||
else
|
else
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
*bytes = r;
|
*bytes = r;
|
||||||
|
|
||||||
if (r == 0 && !inputStreamAtEOF(data->inStream) && !data->dc->stop)
|
if (r == 0 && !inputStreamAtEOF(data->inStream) && !dc.stop)
|
||||||
return OggFLAC__SEEKABLE_STREAM_DECODER_READ_STATUS_ERROR;
|
return OggFLAC__SEEKABLE_STREAM_DECODER_READ_STATUS_ERROR;
|
||||||
|
|
||||||
return OggFLAC__SEEKABLE_STREAM_DECODER_READ_STATUS_OK;
|
return OggFLAC__SEEKABLE_STREAM_DECODER_READ_STATUS_OK;
|
||||||
@ -193,14 +193,14 @@ static FLAC__StreamDecoderWriteStatus oggflacWrite(const
|
|||||||
c_chan++) {
|
c_chan++) {
|
||||||
u16 = buf[c_chan][c_samp];
|
u16 = buf[c_chan][c_samp];
|
||||||
uc = (unsigned char *)&u16;
|
uc = (unsigned char *)&u16;
|
||||||
for (i = 0; i < (data->dc->audioFormat.bits / 8); i++) {
|
for (i = 0; i < (dc.audioFormat.bits / 8); i++) {
|
||||||
if (data->chunk_length >= FLAC_CHUNK_SIZE) {
|
if (data->chunk_length >= FLAC_CHUNK_SIZE) {
|
||||||
if (flacSendChunk(data) < 0) {
|
if (flacSendChunk(data) < 0) {
|
||||||
return
|
return
|
||||||
FLAC__STREAM_DECODER_WRITE_STATUS_ABORT;
|
FLAC__STREAM_DECODER_WRITE_STATUS_ABORT;
|
||||||
}
|
}
|
||||||
data->chunk_length = 0;
|
data->chunk_length = 0;
|
||||||
if (data->dc->seek) {
|
if (dc.seek) {
|
||||||
return
|
return
|
||||||
FLAC__STREAM_DECODER_WRITE_STATUS_CONTINUE;
|
FLAC__STREAM_DECODER_WRITE_STATUS_CONTINUE;
|
||||||
}
|
}
|
||||||
@ -336,21 +336,20 @@ static unsigned int oggflac_try_decode(InputStream * inStream)
|
|||||||
return (ogg_stream_type_detect(inStream) == FLAC) ? 1 : 0;
|
return (ogg_stream_type_detect(inStream) == FLAC) ? 1 : 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int oggflac_decode(OutputBuffer * cb, DecoderControl * dc,
|
static int oggflac_decode(OutputBuffer * cb, InputStream * inStream)
|
||||||
InputStream * inStream)
|
|
||||||
{
|
{
|
||||||
OggFLAC__SeekableStreamDecoder *decoder = NULL;
|
OggFLAC__SeekableStreamDecoder *decoder = NULL;
|
||||||
FlacData data;
|
FlacData data;
|
||||||
int ret = 0;
|
int ret = 0;
|
||||||
|
|
||||||
init_FlacData(&data, cb, dc, inStream);
|
init_FlacData(&data, cb, inStream);
|
||||||
|
|
||||||
if (!(decoder = full_decoder_init_and_read_metadata(&data, 0))) {
|
if (!(decoder = full_decoder_init_and_read_metadata(&data, 0))) {
|
||||||
ret = -1;
|
ret = -1;
|
||||||
goto fail;
|
goto fail;
|
||||||
}
|
}
|
||||||
|
|
||||||
dc->state = DECODE_STATE_DECODE;
|
dc.state = DECODE_STATE_DECODE;
|
||||||
|
|
||||||
while (1) {
|
while (1) {
|
||||||
OggFLAC__seekable_stream_decoder_process_single(decoder);
|
OggFLAC__seekable_stream_decoder_process_single(decoder);
|
||||||
@ -358,29 +357,29 @@ static int oggflac_decode(OutputBuffer * cb, DecoderControl * dc,
|
|||||||
OggFLAC__SEEKABLE_STREAM_DECODER_OK) {
|
OggFLAC__SEEKABLE_STREAM_DECODER_OK) {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
if (dc->seek) {
|
if (dc.seek) {
|
||||||
FLAC__uint64 sampleToSeek = dc->seekWhere *
|
FLAC__uint64 sampleToSeek = dc.seekWhere *
|
||||||
dc->audioFormat.sampleRate + 0.5;
|
dc.audioFormat.sampleRate + 0.5;
|
||||||
if (OggFLAC__seekable_stream_decoder_seek_absolute
|
if (OggFLAC__seekable_stream_decoder_seek_absolute
|
||||||
(decoder, sampleToSeek)) {
|
(decoder, sampleToSeek)) {
|
||||||
clearOutputBuffer(cb);
|
clearOutputBuffer(cb);
|
||||||
data.time = ((float)sampleToSeek) /
|
data.time = ((float)sampleToSeek) /
|
||||||
dc->audioFormat.sampleRate;
|
dc.audioFormat.sampleRate;
|
||||||
data.position = 0;
|
data.position = 0;
|
||||||
} else
|
} else
|
||||||
dc->seekError = 1;
|
dc.seekError = 1;
|
||||||
dc->seek = 0;
|
dc.seek = 0;
|
||||||
decoder_wakeup_player();
|
decoder_wakeup_player();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!dc->stop) {
|
if (!dc.stop) {
|
||||||
oggflacPrintErroredState
|
oggflacPrintErroredState
|
||||||
(OggFLAC__seekable_stream_decoder_get_state(decoder));
|
(OggFLAC__seekable_stream_decoder_get_state(decoder));
|
||||||
OggFLAC__seekable_stream_decoder_finish(decoder);
|
OggFLAC__seekable_stream_decoder_finish(decoder);
|
||||||
}
|
}
|
||||||
/* send last little bit */
|
/* send last little bit */
|
||||||
if (data.chunk_length > 0 && !dc->stop) {
|
if (data.chunk_length > 0 && !dc.stop) {
|
||||||
flacSendChunk(&data);
|
flacSendChunk(&data);
|
||||||
flushOutputBuffer(data.cb);
|
flushOutputBuffer(data.cb);
|
||||||
}
|
}
|
||||||
|
@ -56,7 +56,6 @@
|
|||||||
|
|
||||||
typedef struct _OggCallbackData {
|
typedef struct _OggCallbackData {
|
||||||
InputStream *inStream;
|
InputStream *inStream;
|
||||||
DecoderControl *dc;
|
|
||||||
} OggCallbackData;
|
} 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)
|
||||||
@ -67,7 +66,7 @@ static size_t ogg_read_cb(void *ptr, size_t size, size_t nmemb, void *vdata)
|
|||||||
while (1) {
|
while (1) {
|
||||||
ret = readFromInputStream(data->inStream, ptr, size, nmemb);
|
ret = readFromInputStream(data->inStream, ptr, size, nmemb);
|
||||||
if (ret == 0 && !inputStreamAtEOF(data->inStream) &&
|
if (ret == 0 && !inputStreamAtEOF(data->inStream) &&
|
||||||
!data->dc->stop) {
|
!dc.stop) {
|
||||||
my_usleep(10000);
|
my_usleep(10000);
|
||||||
} else
|
} else
|
||||||
break;
|
break;
|
||||||
@ -81,7 +80,7 @@ static size_t ogg_read_cb(void *ptr, size_t size, size_t nmemb, void *vdata)
|
|||||||
static int ogg_seek_cb(void *vdata, ogg_int64_t offset, int whence)
|
static int ogg_seek_cb(void *vdata, ogg_int64_t offset, int whence)
|
||||||
{
|
{
|
||||||
const OggCallbackData *data = (const OggCallbackData *) vdata;
|
const OggCallbackData *data = (const OggCallbackData *) vdata;
|
||||||
if(data->dc->stop)
|
if (dc.stop)
|
||||||
return -1;
|
return -1;
|
||||||
return seekInputStream(data->inStream, offset, whence);
|
return seekInputStream(data->inStream, offset, whence);
|
||||||
}
|
}
|
||||||
@ -217,8 +216,7 @@ static void putOggCommentsIntoOutputBuffer(OutputBuffer * cb, char *streamName,
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* public */
|
/* public */
|
||||||
static int oggvorbis_decode(OutputBuffer * cb, DecoderControl * dc,
|
static int oggvorbis_decode(OutputBuffer * cb, InputStream * inStream)
|
||||||
InputStream * inStream)
|
|
||||||
{
|
{
|
||||||
OggVorbis_File vf;
|
OggVorbis_File vf;
|
||||||
ov_callbacks callbacks;
|
ov_callbacks callbacks;
|
||||||
@ -236,14 +234,13 @@ static int oggvorbis_decode(OutputBuffer * cb, DecoderControl * dc,
|
|||||||
const char *errorStr;
|
const char *errorStr;
|
||||||
|
|
||||||
data.inStream = inStream;
|
data.inStream = inStream;
|
||||||
data.dc = dc;
|
|
||||||
|
|
||||||
callbacks.read_func = ogg_read_cb;
|
callbacks.read_func = ogg_read_cb;
|
||||||
callbacks.seek_func = ogg_seek_cb;
|
callbacks.seek_func = ogg_seek_cb;
|
||||||
callbacks.close_func = ogg_close_cb;
|
callbacks.close_func = ogg_close_cb;
|
||||||
callbacks.tell_func = ogg_tell_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) {
|
||||||
if (!dc->stop) {
|
if (!dc.stop) {
|
||||||
switch (ret) {
|
switch (ret) {
|
||||||
case OV_EREAD:
|
case OV_EREAD:
|
||||||
errorStr = "read error";
|
errorStr = "read error";
|
||||||
@ -270,19 +267,19 @@ static int oggvorbis_decode(OutputBuffer * cb, DecoderControl * dc,
|
|||||||
}
|
}
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
dc->totalTime = ov_time_total(&vf, -1);
|
dc.totalTime = ov_time_total(&vf, -1);
|
||||||
if (dc->totalTime < 0)
|
if (dc.totalTime < 0)
|
||||||
dc->totalTime = 0;
|
dc.totalTime = 0;
|
||||||
dc->audioFormat.bits = 16;
|
dc.audioFormat.bits = 16;
|
||||||
|
|
||||||
while (1) {
|
while (1) {
|
||||||
if (dc->seek) {
|
if (dc.seek) {
|
||||||
if (0 == ov_time_seek_page(&vf, dc->seekWhere)) {
|
if (0 == ov_time_seek_page(&vf, dc.seekWhere)) {
|
||||||
clearOutputBuffer(cb);
|
clearOutputBuffer(cb);
|
||||||
chunkpos = 0;
|
chunkpos = 0;
|
||||||
} else
|
} else
|
||||||
dc->seekError = 1;
|
dc.seekError = 1;
|
||||||
dc->seek = 0;
|
dc.seek = 0;
|
||||||
decoder_wakeup_player();
|
decoder_wakeup_player();
|
||||||
}
|
}
|
||||||
ret = ov_read(&vf, chunk + chunkpos,
|
ret = ov_read(&vf, chunk + chunkpos,
|
||||||
@ -291,12 +288,12 @@ static int oggvorbis_decode(OutputBuffer * cb, DecoderControl * dc,
|
|||||||
if (current_section != prev_section) {
|
if (current_section != prev_section) {
|
||||||
/*printf("new song!\n"); */
|
/*printf("new song!\n"); */
|
||||||
vorbis_info *vi = ov_info(&vf, -1);
|
vorbis_info *vi = ov_info(&vf, -1);
|
||||||
dc->audioFormat.channels = vi->channels;
|
dc.audioFormat.channels = vi->channels;
|
||||||
dc->audioFormat.sampleRate = vi->rate;
|
dc.audioFormat.sampleRate = vi->rate;
|
||||||
if (dc->state == DECODE_STATE_START) {
|
if (dc.state == DECODE_STATE_START) {
|
||||||
getOutputAudioFormat(&(dc->audioFormat),
|
getOutputAudioFormat(&(dc.audioFormat),
|
||||||
&(cb->audioFormat));
|
&(cb->audioFormat));
|
||||||
dc->state = DECODE_STATE_DECODE;
|
dc.state = DECODE_STATE_DECODE;
|
||||||
}
|
}
|
||||||
comments = ov_comment(&vf, -1)->user_comments;
|
comments = ov_comment(&vf, -1)->user_comments;
|
||||||
putOggCommentsIntoOutputBuffer(cb, inStream->metaName,
|
putOggCommentsIntoOutputBuffer(cb, inStream->metaName,
|
||||||
@ -319,20 +316,20 @@ static int oggvorbis_decode(OutputBuffer * cb, DecoderControl * dc,
|
|||||||
if ((test = ov_bitrate_instant(&vf)) > 0) {
|
if ((test = ov_bitrate_instant(&vf)) > 0) {
|
||||||
bitRate = test / 1000;
|
bitRate = test / 1000;
|
||||||
}
|
}
|
||||||
sendDataToOutputBuffer(cb, inStream, dc,
|
sendDataToOutputBuffer(cb, inStream,
|
||||||
inStream->seekable,
|
inStream->seekable,
|
||||||
chunk, chunkpos,
|
chunk, chunkpos,
|
||||||
ov_pcm_tell(&vf) /
|
ov_pcm_tell(&vf) /
|
||||||
dc->audioFormat.sampleRate,
|
dc.audioFormat.sampleRate,
|
||||||
bitRate, replayGainInfo);
|
bitRate, replayGainInfo);
|
||||||
chunkpos = 0;
|
chunkpos = 0;
|
||||||
if (dc->stop)
|
if (dc.stop)
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!dc->stop && chunkpos > 0) {
|
if (!dc.stop && chunkpos > 0) {
|
||||||
sendDataToOutputBuffer(cb, NULL, dc, inStream->seekable,
|
sendDataToOutputBuffer(cb, NULL, inStream->seekable,
|
||||||
chunk, chunkpos,
|
chunk, chunkpos,
|
||||||
ov_time_tell(&vf), bitRate,
|
ov_time_tell(&vf), bitRate,
|
||||||
replayGainInfo);
|
replayGainInfo);
|
||||||
|
@ -128,7 +128,7 @@ static void format_samples_float(int Bps, void *buffer, uint32_t samcnt)
|
|||||||
* This does the main decoding thing.
|
* This does the main decoding thing.
|
||||||
* Requires an already opened WavpackContext.
|
* Requires an already opened WavpackContext.
|
||||||
*/
|
*/
|
||||||
static void wavpack_decode(OutputBuffer *cb, DecoderControl *dc,
|
static void wavpack_decode(OutputBuffer *cb,
|
||||||
WavpackContext *wpc, int canseek,
|
WavpackContext *wpc, int canseek,
|
||||||
ReplayGainInfo *replayGainInfo)
|
ReplayGainInfo *replayGainInfo)
|
||||||
{
|
{
|
||||||
@ -140,12 +140,12 @@ static void wavpack_decode(OutputBuffer *cb, DecoderControl *dc,
|
|||||||
int position, outsamplesize;
|
int position, outsamplesize;
|
||||||
int Bps;
|
int Bps;
|
||||||
|
|
||||||
dc->audioFormat.sampleRate = WavpackGetSampleRate(wpc);
|
dc.audioFormat.sampleRate = WavpackGetSampleRate(wpc);
|
||||||
dc->audioFormat.channels = WavpackGetReducedChannels(wpc);
|
dc.audioFormat.channels = WavpackGetReducedChannels(wpc);
|
||||||
dc->audioFormat.bits = WavpackGetBitsPerSample(wpc);
|
dc.audioFormat.bits = WavpackGetBitsPerSample(wpc);
|
||||||
|
|
||||||
if (dc->audioFormat.bits > 16)
|
if (dc.audioFormat.bits > 16)
|
||||||
dc->audioFormat.bits = 16;
|
dc.audioFormat.bits = 16;
|
||||||
|
|
||||||
if ((WavpackGetMode(wpc) & MODE_FLOAT) == MODE_FLOAT)
|
if ((WavpackGetMode(wpc) & MODE_FLOAT) == MODE_FLOAT)
|
||||||
format_samples = format_samples_float;
|
format_samples = format_samples_float;
|
||||||
@ -163,40 +163,40 @@ static void wavpack_decode(OutputBuffer *cb, DecoderControl *dc,
|
|||||||
outsamplesize = Bps;
|
outsamplesize = Bps;
|
||||||
if (outsamplesize > 2)
|
if (outsamplesize > 2)
|
||||||
outsamplesize = 2;
|
outsamplesize = 2;
|
||||||
outsamplesize *= dc->audioFormat.channels;
|
outsamplesize *= dc.audioFormat.channels;
|
||||||
|
|
||||||
samplesreq = sizeof(chunk) / (4 * dc->audioFormat.channels);
|
samplesreq = sizeof(chunk) / (4 * dc.audioFormat.channels);
|
||||||
|
|
||||||
getOutputAudioFormat(&(dc->audioFormat), &(cb->audioFormat));
|
getOutputAudioFormat(&(dc.audioFormat), &(cb->audioFormat));
|
||||||
|
|
||||||
dc->totalTime = (float)allsamples / dc->audioFormat.sampleRate;
|
dc.totalTime = (float)allsamples / dc.audioFormat.sampleRate;
|
||||||
dc->state = DECODE_STATE_DECODE;
|
dc.state = DECODE_STATE_DECODE;
|
||||||
dc->seekable = canseek;
|
dc.seekable = canseek;
|
||||||
|
|
||||||
position = 0;
|
position = 0;
|
||||||
|
|
||||||
do {
|
do {
|
||||||
if (dc->seek) {
|
if (dc.seek) {
|
||||||
if (canseek) {
|
if (canseek) {
|
||||||
int where;
|
int where;
|
||||||
|
|
||||||
clearOutputBuffer(cb);
|
clearOutputBuffer(cb);
|
||||||
|
|
||||||
where = dc->seekWhere *
|
where = dc.seekWhere *
|
||||||
dc->audioFormat.sampleRate;
|
dc.audioFormat.sampleRate;
|
||||||
if (WavpackSeekSample(wpc, where))
|
if (WavpackSeekSample(wpc, where))
|
||||||
position = where;
|
position = where;
|
||||||
else
|
else
|
||||||
dc->seekError = 1;
|
dc.seekError = 1;
|
||||||
} else {
|
} else {
|
||||||
dc->seekError = 1;
|
dc.seekError = 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
dc->seek = 0;
|
dc.seek = 0;
|
||||||
decoder_wakeup_player();
|
decoder_wakeup_player();
|
||||||
}
|
}
|
||||||
|
|
||||||
if (dc->stop)
|
if (dc.stop)
|
||||||
break;
|
break;
|
||||||
|
|
||||||
samplesgot = WavpackUnpackSamples(wpc,
|
samplesgot = WavpackUnpackSamples(wpc,
|
||||||
@ -206,12 +206,12 @@ static void wavpack_decode(OutputBuffer *cb, DecoderControl *dc,
|
|||||||
1000 + 0.5);
|
1000 + 0.5);
|
||||||
position += samplesgot;
|
position += samplesgot;
|
||||||
file_time = (float)position /
|
file_time = (float)position /
|
||||||
dc->audioFormat.sampleRate;
|
dc.audioFormat.sampleRate;
|
||||||
|
|
||||||
format_samples(Bps, chunk,
|
format_samples(Bps, chunk,
|
||||||
samplesgot * dc->audioFormat.channels);
|
samplesgot * dc.audioFormat.channels);
|
||||||
|
|
||||||
sendDataToOutputBuffer(cb, NULL, dc, 0, chunk,
|
sendDataToOutputBuffer(cb, NULL, 0, chunk,
|
||||||
samplesgot * outsamplesize,
|
samplesgot * outsamplesize,
|
||||||
file_time, bitrate,
|
file_time, bitrate,
|
||||||
replayGainInfo);
|
replayGainInfo);
|
||||||
@ -442,8 +442,7 @@ static unsigned int wavpack_trydecode(InputStream *is)
|
|||||||
/*
|
/*
|
||||||
* Decodes a stream.
|
* Decodes a stream.
|
||||||
*/
|
*/
|
||||||
static int wavpack_streamdecode(OutputBuffer *cb, DecoderControl *dc,
|
static int wavpack_streamdecode(OutputBuffer *cb, InputStream *is)
|
||||||
InputStream *is)
|
|
||||||
{
|
{
|
||||||
char error[ERRORLEN];
|
char error[ERRORLEN];
|
||||||
WavpackContext *wpc;
|
WavpackContext *wpc;
|
||||||
@ -462,7 +461,7 @@ static int wavpack_streamdecode(OutputBuffer *cb, DecoderControl *dc,
|
|||||||
err = 1;
|
err = 1;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* As we use dc->utf8url, this function will be bad for
|
* As we use dc.utf8url, this function will be bad for
|
||||||
* single files. utf8url is not absolute file path :/
|
* single files. utf8url is not absolute file path :/
|
||||||
*/
|
*/
|
||||||
utf8url = get_song_url(tmp, pc.current_song);
|
utf8url = get_song_url(tmp, pc.current_song);
|
||||||
@ -507,7 +506,7 @@ static int wavpack_streamdecode(OutputBuffer *cb, DecoderControl *dc,
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (dc->stop) {
|
if (dc.stop) {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -542,7 +541,7 @@ static int wavpack_streamdecode(OutputBuffer *cb, DecoderControl *dc,
|
|||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
wavpack_decode(cb, dc, wpc, canseek, NULL);
|
wavpack_decode(cb, wpc, canseek, NULL);
|
||||||
|
|
||||||
WavpackCloseFile(wpc);
|
WavpackCloseFile(wpc);
|
||||||
if (wvc_url != NULL) {
|
if (wvc_url != NULL) {
|
||||||
@ -557,7 +556,7 @@ static int wavpack_streamdecode(OutputBuffer *cb, DecoderControl *dc,
|
|||||||
/*
|
/*
|
||||||
* Decodes a file.
|
* Decodes a file.
|
||||||
*/
|
*/
|
||||||
static int wavpack_filedecode(OutputBuffer *cb, DecoderControl *dc, char *fname)
|
static int wavpack_filedecode(OutputBuffer *cb, char *fname)
|
||||||
{
|
{
|
||||||
char error[ERRORLEN];
|
char error[ERRORLEN];
|
||||||
WavpackContext *wpc;
|
WavpackContext *wpc;
|
||||||
@ -573,7 +572,7 @@ static int wavpack_filedecode(OutputBuffer *cb, DecoderControl *dc, char *fname)
|
|||||||
|
|
||||||
replayGainInfo = wavpack_replaygain(wpc);
|
replayGainInfo = wavpack_replaygain(wpc);
|
||||||
|
|
||||||
wavpack_decode(cb, dc, wpc, 1, replayGainInfo);
|
wavpack_decode(cb, wpc, 1, replayGainInfo);
|
||||||
|
|
||||||
if (replayGainInfo)
|
if (replayGainInfo)
|
||||||
freeReplayGainInfo(replayGainInfo);
|
freeReplayGainInfo(replayGainInfo);
|
||||||
|
@ -431,7 +431,7 @@ int main(int argc, char *argv[])
|
|||||||
initZeroconf();
|
initZeroconf();
|
||||||
|
|
||||||
openVolumeDevice();
|
openVolumeDevice();
|
||||||
decoderInit(&getPlayerData()->decoderControl);
|
decoderInit();
|
||||||
playerInit();
|
playerInit();
|
||||||
read_state_file();
|
read_state_file();
|
||||||
|
|
||||||
|
@ -20,6 +20,7 @@
|
|||||||
|
|
||||||
#include "utils.h"
|
#include "utils.h"
|
||||||
#include "normalize.h"
|
#include "normalize.h"
|
||||||
|
#include "playerData.h"
|
||||||
|
|
||||||
void initOutputBuffer(OutputBuffer * cb, unsigned int size)
|
void initOutputBuffer(OutputBuffer * cb, unsigned int size)
|
||||||
{
|
{
|
||||||
@ -150,8 +151,7 @@ OutputBufferChunk * outputBufferGetChunk(const OutputBuffer * cb, unsigned i)
|
|||||||
* another thread requested stopping the decoder.
|
* another thread requested stopping the decoder.
|
||||||
*/
|
*/
|
||||||
static int tailChunk(OutputBuffer * cb, InputStream * inStream,
|
static int tailChunk(OutputBuffer * cb, InputStream * inStream,
|
||||||
DecoderControl * dc, int seekable,
|
int seekable, float data_time, mpd_uint16 bitRate)
|
||||||
float data_time, mpd_uint16 bitRate)
|
|
||||||
{
|
{
|
||||||
unsigned int next;
|
unsigned int next;
|
||||||
OutputBufferChunk *chunk;
|
OutputBufferChunk *chunk;
|
||||||
@ -165,21 +165,20 @@ static int tailChunk(OutputBuffer * cb, InputStream * inStream,
|
|||||||
/* all chunks are full of decoded data; wait
|
/* all chunks are full of decoded data; wait
|
||||||
for the player to free one */
|
for the player to free one */
|
||||||
|
|
||||||
if (dc->stop)
|
if (dc.stop)
|
||||||
return OUTPUT_BUFFER_DC_STOP;
|
return OUTPUT_BUFFER_DC_STOP;
|
||||||
|
|
||||||
if (dc->seek) {
|
if (dc.seek) {
|
||||||
if (seekable) {
|
if (seekable) {
|
||||||
return OUTPUT_BUFFER_DC_SEEK;
|
return OUTPUT_BUFFER_DC_SEEK;
|
||||||
} else {
|
} else {
|
||||||
dc->seekError = 1;
|
dc.seekError = 1;
|
||||||
dc->seek = 0;
|
dc.seek = 0;
|
||||||
decoder_wakeup_player();
|
decoder_wakeup_player();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (!inStream ||
|
if (!inStream || bufferInputStream(inStream) <= 0) {
|
||||||
bufferInputStream(inStream) <= 0) {
|
decoder_sleep();
|
||||||
decoder_sleep(dc);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -200,7 +199,7 @@ static int tailChunk(OutputBuffer * cb, InputStream * inStream,
|
|||||||
}
|
}
|
||||||
|
|
||||||
int sendDataToOutputBuffer(OutputBuffer * cb, InputStream * inStream,
|
int sendDataToOutputBuffer(OutputBuffer * cb, InputStream * inStream,
|
||||||
DecoderControl * dc, int seekable, void *dataIn,
|
int seekable, void *dataIn,
|
||||||
size_t dataInLen, float data_time, mpd_uint16 bitRate,
|
size_t dataInLen, float data_time, mpd_uint16 bitRate,
|
||||||
ReplayGainInfo * replayGainInfo)
|
ReplayGainInfo * replayGainInfo)
|
||||||
{
|
{
|
||||||
@ -211,11 +210,11 @@ int sendDataToOutputBuffer(OutputBuffer * cb, InputStream * inStream,
|
|||||||
static size_t convBufferLen;
|
static size_t convBufferLen;
|
||||||
OutputBufferChunk *chunk = NULL;
|
OutputBufferChunk *chunk = NULL;
|
||||||
|
|
||||||
if (cmpAudioFormat(&(cb->audioFormat), &(dc->audioFormat)) == 0) {
|
if (cmpAudioFormat(&(cb->audioFormat), &(dc.audioFormat)) == 0) {
|
||||||
data = dataIn;
|
data = dataIn;
|
||||||
datalen = dataInLen;
|
datalen = dataInLen;
|
||||||
} else {
|
} else {
|
||||||
datalen = pcm_sizeOfConvBuffer(&(dc->audioFormat), dataInLen,
|
datalen = pcm_sizeOfConvBuffer(&(dc.audioFormat), dataInLen,
|
||||||
&(cb->audioFormat));
|
&(cb->audioFormat));
|
||||||
if (datalen > convBufferLen) {
|
if (datalen > convBufferLen) {
|
||||||
if (convBuffer != NULL)
|
if (convBuffer != NULL)
|
||||||
@ -224,7 +223,7 @@ int sendDataToOutputBuffer(OutputBuffer * cb, InputStream * inStream,
|
|||||||
convBufferLen = datalen;
|
convBufferLen = datalen;
|
||||||
}
|
}
|
||||||
data = convBuffer;
|
data = convBuffer;
|
||||||
datalen = pcm_convertAudioFormat(&(dc->audioFormat), dataIn,
|
datalen = pcm_convertAudioFormat(&(dc.audioFormat), dataIn,
|
||||||
dataInLen, &(cb->audioFormat),
|
dataInLen, &(cb->audioFormat),
|
||||||
data, &(cb->convState));
|
data, &(cb->convState));
|
||||||
}
|
}
|
||||||
@ -235,8 +234,7 @@ int sendDataToOutputBuffer(OutputBuffer * cb, InputStream * inStream,
|
|||||||
normalizeData(data, datalen, &cb->audioFormat);
|
normalizeData(data, datalen, &cb->audioFormat);
|
||||||
|
|
||||||
while (datalen) {
|
while (datalen) {
|
||||||
int chunk_index = tailChunk(cb, inStream,
|
int chunk_index = tailChunk(cb, inStream, seekable,
|
||||||
dc, seekable,
|
|
||||||
data_time, bitRate);
|
data_time, bitRate);
|
||||||
if (chunk_index < 0)
|
if (chunk_index < 0)
|
||||||
return chunk_index;
|
return chunk_index;
|
||||||
|
@ -91,7 +91,6 @@ OutputBufferChunk * outputBufferGetChunk(const OutputBuffer * cb, unsigned i);
|
|||||||
send the next chunk */
|
send the next chunk */
|
||||||
int sendDataToOutputBuffer(OutputBuffer * cb,
|
int sendDataToOutputBuffer(OutputBuffer * cb,
|
||||||
InputStream * inStream,
|
InputStream * inStream,
|
||||||
DecoderControl * dc,
|
|
||||||
int seekable,
|
int seekable,
|
||||||
void *data,
|
void *data,
|
||||||
size_t datalen,
|
size_t datalen,
|
||||||
|
@ -28,6 +28,7 @@ unsigned int buffered_before_play;
|
|||||||
|
|
||||||
static PlayerData playerData_pd;
|
static PlayerData playerData_pd;
|
||||||
PlayerControl pc;
|
PlayerControl pc;
|
||||||
|
DecoderControl dc;
|
||||||
|
|
||||||
void initPlayerData(void)
|
void initPlayerData(void)
|
||||||
{
|
{
|
||||||
@ -85,13 +86,9 @@ void initPlayerData(void)
|
|||||||
pc.crossFade = crossfade;
|
pc.crossFade = crossfade;
|
||||||
pc.softwareVolume = 1000;
|
pc.softwareVolume = 1000;
|
||||||
|
|
||||||
notifyInit(&playerData_pd.decoderControl.notify);
|
notifyInit(&dc.notify);
|
||||||
playerData_pd.decoderControl.stop = 0;
|
dc.state = DECODE_STATE_STOP;
|
||||||
playerData_pd.decoderControl.start = 0;
|
dc.error = DECODE_ERROR_NOERROR;
|
||||||
playerData_pd.decoderControl.state = DECODE_STATE_STOP;
|
|
||||||
playerData_pd.decoderControl.seek = 0;
|
|
||||||
playerData_pd.decoderControl.error = DECODE_ERROR_NOERROR;
|
|
||||||
playerData_pd.decoderControl.current_song = NULL;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
PlayerData *getPlayerData(void)
|
PlayerData *getPlayerData(void)
|
||||||
|
@ -27,10 +27,10 @@
|
|||||||
|
|
||||||
extern unsigned int buffered_before_play;
|
extern unsigned int buffered_before_play;
|
||||||
extern PlayerControl pc;
|
extern PlayerControl pc;
|
||||||
|
extern DecoderControl dc;
|
||||||
|
|
||||||
typedef struct _PlayerData {
|
typedef struct _PlayerData {
|
||||||
OutputBuffer buffer;
|
OutputBuffer buffer;
|
||||||
DecoderControl decoderControl;
|
|
||||||
mpd_uint8 *audioDeviceStates;
|
mpd_uint8 *audioDeviceStates;
|
||||||
} PlayerData;
|
} PlayerData;
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user