You need to sign in or sign up before continuing.
Commit 3794126e authored by Warren Dukes's avatar Warren Dukes

new OutputBuffer abstraction stuff, implemented for mp3, now need to

implement in other decoders git-svn-id: https://svn.musicpd.org/mpd/trunk@940 09075e82-0dd4-0310-85a5-a0d7c8717e4f
parent 9196023f
...@@ -5,13 +5,15 @@ mpd_headers = buffer2array.h interface.h command.h playlist.h ls.h \ ...@@ -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 \ 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 \ 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 \ 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 \ 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 \ 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 \ 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 \ 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 \ 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_CFLAGS = $(MPD_CFLAGS)
mpd_LDADD = $(MPD_LIBS) $(ID3_LIB) $(MAD_LIB) $(MP4FF_LIB) mpd_LDADD = $(MPD_LIBS) $(ID3_LIB) $(MAD_LIB) $(MP4FF_LIB)
......
...@@ -250,7 +250,7 @@ int getAacTotalTime(char * file) { ...@@ -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 time;
float totalTime; float totalTime;
faacDecHandle decoder; faacDecHandle decoder;
......
...@@ -27,7 +27,7 @@ ...@@ -27,7 +27,7 @@
int getAacTotalTime(char * file); 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 */ #endif /* HAVE_FAAD */
......
...@@ -51,7 +51,7 @@ int getAudiofileTotalTime(char * file) ...@@ -51,7 +51,7 @@ int getAudiofileTotalTime(char * file)
return time; return time;
} }
int audiofile_decode(Buffer * cb, AudioFormat * af, DecoderControl * dc) int audiofile_decode(OutputBuffer * cb, AudioFormat * af, DecoderControl * dc)
{ {
int fs, frame_count; int fs, frame_count;
AFfilehandle af_fp; AFfilehandle af_fp;
......
...@@ -27,7 +27,7 @@ ...@@ -27,7 +27,7 @@
#include "playerData.h" #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); int getAudiofileTotalTime(char * file);
......
...@@ -112,7 +112,7 @@ int calculateCrossFadeChunks(PlayerControl * pc, AudioFormat * af) { ...@@ -112,7 +112,7 @@ int calculateCrossFadeChunks(PlayerControl * pc, AudioFormat * af) {
} }
int waitOnDecode(PlayerControl * pc, AudioFormat * af, DecoderControl * dc, int waitOnDecode(PlayerControl * pc, AudioFormat * af, DecoderControl * dc,
Buffer * cb) OutputBuffer * cb)
{ {
while(decode_pid && *decode_pid>0 && dc->start) my_usleep(1000); while(decode_pid && *decode_pid>0 && dc->start) my_usleep(1000);
...@@ -143,7 +143,7 @@ int waitOnDecode(PlayerControl * pc, AudioFormat * af, DecoderControl * dc, ...@@ -143,7 +143,7 @@ int waitOnDecode(PlayerControl * pc, AudioFormat * af, DecoderControl * dc,
} }
void decodeSeek(PlayerControl * pc, AudioFormat * af, DecoderControl * dc, void decodeSeek(PlayerControl * pc, AudioFormat * af, DecoderControl * dc,
Buffer * cb) OutputBuffer * cb)
{ {
if(decode_pid && *decode_pid>0) { if(decode_pid && *decode_pid>0) {
cb->next = -1; cb->next = -1;
...@@ -217,7 +217,7 @@ void decodeSeek(PlayerControl * pc, AudioFormat * af, DecoderControl * dc, ...@@ -217,7 +217,7 @@ void decodeSeek(PlayerControl * pc, AudioFormat * af, DecoderControl * dc,
return; \ return; \
} }
int decoderInit(PlayerControl * pc, Buffer * cb, AudioFormat *af, int decoderInit(PlayerControl * pc, OutputBuffer * cb, AudioFormat *af,
DecoderControl * dc) { DecoderControl * dc) {
int pid; int pid;
int ret; int ret;
...@@ -311,7 +311,7 @@ int decoderInit(PlayerControl * pc, Buffer * cb, AudioFormat *af, ...@@ -311,7 +311,7 @@ int decoderInit(PlayerControl * pc, Buffer * cb, AudioFormat *af,
* parent process does playing audio * parent process does playing audio
*/ */
void decode() { void decode() {
Buffer * cb; OutputBuffer * cb;
PlayerControl * pc; PlayerControl * pc;
AudioFormat * af; AudioFormat * af;
DecoderControl * dc; DecoderControl * dc;
......
...@@ -37,7 +37,7 @@ typedef struct { ...@@ -37,7 +37,7 @@ typedef struct {
float time; float time;
int bitRate; int bitRate;
FLAC__uint64 position; FLAC__uint64 position;
Buffer * cb; OutputBuffer * cb;
AudioFormat * af; AudioFormat * af;
DecoderControl * dc; DecoderControl * dc;
char * file; char * file;
...@@ -65,7 +65,7 @@ FLAC__SeekableStreamDecoderLengthStatus flacLength( ...@@ -65,7 +65,7 @@ FLAC__SeekableStreamDecoderLengthStatus flacLength(
const FLAC__SeekableStreamDecoder *, FLAC__uint64 *, void *); const FLAC__SeekableStreamDecoder *, FLAC__uint64 *, void *);
FLAC__bool flacEOF(const FLAC__SeekableStreamDecoder *, 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) DecoderControl *dc)
{ {
FLAC__SeekableStreamDecoder * flacDec; FLAC__SeekableStreamDecoder * flacDec;
...@@ -392,7 +392,7 @@ int getFlacTotalTime(char * file) { ...@@ -392,7 +392,7 @@ int getFlacTotalTime(char * file) {
return (int)(totalTime+0.5); 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) { if(flac_getAudioFormatAndTime(dc->file,af,&(cb->totalTime))<0) {
ERROR("\"%s\" doesn't seem to be a flac\n",dc->file); ERROR("\"%s\" doesn't seem to be a flac\n",dc->file);
return -1; return -1;
......
...@@ -25,7 +25,7 @@ ...@@ -25,7 +25,7 @@
#include <stdio.h> #include <stdio.h>
int flac_decode(Buffer * cb, AudioFormat * af, DecoderControl * dc); int flac_decode(OutputBuffer * cb, AudioFormat * af, DecoderControl * dc);
int getFlacTotalTime(char * file); int getFlacTotalTime(char * file);
......
...@@ -37,6 +37,7 @@ ...@@ -37,6 +37,7 @@
#include "log.h" #include "log.h"
#include "utils.h" #include "utils.h"
#include "inputStream.h" #include "inputStream.h"
#include "outputBuffer.h"
#include <stdio.h> #include <stdio.h>
#include <string.h> #include <string.h>
...@@ -111,13 +112,15 @@ signed long audio_linear_dither(unsigned int bits, mad_fixed_t sample, struct au ...@@ -111,13 +112,15 @@ signed long audio_linear_dither(unsigned int bits, mad_fixed_t sample, struct au
/* decoder stuff is based on madlld */ /* decoder stuff is based on madlld */
#define MP3_DATA_OUTPUT_BUFFER_SIZE 4096
typedef struct _mp3DecodeData { typedef struct _mp3DecodeData {
struct mad_stream stream; struct mad_stream stream;
struct mad_frame frame; struct mad_frame frame;
struct mad_synth synth; struct mad_synth synth;
mad_timer_t timer; mad_timer_t timer;
unsigned char readBuffer[READ_BUFFER_SIZE]; unsigned char readBuffer[READ_BUFFER_SIZE];
char outputBuffer[CHUNK_SIZE]; char outputBuffer[MP3_DATA_OUTPUT_BUFFER_SIZE];
char * outputPtr; char * outputPtr;
char * outputBufferEnd; char * outputBufferEnd;
float totalTime; float totalTime;
...@@ -141,7 +144,7 @@ int initMp3DecodeData(mp3DecodeData * data, char * file) { ...@@ -141,7 +144,7 @@ int initMp3DecodeData(mp3DecodeData * data, char * file) {
if(ret<0) return -1; if(ret<0) return -1;
data->outputPtr = data->outputBuffer; data->outputPtr = data->outputBuffer;
data->outputBufferEnd = data->outputBuffer+CHUNK_SIZE; data->outputBufferEnd = data->outputBuffer+MP3_DATA_OUTPUT_BUFFER_SIZE;
data->muteFrame = 0; data->muteFrame = 0;
data->highestFrame = 0; data->highestFrame = 0;
data->maxFrames = 0; data->maxFrames = 0;
...@@ -406,29 +409,7 @@ int openMp3(char * file, mp3DecodeData * data) { ...@@ -406,29 +409,7 @@ int openMp3(char * file, mp3DecodeData * data) {
return 0; return 0;
} }
int mp3ChildSendData(mp3DecodeData * data, Buffer * cb, DecoderControl * dc) { int mp3Read(mp3DecodeData * data, OutputBuffer * 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) {
static int i; static int i;
static int ret; static int ret;
static struct audio_dither dither; static struct audio_dither dither;
...@@ -464,6 +445,8 @@ int mp3Read(mp3DecodeData * data, Buffer * cb, DecoderControl * dc) { ...@@ -464,6 +445,8 @@ int mp3Read(mp3DecodeData * data, Buffer * cb, DecoderControl * dc) {
} }
} }
else { else {
long ret;
mad_synth_frame(&data->synth,&data->frame); mad_synth_frame(&data->synth,&data->frame);
for(i=0;i<(data->synth).pcm.length;i++) { for(i=0;i<(data->synth).pcm.length;i++) {
...@@ -484,12 +467,24 @@ int mp3Read(mp3DecodeData * data, Buffer * cb, DecoderControl * dc) { ...@@ -484,12 +467,24 @@ int mp3Read(mp3DecodeData * data, Buffer * cb, DecoderControl * dc) {
} }
if(data->outputPtr==data->outputBufferEnd) { if(data->outputPtr==data->outputBufferEnd) {
if(mp3ChildSendData(data,cb,dc)<0) { ret = sendDataToOutputBuffer(cb,dc,
data->flush = 0; 0,data->outputBuffer,
return DECODE_BREAK; MP3_DATA_OUTPUT_BUFFER_SIZE,
} data->elapsedTime,
data->outputPtr = data->outputBuffer; data->bitRate/1000);
if(dc->seek) break; 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) { ...@@ -534,7 +529,7 @@ void initAudioFormatFromMp3DecodeData(mp3DecodeData * data, AudioFormat * af) {
af->channels = MAD_NCHANNELS(&(data->frame).header); 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; mp3DecodeData data;
if(openMp3(dc->file,&data) < 0) { if(openMp3(dc->file,&data) < 0) {
...@@ -550,7 +545,9 @@ int mp3_decode(Buffer * cb, AudioFormat * af, DecoderControl * dc) { ...@@ -550,7 +545,9 @@ int mp3_decode(Buffer * cb, AudioFormat * af, DecoderControl * dc) {
while(mp3Read(&data,cb,dc)!=DECODE_BREAK); while(mp3Read(&data,cb,dc)!=DECODE_BREAK);
/* send last little bit if not dc->stop */ /* send last little bit if not dc->stop */
if(data.outputPtr!=data.outputBuffer && data.flush) { 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); mp3DecodeDataFinalize(&data);
...@@ -567,4 +564,4 @@ int mp3_decode(Buffer * cb, AudioFormat * af, DecoderControl * dc) { ...@@ -567,4 +564,4 @@ int mp3_decode(Buffer * cb, AudioFormat * af, DecoderControl * dc) {
} }
#endif #endif
/* vim:set shiftwidth=4 tabstop=8 expandtab: */ /* vim:set shiftwidth=8 tabstop=8 expandtab: */
...@@ -28,7 +28,7 @@ ...@@ -28,7 +28,7 @@
/* this is primarily used in tag.c */ /* this is primarily used in tag.c */
int getMp3TotalTime(char * file); int getMp3TotalTime(char * file);
int mp3_decode(Buffer * cb, AudioFormat * af, DecoderControl * dc); int mp3_decode(OutputBuffer * cb, AudioFormat * af, DecoderControl * dc);
#endif #endif
......
...@@ -84,7 +84,7 @@ uint32_t mp4_inputStreamSeekCallback(void *inStream, uint64_t position) { ...@@ -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_t * mp4fh;
mp4ff_callback_t * mp4cb; mp4ff_callback_t * mp4cb;
int32_t track; int32_t track;
......
...@@ -29,7 +29,7 @@ ...@@ -29,7 +29,7 @@
int mp4_getAACTrack(mp4ff_t *infile); 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 mp4_inputStreamReadCallback(void *inStream, void *buffer,
uint32_t length); uint32_t length);
......
...@@ -82,7 +82,7 @@ long ogg_tell_cb(void * inStream) { ...@@ -82,7 +82,7 @@ long ogg_tell_cb(void * inStream) {
return ((InputStream *)inStream)->offset; 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; OggVorbis_File vf;
ov_callbacks callbacks; ov_callbacks callbacks;
......
...@@ -25,7 +25,7 @@ ...@@ -25,7 +25,7 @@
#include <stdio.h> #include <stdio.h>
int ogg_decode(Buffer * cb, AudioFormat * af, DecoderControl * dc); int ogg_decode(OutputBuffer * cb, AudioFormat * af, DecoderControl * dc);
int getOggTotalTime(char * file); int getOggTotalTime(char * file);
......
...@@ -20,17 +20,13 @@ ...@@ -20,17 +20,13 @@
#include "pcm_utils.h" #include "pcm_utils.h"
#include "playerData.h" #include "playerData.h"
#include "log.h"
#include "utils.h" #include "utils.h"
#include <string.h> #include <string.h>
#include <errno.h>
#define OUTPUT_BUFFER_DC_STOP -1 long sendDataToOutputBuffer(OutputBuffer * cb, DecoderControl * dc,
#define OUTPUT_BUFFER_DC_SEEK -2 int flushAllData, char * data, long datalen, float time,
mpd_uint16 bitRate)
long sendDataToOutputBuffer(Buffer * cb, DecoderControl * dc, int flushAllData,
char * data, long datalen, float time, mpd_uint16 bitRate)
{ {
long dataSent = 0; long dataSent = 0;
long dataToSend; long dataToSend;
......
/* 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: */
...@@ -39,7 +39,7 @@ void initPlayerData() { ...@@ -39,7 +39,7 @@ void initPlayerData() {
int crossfade = 0; int crossfade = 0;
size_t bufferSize; size_t bufferSize;
size_t allocationSize; size_t allocationSize;
Buffer * buffer; OutputBuffer * buffer;
bufferSize = strtol(getConf()[CONF_BUFFER_SIZE],&test,10); bufferSize = strtol(getConf()[CONF_BUFFER_SIZE],&test,10);
if(*test!='\0' || bufferSize<=0) { if(*test!='\0' || bufferSize<=0) {
......
...@@ -25,6 +25,7 @@ ...@@ -25,6 +25,7 @@
#include "player.h" #include "player.h"
#include "decode.h" #include "decode.h"
#include "mpd_types.h" #include "mpd_types.h"
#include "outputBuffer.h"
/* pick 1020 since its devisible for 8,16,24, and 32-bit audio */ /* pick 1020 since its devisible for 8,16,24, and 32-bit audio */
#define CHUNK_SIZE 1020 #define CHUNK_SIZE 1020
...@@ -32,20 +33,8 @@ ...@@ -32,20 +33,8 @@
extern int buffered_before_play; extern int buffered_before_play;
extern int buffered_chunks; 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 { typedef struct _PlayerData {
Buffer buffer; OutputBuffer buffer;
AudioFormat audioFormat; AudioFormat audioFormat;
PlayerControl playerControl; PlayerControl playerControl;
DecoderControl decoderControl; DecoderControl decoderControl;
...@@ -54,7 +43,6 @@ typedef struct _PlayerData { ...@@ -54,7 +43,6 @@ typedef struct _PlayerData {
void initPlayerData(); void initPlayerData();
PlayerData * getPlayerData(); PlayerData * getPlayerData();
Buffer * getBuffer();
void freePlayerData(); void freePlayerData();
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment