some more work on organizing code for resampling/audioFormat conversion

git-svn-id: https://svn.musicpd.org/mpd/trunk@968 09075e82-0dd4-0310-85a5-a0d7c8717e4f
This commit is contained in:
Warren Dukes 2004-05-10 12:35:18 +00:00
parent cd3180c701
commit 2ec1c5ff3c
17 changed files with 100 additions and 87 deletions

View File

@ -251,7 +251,7 @@ int getAacTotalTime(char * file) {
}
int aac_decode(OutputBuffer * cb, AudioFormat * af, DecoderControl * dc) {
int aac_decode(OutputBuffer * cb, DecoderControl * dc) {
float time;
float totalTime;
faacDecHandle decoder;
@ -306,9 +306,9 @@ int aac_decode(OutputBuffer * cb, AudioFormat * af, DecoderControl * dc) {
return -1;
}
af->bits = 16;
dc->audioFormat.bits = 16;
cb->totalTime = totalTime;
dc->totalTime = totalTime;
time = 0.0;
@ -342,8 +342,10 @@ int aac_decode(OutputBuffer * cb, AudioFormat * af, DecoderControl * dc) {
#endif
if(dc->start) {
af->channels = frameInfo.channels;
af->sampleRate = sampleRate;
dc->audioFormat.channels = frameInfo.channels;
dc->audioFormat.sampleRate = sampleRate;
getOutputAudioFormat(&(dc->audioFormat),
&(cb->audioFormat));
dc->state = DECODE_STATE_DECODE;
dc->start = 0;
}

View File

@ -27,7 +27,7 @@
int getAacTotalTime(char * file);
int aac_decode(OutputBuffer * cb, AudioFormat * af, DecoderControl * dc);
int aac_decode(OutputBuffer * cb, DecoderControl * dc);
#endif /* HAVE_FAAD */

View File

@ -51,8 +51,7 @@ int getAudiofileTotalTime(char * file)
return time;
}
int audiofile_decode(OutputBuffer * cb, AudioFormat * af, DecoderControl * dc)
{
int audiofile_decode(OutputBuffer * cb, DecoderControl * dc) {
int fs, frame_count;
AFfilehandle af_fp;
int bits;
@ -71,19 +70,20 @@ int audiofile_decode(OutputBuffer * cb, AudioFormat * af, DecoderControl * dc)
}
afGetSampleFormat(af_fp, AF_DEFAULT_TRACK, &fs, &bits);
af->bits = bits;
af->sampleRate = afGetRate(af_fp, AF_DEFAULT_TRACK);
af->channels = afGetChannels(af_fp,AF_DEFAULT_TRACK);
dc->audioFormat.bits = bits;
dc->audioFormat.sampleRate = afGetRate(af_fp, AF_DEFAULT_TRACK);
dc->audioFormat.channels = afGetChannels(af_fp,AF_DEFAULT_TRACK);
getOutputAudioFormat(&(dc->audioFormat),&(cb->audioFormat));
frame_count = afGetFrameCount(af_fp,AF_DEFAULT_TRACK);
cb->totalTime = ((float)frame_count/(float)af->sampleRate);
dc->totalTime = ((float)frame_count/(float)dc->audioFormat.sampleRate);
bitRate = st.st_size*8.0/cb->totalTime/1000.0+0.5;
bitRate = st.st_size*8.0/dc->totalTime/1000.0+0.5;
if (af->bits != 8 && af->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",
dc->file,af->bits);
dc->file,dc->audioFormat.bits);
afCloseFile(af_fp);
return -1;
}
@ -100,7 +100,8 @@ int audiofile_decode(OutputBuffer * cb, AudioFormat * af, DecoderControl * dc)
if(dc->seek) {
cb->end = cb->begin;
cb->wrap = 0;
current = dc->seekWhere * af->sampleRate;
current = dc->seekWhere *
dc->audioFormat.sampleRate;
afSeekFrame(af_fp, AF_DEFAULT_TRACK,current);
dc->seek = 0;
@ -111,9 +112,9 @@ int audiofile_decode(OutputBuffer * cb, AudioFormat * af, DecoderControl * dc)
else {
current += ret;
sendDataToOutputBuffer(cb,dc,chunk,ret*fs,
(float)current /
(float)af->sampleRate,
bitRate);
(float)current /
(float)dc->audioFormat.sampleRate,
bitRate);
if(dc->stop) break;
else if(dc->seek) continue;
}

View File

@ -27,7 +27,7 @@
#include "playerData.h"
int audiofile_decode(OutputBuffer * cb, AudioFormat * af, DecoderControl * dc);
int audiofile_decode(OutputBuffer * cb, DecoderControl * dc);
int getAudiofileTotalTime(char * file);

View File

@ -111,9 +111,7 @@ int calculateCrossFadeChunks(PlayerControl * pc, AudioFormat * af) {
return (int)chunks;
}
int waitOnDecode(PlayerControl * pc, AudioFormat * af, DecoderControl * dc,
OutputBuffer * cb)
{
int waitOnDecode(PlayerControl * pc, DecoderControl * dc, OutputBuffer * cb) {
while(decode_pid && *decode_pid>0 && dc->start) my_usleep(1000);
if(dc->start || dc->error!=DECODE_ERROR_NOERROR) {
@ -124,7 +122,7 @@ int waitOnDecode(PlayerControl * pc, AudioFormat * af, DecoderControl * dc,
return -1;
}
if(openAudioDevice(af)<0) {
if(openAudioDevice(&(cb->audioFormat))<0) {
strncpy(pc->erroredFile,pc->file,MAXPATHLEN);
pc->erroredFile[MAXPATHLEN] = '\0';
pc->error = PLAYER_ERROR_AUDIO;
@ -132,19 +130,17 @@ int waitOnDecode(PlayerControl * pc, AudioFormat * af, DecoderControl * dc,
return -1;
}
pc->totalTime = cb->totalTime;
pc->totalTime = dc->totalTime;
pc->elapsedTime = 0;
pc->bitRate = 0;
pc->sampleRate = af->sampleRate;
pc->bits = af->bits;
pc->channels = af->channels;
pc->sampleRate = dc->audioFormat.sampleRate;
pc->bits = dc->audioFormat.bits;
pc->channels = dc->audioFormat.channels;
return 0;
}
void decodeSeek(PlayerControl * pc, AudioFormat * af, DecoderControl * dc,
OutputBuffer * cb)
{
void decodeSeek(PlayerControl * pc, DecoderControl * dc, OutputBuffer * cb) {
if(decode_pid && *decode_pid>0) {
cb->next = -1;
if(dc->state!=DECODE_STATE_DECODE || dc->error ||
@ -156,7 +152,7 @@ void decodeSeek(PlayerControl * pc, AudioFormat * af, DecoderControl * dc,
cb->wrap = 0;
dc->error = 0;
dc->start = 1;
waitOnDecode(pc,af,dc,cb);
waitOnDecode(pc,dc,cb);
}
if(*decode_pid>0 && dc->state==DECODE_STATE_DECODE) {
dc->seekWhere = pc->seekWhere > pc->totalTime-0.1 ?
@ -205,7 +201,7 @@ void decodeSeek(PlayerControl * pc, AudioFormat * af, DecoderControl * dc,
} \
if(pc->seek) { \
pc->totalPlayTime+= pc->elapsedTime-pc->beginTime; \
decodeSeek(pc,af,dc,cb); \
decodeSeek(pc,dc,cb); \
pc->beginTime = pc->elapsedTime; \
doCrossFade = 0; \
nextChunk = -1; \
@ -217,8 +213,8 @@ void decodeSeek(PlayerControl * pc, AudioFormat * af, DecoderControl * dc,
return; \
}
int decoderInit(PlayerControl * pc, OutputBuffer * cb, AudioFormat *af,
DecoderControl * dc) {
int decoderInit(PlayerControl * pc, OutputBuffer * cb, DecoderControl * dc) {
int pid;
int ret;
decode_pid = &(pc->decode_pid);
@ -237,30 +233,30 @@ int decoderInit(PlayerControl * pc, OutputBuffer * cb, AudioFormat *af,
switch(pc->decodeType) {
#ifdef HAVE_MAD
case DECODE_TYPE_MP3:
ret = mp3_decode(cb,af,dc);
ret = mp3_decode(cb,dc);
break;
#endif
#ifdef HAVE_FAAD
case DECODE_TYPE_AAC:
ret = aac_decode(cb,af,dc);
ret = aac_decode(cb,dc);
break;
case DECODE_TYPE_MP4:
ret = mp4_decode(cb,af,dc);
ret = mp4_decode(cb,dc);
break;
#endif
#ifdef HAVE_OGG
case DECODE_TYPE_OGG:
ret = ogg_decode(cb,af,dc);
ret = ogg_decode(cb,dc);
break;
#endif
#ifdef HAVE_FLAC
case DECODE_TYPE_FLAC:
ret = flac_decode(cb,af,dc);
ret = flac_decode(cb,dc);
break;
#endif
#ifdef HAVE_AUDIOFILE
case DECODE_TYPE_AUDIOFILE:
ret = audiofile_decode(cb,af,dc);
ret = audiofile_decode(cb,dc);
break;
#endif
default:
@ -313,7 +309,6 @@ int decoderInit(PlayerControl * pc, OutputBuffer * cb, AudioFormat *af,
void decode() {
OutputBuffer * cb;
PlayerControl * pc;
AudioFormat * af;
DecoderControl * dc;
cb = &(getPlayerData()->buffer);
@ -323,13 +318,12 @@ void decode() {
cb->wrap = 0;
pc = &(getPlayerData()->playerControl);
dc = &(getPlayerData()->decoderControl);
af = &(getPlayerData()->audioFormat);
dc->error = 0;
dc->start = 1;
cb->next = -1;
if(decode_pid==NULL || *decode_pid<=0) {
if(decoderInit(pc,cb,af,dc)<0) return;
if(decoderInit(pc,cb,dc)<0) return;
}
{
@ -343,7 +337,7 @@ void decode() {
int nextChunk = -1;
int test;
if(waitOnDecode(pc,af,dc,cb)<0) return;
if(waitOnDecode(pc,dc,cb)<0) return;
pc->state = PLAYER_STATE_PLAY;
pc->play = 0;
@ -371,12 +365,13 @@ void decode() {
}
if(cb->next>=0 && doCrossFade==0 && !dc->start) {
nextChunk = -1;
if(isCurrentAudioFormat(af)) {
if(isCurrentAudioFormat(&(cb->audioFormat))) {
doCrossFade = 1;
crossFadeChunks =
calculateCrossFadeChunks(pc,af);
calculateCrossFadeChunks(pc,
&(cb->audioFormat));
if(!crossFadeChunks ||
pc->crossFade>=cb->totalTime)
pc->crossFade>=dc->totalTime)
{
doCrossFade = -1;
}
@ -415,7 +410,7 @@ void decode() {
cb->begin],
cb->chunkSize[
nextChunk],
af,
&(cb->audioFormat),
((float)fadePosition)/
crossFadeChunks);
if(cb->chunkSize[nextChunk]>
@ -440,7 +435,7 @@ void decode() {
pcm_volumeChange(cb->chunks+cb->begin*
CHUNK_SIZE,
cb->chunkSize[cb->begin],
af,
&(cb->audioFormat),
pc->softwareVolume);
if(playAudio(cb->chunks+cb->begin*CHUNK_SIZE,
cb->chunkSize[cb->begin])<0)
@ -485,7 +480,7 @@ void decode() {
}
else {
cb->next = -1;
if(waitOnDecode(pc,af,dc,cb)<0) return;
if(waitOnDecode(pc,dc,cb)<0) return;
nextChunk = -1;
doCrossFade = 0;
crossFadeChunks = 0;

View File

@ -22,6 +22,7 @@
#include "../config.h"
#include "mpd_types.h"
#include "audio.h"
#include <stdio.h>
#include <sys/param.h>
@ -48,8 +49,10 @@ typedef struct _DecoderControl {
volatile mpd_sint8 seek;
volatile mpd_sint8 seekError;
volatile mpd_sint8 cycleLogFiles;
double seekWhere;
volatile double seekWhere;
char file[MAXPATHLEN+1];
AudioFormat audioFormat;
volatile float totalTime;
} DecoderControl;
void decodeSigHandler(int sig);

View File

@ -26,6 +26,7 @@
#include "inputStream.h"
#include "outputBuffer.h"
#include "replayGain.h"
#include "audio.h"
#include <stdio.h>
#include <string.h>
@ -40,7 +41,6 @@ typedef struct {
int bitRate;
FLAC__uint64 position;
OutputBuffer * cb;
AudioFormat * af;
DecoderControl * dc;
InputStream inStream;
float replayGainScale;
@ -67,7 +67,7 @@ FLAC__SeekableStreamDecoderLengthStatus flacLength(
const FLAC__SeekableStreamDecoder *, FLAC__uint64 *, void *);
FLAC__bool flacEOF(const FLAC__SeekableStreamDecoder *, void *);
int flac_decode(OutputBuffer * cb, AudioFormat * af, DecoderControl *dc) {
int flac_decode(OutputBuffer * cb, DecoderControl *dc) {
FLAC__SeekableStreamDecoder * flacDec;
FlacData data;
int status = 1;
@ -77,7 +77,6 @@ int flac_decode(OutputBuffer * cb, AudioFormat * af, DecoderControl *dc) {
data.position = 0;
data.bitRate = 0;
data.cb = cb;
data.af = af;
data.dc = dc;
data.replayGainScale = 1.0;
@ -146,14 +145,14 @@ int flac_decode(OutputBuffer * cb, AudioFormat * af, DecoderControl *dc) {
}
if(dc->seek) {
FLAC__uint64 sampleToSeek = dc->seekWhere*
af->sampleRate+0.5;
dc->audioFormat.sampleRate+0.5;
cb->end = cb->begin;
cb->wrap = 0;
if(FLAC__seekable_stream_decoder_seek_absolute(flacDec,
sampleToSeek))
{
data.time = ((float)sampleToSeek)/
af->sampleRate;
dc->audioFormat.sampleRate;
data.position = 0;
}
dc->seek = 0;
@ -354,13 +353,17 @@ void flacMetadata(const FLAC__SeekableStreamDecoder *dec,
switch(block->type) {
case FLAC__METADATA_TYPE_STREAMINFO:
data->af->bits = block->data.stream_info.bits_per_sample;
data->af->bits = 16;
data->af->sampleRate = block->data.stream_info.sample_rate;
data->af->channels = block->data.stream_info.channels;
data->cb->totalTime =
data->dc->audioFormat.bits =
block->data.stream_info.bits_per_sample;
data->dc->audioFormat.sampleRate =
block->data.stream_info.sample_rate;
data->dc->audioFormat.channels =
block->data.stream_info.channels;
data->dc->totalTime =
((float)block->data.stream_info.total_samples)/
data->af->sampleRate;
data->dc->audioFormat.sampleRate;
getOutputAudioFormat(&(data->dc->audioFormat),
&(data->cb->audioFormat));
break;
case FLAC__METADATA_TYPE_VORBIS_COMMENT:
flacParseReplayGain(block,data);
@ -370,7 +373,7 @@ void flacMetadata(const FLAC__SeekableStreamDecoder *dec,
}
int flacSendChunk(FlacData * data) {
doReplayGain(data->chunk,data->chunk_length,data->af,
doReplayGain(data->chunk,data->chunk_length,&(data->dc->audioFormat),
data->replayGainScale);
switch(sendDataToOutputBuffer(data->cb,data->dc,data->chunk,
@ -413,7 +416,7 @@ FLAC__StreamDecoderWriteStatus flacWrite(const FLAC__SeekableStreamDecoder *dec,
c_chan++, d_samp++) {
u16 = buf[c_chan][c_samp];
uc = (unsigned char *)&u16;
for(i=0;i<(data->af->bits/8);i++) {
for(i=0;i<(data->dc->audioFormat.bits/8);i++) {
if(data->chunk_length>=CHUNK_SIZE) {
if(flacSendChunk(data)<0) {
return FLAC__STREAM_DECODER_WRITE_STATUS_ABORT;

View File

@ -25,7 +25,7 @@
#include <stdio.h>
int flac_decode(OutputBuffer * cb, AudioFormat * af, DecoderControl * dc);
int flac_decode(OutputBuffer * cb, DecoderControl * dc);
#endif
/* vim:set shiftwidth=8 tabstop=8 expandtab: */

View File

@ -523,7 +523,7 @@ void initAudioFormatFromMp3DecodeData(mp3DecodeData * data, AudioFormat * af) {
af->channels = MAD_NCHANNELS(&(data->frame).header);
}
int mp3_decode(OutputBuffer * cb, AudioFormat * af, DecoderControl * dc) {
int mp3_decode(OutputBuffer * cb, DecoderControl * dc) {
mp3DecodeData data;
if(openMp3(dc->file,&data) < 0) {
@ -531,8 +531,10 @@ int mp3_decode(OutputBuffer * cb, AudioFormat * af, DecoderControl * dc) {
return -1;
}
initAudioFormatFromMp3DecodeData(&data,af);
cb->totalTime = data.totalTime;
initAudioFormatFromMp3DecodeData(&data, &(dc->audioFormat));
getOutputAudioFormat(&(dc->audioFormat), &(cb->audioFormat));
dc->totalTime = data.totalTime;
dc->start = 0;
dc->state = DECODE_STATE_DECODE;

View File

@ -28,7 +28,7 @@
/* this is primarily used in tag.c */
int getMp3TotalTime(char * file);
int mp3_decode(OutputBuffer * cb, AudioFormat * af, DecoderControl * dc);
int mp3_decode(OutputBuffer * cb, DecoderControl * dc);
#endif

View File

@ -84,7 +84,7 @@ uint32_t mp4_inputStreamSeekCallback(void *inStream, uint64_t position) {
}
int mp4_decode(OutputBuffer * cb, AudioFormat * af, DecoderControl * dc) {
int mp4_decode(OutputBuffer * cb, DecoderControl * dc) {
mp4ff_t * mp4fh;
mp4ff_callback_t * mp4cb;
int32_t track;
@ -152,7 +152,7 @@ int mp4_decode(OutputBuffer * cb, AudioFormat * af, DecoderControl * dc) {
#endif
faacDecSetConfiguration(decoder,config);
af->bits = 16;
dc->audioFormat.bits = 16;
mp4Buffer = NULL;
mp4BufferSize = 0;
@ -169,8 +169,8 @@ int mp4_decode(OutputBuffer * cb, AudioFormat * af, DecoderControl * dc) {
return -1;
}
af->sampleRate = sampleRate;
af->channels = channels;
dc->audioFormat.sampleRate = sampleRate;
dc->audioFormat.channels = channels;
time = mp4ff_get_track_duration_use_offsets(mp4fh,track);
scale = mp4ff_time_scale(mp4fh,track);
@ -184,7 +184,7 @@ int mp4_decode(OutputBuffer * cb, AudioFormat * af, DecoderControl * dc) {
free(mp4cb);
return -1;
}
cb->totalTime = ((float)time)/scale;
dc->totalTime = ((float)time)/scale;
numSamples = mp4ff_num_samples(mp4fh,track);
@ -255,8 +255,10 @@ int mp4_decode(OutputBuffer * cb, AudioFormat * af, DecoderControl * dc) {
#ifdef HAVE_FAACDECFRAMEINFO_SAMPLERATE
scale = frameInfo.samplerate;
#endif
af->sampleRate = scale;
af->channels = frameInfo.channels;
dc->audioFormat.sampleRate = scale;
dc->audioFormat.channels = frameInfo.channels;
getOutputAudioFormat(&(dc->audioFormat),
&(cb->audioFormat));
dc->state = DECODE_STATE_DECODE;
dc->start = 0;
}

View File

@ -29,7 +29,7 @@
int mp4_getAACTrack(mp4ff_t *infile);
int mp4_decode(OutputBuffer * cb, AudioFormat * af, DecoderControl * dc);
int mp4_decode(OutputBuffer * cb, DecoderControl * dc);
uint32_t mp4_inputStreamReadCallback(void *inStream, void *buffer,
uint32_t length);

View File

@ -142,7 +142,7 @@ float ogg_getReplayGainScale(char ** comments) {
return 1.0;
}
int ogg_decode(OutputBuffer * cb, AudioFormat * af, DecoderControl * dc)
int ogg_decode(OutputBuffer * cb, DecoderControl * dc)
{
OggVorbis_File vf;
ov_callbacks callbacks;
@ -167,12 +167,13 @@ int ogg_decode(OutputBuffer * cb, AudioFormat * af, DecoderControl * dc)
{
vorbis_info *vi=ov_info(&vf,-1);
af->bits = 16;
af->channels = vi->channels;
af->sampleRate = vi->rate;
dc->audioFormat.bits = 16;
dc->audioFormat.channels = vi->channels;
dc->audioFormat.sampleRate = vi->rate;
getOutputAudioFormat(&(dc->audioFormat),&(cb->audioFormat));
}
cb->totalTime = ov_time_total(&vf,-1);
dc->totalTime = ov_time_total(&vf,-1);
dc->state = DECODE_STATE_DECODE;
dc->start = 0;
@ -203,7 +204,8 @@ int ogg_decode(OutputBuffer * cb, AudioFormat * af, DecoderControl * dc)
if((test = ov_bitrate_instant(&vf))>0) {
bitRate = test/1000;
}
doReplayGain(chunk,ret,af,replayGainScale);
doReplayGain(chunk,ret,&(dc->audioFormat),
replayGainScale);
sendDataToOutputBuffer(cb,dc,chunk,ret,
ov_time_tell(&vf),bitRate);
if(dc->stop) break;

View File

@ -25,7 +25,7 @@
#include <stdio.h>
int ogg_decode(OutputBuffer * cb, AudioFormat * af, DecoderControl * dc);
int ogg_decode(OutputBuffer * cb, DecoderControl * dc);
int getOggTotalTime(char * file);

View File

@ -21,6 +21,7 @@
#include "mpd_types.h"
#include "decode.h"
#include "audio.h"
#define OUTPUT_BUFFER_DC_STOP -1
#define OUTPUT_BUFFER_DC_SEEK -2
@ -34,7 +35,7 @@ typedef struct _OutputBuffer {
mpd_sint16 volatile end;
mpd_sint16 volatile next;
mpd_sint8 volatile wrap;
float totalTime;
AudioFormat audioFormat;
} OutputBuffer;
void flushOutputBuffer(OutputBuffer * cb);

View File

@ -33,5 +33,8 @@ void pcm_volumeChange(char * buffer, int bufferSize, AudioFormat * format,
void pcm_mix(char * buffer1, char * buffer2, size_t bufferSize1,
size_t bufferSize2, AudioFormat * format, float portion1);
void pmc_convertAudioFormat(AudioFormat * inFormat, char * inBuffer, size_t
inSize, size_t * inLeft, AudioFormat * outFormat,
char * outBuffer, size_t outSize, size_t * outLeft);
#endif
/* vim:set shiftwidth=4 tabstop=8 expandtab: */

View File

@ -35,7 +35,6 @@ extern int buffered_chunks;
typedef struct _PlayerData {
OutputBuffer buffer;
AudioFormat audioFormat;
PlayerControl playerControl;
DecoderControl decoderControl;
} PlayerData;