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:
Eric Wong 2008-04-13 01:16:03 +00:00
parent 98acfa8ac5
commit dec6b1612e
20 changed files with 337 additions and 374 deletions

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View 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;

View File

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

View File

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

View File

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