diff --git a/src/Makefile.am b/src/Makefile.am index 2d19a13ff..33919516f 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -5,13 +5,15 @@ mpd_headers = buffer2array.h interface.h command.h playlist.h ls.h \ tag.h player.h listen.h conf.h ogg_decode.h volume.h flac_decode.h \ audio.h playerData.h stats.h myfprintf.h sig_handlers.h decode.h log.h \ audiofile_decode.h charConv.h permission.h mpd_types.h pcm_utils.h \ - mp4_decode.h aac_decode.h signal_check.h utf8.h inputStream.h + mp4_decode.h aac_decode.h signal_check.h utf8.h inputStream.h \ + outputBuffer.h mpd_SOURCES = main.c buffer2array.c interface.c command.c playlist.c ls.c \ song.c list.c directory.c tables.c utils.c path.c mp3_decode.c \ tag.c player.c listen.c conf.c ogg_decode.c volume.c flac_decode.c \ audio.c playerData.c stats.c myfprintf.c sig_handlers.c decode.c log.c \ audiofile_decode.c charConv.c permission.c pcm_utils.c mp4_decode.c \ - aac_decode.c signal_check.c utf8.c inputStream.c $(mpd_headers) + aac_decode.c signal_check.c utf8.c inputStream.c outputBuffer.c \ + $(mpd_headers) mpd_CFLAGS = $(MPD_CFLAGS) mpd_LDADD = $(MPD_LIBS) $(ID3_LIB) $(MAD_LIB) $(MP4FF_LIB) diff --git a/src/aac_decode.c b/src/aac_decode.c index 9d56e3392..42da876be 100644 --- a/src/aac_decode.c +++ b/src/aac_decode.c @@ -250,7 +250,7 @@ int getAacTotalTime(char * file) { } -int aac_decode(Buffer * cb, AudioFormat * af, DecoderControl * dc) { +int aac_decode(OutputBuffer * cb, AudioFormat * af, DecoderControl * dc) { float time; float totalTime; faacDecHandle decoder; diff --git a/src/aac_decode.h b/src/aac_decode.h index bd8149778..62e77eb1e 100644 --- a/src/aac_decode.h +++ b/src/aac_decode.h @@ -27,7 +27,7 @@ int getAacTotalTime(char * file); -int aac_decode(Buffer * cb, AudioFormat * af, DecoderControl * dc); +int aac_decode(OutputBuffer * cb, AudioFormat * af, DecoderControl * dc); #endif /* HAVE_FAAD */ diff --git a/src/audiofile_decode.c b/src/audiofile_decode.c index 79f25e3d4..9a5103716 100644 --- a/src/audiofile_decode.c +++ b/src/audiofile_decode.c @@ -51,7 +51,7 @@ int getAudiofileTotalTime(char * file) return time; } -int audiofile_decode(Buffer * cb, AudioFormat * af, DecoderControl * dc) +int audiofile_decode(OutputBuffer * cb, AudioFormat * af, DecoderControl * dc) { int fs, frame_count; AFfilehandle af_fp; diff --git a/src/audiofile_decode.h b/src/audiofile_decode.h index 5562b628e..774d58c1b 100644 --- a/src/audiofile_decode.h +++ b/src/audiofile_decode.h @@ -27,7 +27,7 @@ #include "playerData.h" -int audiofile_decode(Buffer * cb, AudioFormat * af, DecoderControl * dc);; +int audiofile_decode(OutputBuffer * cb, AudioFormat * af, DecoderControl * dc); int getAudiofileTotalTime(char * file); diff --git a/src/decode.c b/src/decode.c index fc0bd84af..221ca4a9b 100644 --- a/src/decode.c +++ b/src/decode.c @@ -112,7 +112,7 @@ int calculateCrossFadeChunks(PlayerControl * pc, AudioFormat * af) { } int waitOnDecode(PlayerControl * pc, AudioFormat * af, DecoderControl * dc, - Buffer * cb) + OutputBuffer * cb) { while(decode_pid && *decode_pid>0 && dc->start) my_usleep(1000); @@ -143,7 +143,7 @@ int waitOnDecode(PlayerControl * pc, AudioFormat * af, DecoderControl * dc, } void decodeSeek(PlayerControl * pc, AudioFormat * af, DecoderControl * dc, - Buffer * cb) + OutputBuffer * cb) { if(decode_pid && *decode_pid>0) { cb->next = -1; @@ -217,7 +217,7 @@ void decodeSeek(PlayerControl * pc, AudioFormat * af, DecoderControl * dc, return; \ } -int decoderInit(PlayerControl * pc, Buffer * cb, AudioFormat *af, +int decoderInit(PlayerControl * pc, OutputBuffer * cb, AudioFormat *af, DecoderControl * dc) { int pid; int ret; @@ -311,7 +311,7 @@ int decoderInit(PlayerControl * pc, Buffer * cb, AudioFormat *af, * parent process does playing audio */ void decode() { - Buffer * cb; + OutputBuffer * cb; PlayerControl * pc; AudioFormat * af; DecoderControl * dc; diff --git a/src/flac_decode.c b/src/flac_decode.c index 9760bcb11..ee9255efe 100644 --- a/src/flac_decode.c +++ b/src/flac_decode.c @@ -37,7 +37,7 @@ typedef struct { float time; int bitRate; FLAC__uint64 position; - Buffer * cb; + OutputBuffer * cb; AudioFormat * af; DecoderControl * dc; char * file; @@ -65,7 +65,7 @@ FLAC__SeekableStreamDecoderLengthStatus flacLength( const FLAC__SeekableStreamDecoder *, FLAC__uint64 *, void *); FLAC__bool flacEOF(const FLAC__SeekableStreamDecoder *, void *); -void flacPlayFile(char *file, Buffer * cb, AudioFormat * af, +void flacPlayFile(char *file, OutputBuffer * cb, AudioFormat * af, DecoderControl *dc) { FLAC__SeekableStreamDecoder * flacDec; @@ -392,7 +392,7 @@ int getFlacTotalTime(char * file) { return (int)(totalTime+0.5); } -int flac_decode(Buffer * cb, AudioFormat * af, DecoderControl * dc) { +int flac_decode(OutputBuffer * cb, AudioFormat * af, DecoderControl * dc) { if(flac_getAudioFormatAndTime(dc->file,af,&(cb->totalTime))<0) { ERROR("\"%s\" doesn't seem to be a flac\n",dc->file); return -1; diff --git a/src/flac_decode.h b/src/flac_decode.h index 02b3aa092..db7662334 100644 --- a/src/flac_decode.h +++ b/src/flac_decode.h @@ -25,7 +25,7 @@ #include -int flac_decode(Buffer * cb, AudioFormat * af, DecoderControl * dc); +int flac_decode(OutputBuffer * cb, AudioFormat * af, DecoderControl * dc); int getFlacTotalTime(char * file); diff --git a/src/mp3_decode.c b/src/mp3_decode.c index 9103742e4..973f96541 100644 --- a/src/mp3_decode.c +++ b/src/mp3_decode.c @@ -37,6 +37,7 @@ #include "log.h" #include "utils.h" #include "inputStream.h" +#include "outputBuffer.h" #include #include @@ -111,13 +112,15 @@ signed long audio_linear_dither(unsigned int bits, mad_fixed_t sample, struct au /* decoder stuff is based on madlld */ +#define MP3_DATA_OUTPUT_BUFFER_SIZE 4096 + typedef struct _mp3DecodeData { struct mad_stream stream; struct mad_frame frame; struct mad_synth synth; mad_timer_t timer; unsigned char readBuffer[READ_BUFFER_SIZE]; - char outputBuffer[CHUNK_SIZE]; + char outputBuffer[MP3_DATA_OUTPUT_BUFFER_SIZE]; char * outputPtr; char * outputBufferEnd; float totalTime; @@ -141,7 +144,7 @@ int initMp3DecodeData(mp3DecodeData * data, char * file) { if(ret<0) return -1; data->outputPtr = data->outputBuffer; - data->outputBufferEnd = data->outputBuffer+CHUNK_SIZE; + data->outputBufferEnd = data->outputBuffer+MP3_DATA_OUTPUT_BUFFER_SIZE; data->muteFrame = 0; data->highestFrame = 0; data->maxFrames = 0; @@ -406,29 +409,7 @@ int openMp3(char * file, mp3DecodeData * data) { return 0; } -int mp3ChildSendData(mp3DecodeData * data, Buffer * cb, DecoderControl * dc) { - while(cb->begin==cb->end && cb->wrap && !dc->stop && !dc->seek) - my_usleep(10000); - if(dc->stop) return -1; - /* just for now, so it doesn't hang */ - if(dc->seek) return 0; - /* be sure to remove this! */ - - memcpy(cb->chunks+cb->end*CHUNK_SIZE,data->outputBuffer,CHUNK_SIZE); - cb->chunkSize[cb->end] = data->outputPtr-data->outputBuffer; - cb->bitRate[cb->end] = data->bitRate/1000; - cb->times[cb->end] = data->elapsedTime; - - cb->end++; - if(cb->end>=buffered_chunks) { - cb->end = 0; - cb->wrap = 1; - } - - return 0; -} - -int mp3Read(mp3DecodeData * data, Buffer * cb, DecoderControl * dc) { +int mp3Read(mp3DecodeData * data, OutputBuffer * cb, DecoderControl * dc) { static int i; static int ret; static struct audio_dither dither; @@ -464,6 +445,8 @@ int mp3Read(mp3DecodeData * data, Buffer * cb, DecoderControl * dc) { } } else { + long ret; + mad_synth_frame(&data->synth,&data->frame); for(i=0;i<(data->synth).pcm.length;i++) { @@ -484,12 +467,24 @@ int mp3Read(mp3DecodeData * data, Buffer * cb, DecoderControl * dc) { } if(data->outputPtr==data->outputBufferEnd) { - if(mp3ChildSendData(data,cb,dc)<0) { - data->flush = 0; - return DECODE_BREAK; - } - data->outputPtr = data->outputBuffer; - if(dc->seek) break; + ret = sendDataToOutputBuffer(cb,dc, + 0,data->outputBuffer, + MP3_DATA_OUTPUT_BUFFER_SIZE, + data->elapsedTime, + data->bitRate/1000); + if(ret == OUTPUT_BUFFER_DC_STOP) { + return DECODE_BREAK; + } + if(ret >= 0) { + memmove(data->outputBuffer, + data->outputBuffer+ret, + MP3_DATA_OUTPUT_BUFFER_SIZE- + ret); + data->outputPtr-=ret; + } + else data->outputPtr = data->outputBuffer; + + if(ret == OUTPUT_BUFFER_DC_SEEK) break; } } @@ -534,7 +529,7 @@ void initAudioFormatFromMp3DecodeData(mp3DecodeData * data, AudioFormat * af) { af->channels = MAD_NCHANNELS(&(data->frame).header); } -int mp3_decode(Buffer * cb, AudioFormat * af, DecoderControl * dc) { +int mp3_decode(OutputBuffer * cb, AudioFormat * af, DecoderControl * dc) { mp3DecodeData data; if(openMp3(dc->file,&data) < 0) { @@ -550,7 +545,9 @@ int mp3_decode(Buffer * cb, AudioFormat * af, DecoderControl * dc) { while(mp3Read(&data,cb,dc)!=DECODE_BREAK); /* send last little bit if not dc->stop */ if(data.outputPtr!=data.outputBuffer && data.flush) { - mp3ChildSendData(&data,cb,dc); + sendDataToOutputBuffer(cb,dc,1,data.outputBuffer, + data.outputPtr-data.outputBuffer, + data.elapsedTime,data.bitRate/1000); } mp3DecodeDataFinalize(&data); @@ -567,4 +564,4 @@ int mp3_decode(Buffer * cb, AudioFormat * af, DecoderControl * dc) { } #endif -/* vim:set shiftwidth=4 tabstop=8 expandtab: */ +/* vim:set shiftwidth=8 tabstop=8 expandtab: */ diff --git a/src/mp3_decode.h b/src/mp3_decode.h index e75db0763..06525e8c3 100644 --- a/src/mp3_decode.h +++ b/src/mp3_decode.h @@ -28,7 +28,7 @@ /* this is primarily used in tag.c */ int getMp3TotalTime(char * file); -int mp3_decode(Buffer * cb, AudioFormat * af, DecoderControl * dc); +int mp3_decode(OutputBuffer * cb, AudioFormat * af, DecoderControl * dc); #endif diff --git a/src/mp4_decode.c b/src/mp4_decode.c index b6cea1d62..e1faff837 100644 --- a/src/mp4_decode.c +++ b/src/mp4_decode.c @@ -84,7 +84,7 @@ uint32_t mp4_inputStreamSeekCallback(void *inStream, uint64_t position) { } -int mp4_decode(Buffer * cb, AudioFormat * af, DecoderControl * dc) { +int mp4_decode(OutputBuffer * cb, AudioFormat * af, DecoderControl * dc) { mp4ff_t * mp4fh; mp4ff_callback_t * mp4cb; int32_t track; diff --git a/src/mp4_decode.h b/src/mp4_decode.h index 0904dcc28..8116758db 100644 --- a/src/mp4_decode.h +++ b/src/mp4_decode.h @@ -29,7 +29,7 @@ int mp4_getAACTrack(mp4ff_t *infile); -int mp4_decode(Buffer * cb, AudioFormat * af, DecoderControl * dc); +int mp4_decode(OutputBuffer * cb, AudioFormat * af, DecoderControl * dc); uint32_t mp4_inputStreamReadCallback(void *inStream, void *buffer, uint32_t length); diff --git a/src/ogg_decode.c b/src/ogg_decode.c index e37dae2a2..5aad02f78 100644 --- a/src/ogg_decode.c +++ b/src/ogg_decode.c @@ -82,7 +82,7 @@ long ogg_tell_cb(void * inStream) { return ((InputStream *)inStream)->offset; } -int ogg_decode(Buffer * cb, AudioFormat * af, DecoderControl * dc) +int ogg_decode(OutputBuffer * cb, AudioFormat * af, DecoderControl * dc) { OggVorbis_File vf; ov_callbacks callbacks; diff --git a/src/ogg_decode.h b/src/ogg_decode.h index 036b6fc3a..6710c5b8e 100644 --- a/src/ogg_decode.h +++ b/src/ogg_decode.h @@ -25,7 +25,7 @@ #include -int ogg_decode(Buffer * cb, AudioFormat * af, DecoderControl * dc); +int ogg_decode(OutputBuffer * cb, AudioFormat * af, DecoderControl * dc); int getOggTotalTime(char * file); diff --git a/src/outputBuffer.c b/src/outputBuffer.c index 507c6fc01..191ea7556 100644 --- a/src/outputBuffer.c +++ b/src/outputBuffer.c @@ -20,17 +20,13 @@ #include "pcm_utils.h" #include "playerData.h" -#include "log.h" #include "utils.h" #include -#include -#define OUTPUT_BUFFER_DC_STOP -1 -#define OUTPUT_BUFFER_DC_SEEK -2 - -long sendDataToOutputBuffer(Buffer * cb, DecoderControl * dc, int flushAllData, - char * data, long datalen, float time, mpd_uint16 bitRate) +long sendDataToOutputBuffer(OutputBuffer * cb, DecoderControl * dc, + int flushAllData, char * data, long datalen, float time, + mpd_uint16 bitRate) { long dataSent = 0; long dataToSend; diff --git a/src/outputBuffer.h b/src/outputBuffer.h new file mode 100644 index 000000000..1a5335df2 --- /dev/null +++ b/src/outputBuffer.h @@ -0,0 +1,45 @@ +/* the Music Player Daemon (MPD) + * (c)2003-2004 by Warren Dukes (shank@mercury.chem.pitt.edu) + * This project's homepage is: http://www.musicpd.org + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#ifndef OUTPUT_BUFFER_H +#define OUTPUT_BUFFER_H + +#include "mpd_types.h" +#include "decode.h" + +#define OUTPUT_BUFFER_DC_STOP -1 +#define OUTPUT_BUFFER_DC_SEEK -2 + +typedef struct _OutputBuffer { + char * volatile chunks; + mpd_uint16 * volatile chunkSize; + mpd_uint16 * volatile bitRate; + float * volatile times; + mpd_sint16 volatile begin; + mpd_sint16 volatile end; + mpd_sint16 volatile next; + mpd_sint8 volatile wrap; + float totalTime; +} OutputBuffer; + +long sendDataToOutputBuffer(OutputBuffer * cb, DecoderControl * dc, + int flushAllData, char * data, long datalen, float time, + mpd_uint16 bitRate); + +#endif +/* vim:set shiftwidth=4 tabstop=8 expandtab: */ diff --git a/src/playerData.c b/src/playerData.c index 21fc30200..17e79543b 100644 --- a/src/playerData.c +++ b/src/playerData.c @@ -39,7 +39,7 @@ void initPlayerData() { int crossfade = 0; size_t bufferSize; size_t allocationSize; - Buffer * buffer; + OutputBuffer * buffer; bufferSize = strtol(getConf()[CONF_BUFFER_SIZE],&test,10); if(*test!='\0' || bufferSize<=0) { diff --git a/src/playerData.h b/src/playerData.h index eb69ad0fc..387eb07cf 100644 --- a/src/playerData.h +++ b/src/playerData.h @@ -25,6 +25,7 @@ #include "player.h" #include "decode.h" #include "mpd_types.h" +#include "outputBuffer.h" /* pick 1020 since its devisible for 8,16,24, and 32-bit audio */ #define CHUNK_SIZE 1020 @@ -32,20 +33,8 @@ extern int buffered_before_play; extern int buffered_chunks; -typedef struct _Buffer { - char * volatile chunks; - mpd_uint16 * volatile chunkSize; - mpd_uint16 * volatile bitRate; - float * volatile times; - mpd_sint16 volatile begin; - mpd_sint16 volatile end; - mpd_sint16 volatile next; - mpd_sint8 volatile wrap; - float totalTime; -} Buffer; - typedef struct _PlayerData { - Buffer buffer; + OutputBuffer buffer; AudioFormat audioFormat; PlayerControl playerControl; DecoderControl decoderControl; @@ -54,7 +43,6 @@ typedef struct _PlayerData { void initPlayerData(); PlayerData * getPlayerData(); -Buffer * getBuffer(); void freePlayerData();