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:
@@ -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 time;
|
||||||
float totalTime;
|
float totalTime;
|
||||||
faacDecHandle decoder;
|
faacDecHandle decoder;
|
||||||
@@ -306,9 +306,9 @@ int aac_decode(OutputBuffer * cb, AudioFormat * af, DecoderControl * dc) {
|
|||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
af->bits = 16;
|
dc->audioFormat.bits = 16;
|
||||||
|
|
||||||
cb->totalTime = totalTime;
|
dc->totalTime = totalTime;
|
||||||
|
|
||||||
time = 0.0;
|
time = 0.0;
|
||||||
|
|
||||||
@@ -342,8 +342,10 @@ int aac_decode(OutputBuffer * cb, AudioFormat * af, DecoderControl * dc) {
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
if(dc->start) {
|
if(dc->start) {
|
||||||
af->channels = frameInfo.channels;
|
dc->audioFormat.channels = frameInfo.channels;
|
||||||
af->sampleRate = sampleRate;
|
dc->audioFormat.sampleRate = sampleRate;
|
||||||
|
getOutputAudioFormat(&(dc->audioFormat),
|
||||||
|
&(cb->audioFormat));
|
||||||
dc->state = DECODE_STATE_DECODE;
|
dc->state = DECODE_STATE_DECODE;
|
||||||
dc->start = 0;
|
dc->start = 0;
|
||||||
}
|
}
|
||||||
|
@@ -27,7 +27,7 @@
|
|||||||
|
|
||||||
int getAacTotalTime(char * file);
|
int getAacTotalTime(char * file);
|
||||||
|
|
||||||
int aac_decode(OutputBuffer * cb, AudioFormat * af, DecoderControl * dc);
|
int aac_decode(OutputBuffer * cb, DecoderControl * dc);
|
||||||
|
|
||||||
#endif /* HAVE_FAAD */
|
#endif /* HAVE_FAAD */
|
||||||
|
|
||||||
|
@@ -51,8 +51,7 @@ int getAudiofileTotalTime(char * file)
|
|||||||
return time;
|
return time;
|
||||||
}
|
}
|
||||||
|
|
||||||
int audiofile_decode(OutputBuffer * cb, AudioFormat * af, DecoderControl * dc)
|
int audiofile_decode(OutputBuffer * cb, DecoderControl * dc) {
|
||||||
{
|
|
||||||
int fs, frame_count;
|
int fs, frame_count;
|
||||||
AFfilehandle af_fp;
|
AFfilehandle af_fp;
|
||||||
int bits;
|
int bits;
|
||||||
@@ -71,19 +70,20 @@ int audiofile_decode(OutputBuffer * cb, AudioFormat * af, DecoderControl * dc)
|
|||||||
}
|
}
|
||||||
|
|
||||||
afGetSampleFormat(af_fp, AF_DEFAULT_TRACK, &fs, &bits);
|
afGetSampleFormat(af_fp, AF_DEFAULT_TRACK, &fs, &bits);
|
||||||
af->bits = bits;
|
dc->audioFormat.bits = bits;
|
||||||
af->sampleRate = afGetRate(af_fp, AF_DEFAULT_TRACK);
|
dc->audioFormat.sampleRate = afGetRate(af_fp, AF_DEFAULT_TRACK);
|
||||||
af->channels = afGetChannels(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);
|
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",
|
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);
|
afCloseFile(af_fp);
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
@@ -100,7 +100,8 @@ int audiofile_decode(OutputBuffer * cb, AudioFormat * af, DecoderControl * dc)
|
|||||||
if(dc->seek) {
|
if(dc->seek) {
|
||||||
cb->end = cb->begin;
|
cb->end = cb->begin;
|
||||||
cb->wrap = 0;
|
cb->wrap = 0;
|
||||||
current = dc->seekWhere * af->sampleRate;
|
current = dc->seekWhere *
|
||||||
|
dc->audioFormat.sampleRate;
|
||||||
afSeekFrame(af_fp, AF_DEFAULT_TRACK,current);
|
afSeekFrame(af_fp, AF_DEFAULT_TRACK,current);
|
||||||
|
|
||||||
dc->seek = 0;
|
dc->seek = 0;
|
||||||
@@ -112,7 +113,7 @@ int audiofile_decode(OutputBuffer * cb, AudioFormat * af, DecoderControl * dc)
|
|||||||
current += ret;
|
current += ret;
|
||||||
sendDataToOutputBuffer(cb,dc,chunk,ret*fs,
|
sendDataToOutputBuffer(cb,dc,chunk,ret*fs,
|
||||||
(float)current /
|
(float)current /
|
||||||
(float)af->sampleRate,
|
(float)dc->audioFormat.sampleRate,
|
||||||
bitRate);
|
bitRate);
|
||||||
if(dc->stop) break;
|
if(dc->stop) break;
|
||||||
else if(dc->seek) continue;
|
else if(dc->seek) continue;
|
||||||
|
@@ -27,7 +27,7 @@
|
|||||||
|
|
||||||
#include "playerData.h"
|
#include "playerData.h"
|
||||||
|
|
||||||
int audiofile_decode(OutputBuffer * cb, AudioFormat * af, DecoderControl * dc);
|
int audiofile_decode(OutputBuffer * cb, DecoderControl * dc);
|
||||||
|
|
||||||
int getAudiofileTotalTime(char * file);
|
int getAudiofileTotalTime(char * file);
|
||||||
|
|
||||||
|
57
src/decode.c
57
src/decode.c
@@ -111,9 +111,7 @@ int calculateCrossFadeChunks(PlayerControl * pc, AudioFormat * af) {
|
|||||||
return (int)chunks;
|
return (int)chunks;
|
||||||
}
|
}
|
||||||
|
|
||||||
int waitOnDecode(PlayerControl * pc, AudioFormat * af, DecoderControl * dc,
|
int waitOnDecode(PlayerControl * pc, DecoderControl * dc, OutputBuffer * 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);
|
||||||
|
|
||||||
if(dc->start || dc->error!=DECODE_ERROR_NOERROR) {
|
if(dc->start || dc->error!=DECODE_ERROR_NOERROR) {
|
||||||
@@ -124,7 +122,7 @@ int waitOnDecode(PlayerControl * pc, AudioFormat * af, DecoderControl * dc,
|
|||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(openAudioDevice(af)<0) {
|
if(openAudioDevice(&(cb->audioFormat))<0) {
|
||||||
strncpy(pc->erroredFile,pc->file,MAXPATHLEN);
|
strncpy(pc->erroredFile,pc->file,MAXPATHLEN);
|
||||||
pc->erroredFile[MAXPATHLEN] = '\0';
|
pc->erroredFile[MAXPATHLEN] = '\0';
|
||||||
pc->error = PLAYER_ERROR_AUDIO;
|
pc->error = PLAYER_ERROR_AUDIO;
|
||||||
@@ -132,19 +130,17 @@ int waitOnDecode(PlayerControl * pc, AudioFormat * af, DecoderControl * dc,
|
|||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
pc->totalTime = cb->totalTime;
|
pc->totalTime = dc->totalTime;
|
||||||
pc->elapsedTime = 0;
|
pc->elapsedTime = 0;
|
||||||
pc->bitRate = 0;
|
pc->bitRate = 0;
|
||||||
pc->sampleRate = af->sampleRate;
|
pc->sampleRate = dc->audioFormat.sampleRate;
|
||||||
pc->bits = af->bits;
|
pc->bits = dc->audioFormat.bits;
|
||||||
pc->channels = af->channels;
|
pc->channels = dc->audioFormat.channels;
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
void decodeSeek(PlayerControl * pc, AudioFormat * af, DecoderControl * dc,
|
void decodeSeek(PlayerControl * pc, DecoderControl * dc, OutputBuffer * cb) {
|
||||||
OutputBuffer * cb)
|
|
||||||
{
|
|
||||||
if(decode_pid && *decode_pid>0) {
|
if(decode_pid && *decode_pid>0) {
|
||||||
cb->next = -1;
|
cb->next = -1;
|
||||||
if(dc->state!=DECODE_STATE_DECODE || dc->error ||
|
if(dc->state!=DECODE_STATE_DECODE || dc->error ||
|
||||||
@@ -156,7 +152,7 @@ void decodeSeek(PlayerControl * pc, AudioFormat * af, DecoderControl * dc,
|
|||||||
cb->wrap = 0;
|
cb->wrap = 0;
|
||||||
dc->error = 0;
|
dc->error = 0;
|
||||||
dc->start = 1;
|
dc->start = 1;
|
||||||
waitOnDecode(pc,af,dc,cb);
|
waitOnDecode(pc,dc,cb);
|
||||||
}
|
}
|
||||||
if(*decode_pid>0 && dc->state==DECODE_STATE_DECODE) {
|
if(*decode_pid>0 && dc->state==DECODE_STATE_DECODE) {
|
||||||
dc->seekWhere = pc->seekWhere > pc->totalTime-0.1 ?
|
dc->seekWhere = pc->seekWhere > pc->totalTime-0.1 ?
|
||||||
@@ -205,7 +201,7 @@ void decodeSeek(PlayerControl * pc, AudioFormat * af, DecoderControl * dc,
|
|||||||
} \
|
} \
|
||||||
if(pc->seek) { \
|
if(pc->seek) { \
|
||||||
pc->totalPlayTime+= pc->elapsedTime-pc->beginTime; \
|
pc->totalPlayTime+= pc->elapsedTime-pc->beginTime; \
|
||||||
decodeSeek(pc,af,dc,cb); \
|
decodeSeek(pc,dc,cb); \
|
||||||
pc->beginTime = pc->elapsedTime; \
|
pc->beginTime = pc->elapsedTime; \
|
||||||
doCrossFade = 0; \
|
doCrossFade = 0; \
|
||||||
nextChunk = -1; \
|
nextChunk = -1; \
|
||||||
@@ -217,8 +213,8 @@ void decodeSeek(PlayerControl * pc, AudioFormat * af, DecoderControl * dc,
|
|||||||
return; \
|
return; \
|
||||||
}
|
}
|
||||||
|
|
||||||
int decoderInit(PlayerControl * pc, OutputBuffer * cb, AudioFormat *af,
|
int decoderInit(PlayerControl * pc, OutputBuffer * cb, DecoderControl * dc) {
|
||||||
DecoderControl * dc) {
|
|
||||||
int pid;
|
int pid;
|
||||||
int ret;
|
int ret;
|
||||||
decode_pid = &(pc->decode_pid);
|
decode_pid = &(pc->decode_pid);
|
||||||
@@ -237,30 +233,30 @@ int decoderInit(PlayerControl * pc, OutputBuffer * cb, AudioFormat *af,
|
|||||||
switch(pc->decodeType) {
|
switch(pc->decodeType) {
|
||||||
#ifdef HAVE_MAD
|
#ifdef HAVE_MAD
|
||||||
case DECODE_TYPE_MP3:
|
case DECODE_TYPE_MP3:
|
||||||
ret = mp3_decode(cb,af,dc);
|
ret = mp3_decode(cb,dc);
|
||||||
break;
|
break;
|
||||||
#endif
|
#endif
|
||||||
#ifdef HAVE_FAAD
|
#ifdef HAVE_FAAD
|
||||||
case DECODE_TYPE_AAC:
|
case DECODE_TYPE_AAC:
|
||||||
ret = aac_decode(cb,af,dc);
|
ret = aac_decode(cb,dc);
|
||||||
break;
|
break;
|
||||||
case DECODE_TYPE_MP4:
|
case DECODE_TYPE_MP4:
|
||||||
ret = mp4_decode(cb,af,dc);
|
ret = mp4_decode(cb,dc);
|
||||||
break;
|
break;
|
||||||
#endif
|
#endif
|
||||||
#ifdef HAVE_OGG
|
#ifdef HAVE_OGG
|
||||||
case DECODE_TYPE_OGG:
|
case DECODE_TYPE_OGG:
|
||||||
ret = ogg_decode(cb,af,dc);
|
ret = ogg_decode(cb,dc);
|
||||||
break;
|
break;
|
||||||
#endif
|
#endif
|
||||||
#ifdef HAVE_FLAC
|
#ifdef HAVE_FLAC
|
||||||
case DECODE_TYPE_FLAC:
|
case DECODE_TYPE_FLAC:
|
||||||
ret = flac_decode(cb,af,dc);
|
ret = flac_decode(cb,dc);
|
||||||
break;
|
break;
|
||||||
#endif
|
#endif
|
||||||
#ifdef HAVE_AUDIOFILE
|
#ifdef HAVE_AUDIOFILE
|
||||||
case DECODE_TYPE_AUDIOFILE:
|
case DECODE_TYPE_AUDIOFILE:
|
||||||
ret = audiofile_decode(cb,af,dc);
|
ret = audiofile_decode(cb,dc);
|
||||||
break;
|
break;
|
||||||
#endif
|
#endif
|
||||||
default:
|
default:
|
||||||
@@ -313,7 +309,6 @@ int decoderInit(PlayerControl * pc, OutputBuffer * cb, AudioFormat *af,
|
|||||||
void decode() {
|
void decode() {
|
||||||
OutputBuffer * cb;
|
OutputBuffer * cb;
|
||||||
PlayerControl * pc;
|
PlayerControl * pc;
|
||||||
AudioFormat * af;
|
|
||||||
DecoderControl * dc;
|
DecoderControl * dc;
|
||||||
|
|
||||||
cb = &(getPlayerData()->buffer);
|
cb = &(getPlayerData()->buffer);
|
||||||
@@ -323,13 +318,12 @@ void decode() {
|
|||||||
cb->wrap = 0;
|
cb->wrap = 0;
|
||||||
pc = &(getPlayerData()->playerControl);
|
pc = &(getPlayerData()->playerControl);
|
||||||
dc = &(getPlayerData()->decoderControl);
|
dc = &(getPlayerData()->decoderControl);
|
||||||
af = &(getPlayerData()->audioFormat);
|
|
||||||
dc->error = 0;
|
dc->error = 0;
|
||||||
dc->start = 1;
|
dc->start = 1;
|
||||||
cb->next = -1;
|
cb->next = -1;
|
||||||
|
|
||||||
if(decode_pid==NULL || *decode_pid<=0) {
|
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 nextChunk = -1;
|
||||||
int test;
|
int test;
|
||||||
|
|
||||||
if(waitOnDecode(pc,af,dc,cb)<0) return;
|
if(waitOnDecode(pc,dc,cb)<0) return;
|
||||||
|
|
||||||
pc->state = PLAYER_STATE_PLAY;
|
pc->state = PLAYER_STATE_PLAY;
|
||||||
pc->play = 0;
|
pc->play = 0;
|
||||||
@@ -371,12 +365,13 @@ void decode() {
|
|||||||
}
|
}
|
||||||
if(cb->next>=0 && doCrossFade==0 && !dc->start) {
|
if(cb->next>=0 && doCrossFade==0 && !dc->start) {
|
||||||
nextChunk = -1;
|
nextChunk = -1;
|
||||||
if(isCurrentAudioFormat(af)) {
|
if(isCurrentAudioFormat(&(cb->audioFormat))) {
|
||||||
doCrossFade = 1;
|
doCrossFade = 1;
|
||||||
crossFadeChunks =
|
crossFadeChunks =
|
||||||
calculateCrossFadeChunks(pc,af);
|
calculateCrossFadeChunks(pc,
|
||||||
|
&(cb->audioFormat));
|
||||||
if(!crossFadeChunks ||
|
if(!crossFadeChunks ||
|
||||||
pc->crossFade>=cb->totalTime)
|
pc->crossFade>=dc->totalTime)
|
||||||
{
|
{
|
||||||
doCrossFade = -1;
|
doCrossFade = -1;
|
||||||
}
|
}
|
||||||
@@ -415,7 +410,7 @@ void decode() {
|
|||||||
cb->begin],
|
cb->begin],
|
||||||
cb->chunkSize[
|
cb->chunkSize[
|
||||||
nextChunk],
|
nextChunk],
|
||||||
af,
|
&(cb->audioFormat),
|
||||||
((float)fadePosition)/
|
((float)fadePosition)/
|
||||||
crossFadeChunks);
|
crossFadeChunks);
|
||||||
if(cb->chunkSize[nextChunk]>
|
if(cb->chunkSize[nextChunk]>
|
||||||
@@ -440,7 +435,7 @@ void decode() {
|
|||||||
pcm_volumeChange(cb->chunks+cb->begin*
|
pcm_volumeChange(cb->chunks+cb->begin*
|
||||||
CHUNK_SIZE,
|
CHUNK_SIZE,
|
||||||
cb->chunkSize[cb->begin],
|
cb->chunkSize[cb->begin],
|
||||||
af,
|
&(cb->audioFormat),
|
||||||
pc->softwareVolume);
|
pc->softwareVolume);
|
||||||
if(playAudio(cb->chunks+cb->begin*CHUNK_SIZE,
|
if(playAudio(cb->chunks+cb->begin*CHUNK_SIZE,
|
||||||
cb->chunkSize[cb->begin])<0)
|
cb->chunkSize[cb->begin])<0)
|
||||||
@@ -485,7 +480,7 @@ void decode() {
|
|||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
cb->next = -1;
|
cb->next = -1;
|
||||||
if(waitOnDecode(pc,af,dc,cb)<0) return;
|
if(waitOnDecode(pc,dc,cb)<0) return;
|
||||||
nextChunk = -1;
|
nextChunk = -1;
|
||||||
doCrossFade = 0;
|
doCrossFade = 0;
|
||||||
crossFadeChunks = 0;
|
crossFadeChunks = 0;
|
||||||
|
@@ -22,6 +22,7 @@
|
|||||||
#include "../config.h"
|
#include "../config.h"
|
||||||
|
|
||||||
#include "mpd_types.h"
|
#include "mpd_types.h"
|
||||||
|
#include "audio.h"
|
||||||
|
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <sys/param.h>
|
#include <sys/param.h>
|
||||||
@@ -48,8 +49,10 @@ typedef struct _DecoderControl {
|
|||||||
volatile mpd_sint8 seek;
|
volatile mpd_sint8 seek;
|
||||||
volatile mpd_sint8 seekError;
|
volatile mpd_sint8 seekError;
|
||||||
volatile mpd_sint8 cycleLogFiles;
|
volatile mpd_sint8 cycleLogFiles;
|
||||||
double seekWhere;
|
volatile double seekWhere;
|
||||||
char file[MAXPATHLEN+1];
|
char file[MAXPATHLEN+1];
|
||||||
|
AudioFormat audioFormat;
|
||||||
|
volatile float totalTime;
|
||||||
} DecoderControl;
|
} DecoderControl;
|
||||||
|
|
||||||
void decodeSigHandler(int sig);
|
void decodeSigHandler(int sig);
|
||||||
|
@@ -26,6 +26,7 @@
|
|||||||
#include "inputStream.h"
|
#include "inputStream.h"
|
||||||
#include "outputBuffer.h"
|
#include "outputBuffer.h"
|
||||||
#include "replayGain.h"
|
#include "replayGain.h"
|
||||||
|
#include "audio.h"
|
||||||
|
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
@@ -40,7 +41,6 @@ typedef struct {
|
|||||||
int bitRate;
|
int bitRate;
|
||||||
FLAC__uint64 position;
|
FLAC__uint64 position;
|
||||||
OutputBuffer * cb;
|
OutputBuffer * cb;
|
||||||
AudioFormat * af;
|
|
||||||
DecoderControl * dc;
|
DecoderControl * dc;
|
||||||
InputStream inStream;
|
InputStream inStream;
|
||||||
float replayGainScale;
|
float replayGainScale;
|
||||||
@@ -67,7 +67,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 *);
|
||||||
|
|
||||||
int flac_decode(OutputBuffer * cb, AudioFormat * af, DecoderControl *dc) {
|
int flac_decode(OutputBuffer * cb, DecoderControl *dc) {
|
||||||
FLAC__SeekableStreamDecoder * flacDec;
|
FLAC__SeekableStreamDecoder * flacDec;
|
||||||
FlacData data;
|
FlacData data;
|
||||||
int status = 1;
|
int status = 1;
|
||||||
@@ -77,7 +77,6 @@ int flac_decode(OutputBuffer * cb, AudioFormat * af, DecoderControl *dc) {
|
|||||||
data.position = 0;
|
data.position = 0;
|
||||||
data.bitRate = 0;
|
data.bitRate = 0;
|
||||||
data.cb = cb;
|
data.cb = cb;
|
||||||
data.af = af;
|
|
||||||
data.dc = dc;
|
data.dc = dc;
|
||||||
data.replayGainScale = 1.0;
|
data.replayGainScale = 1.0;
|
||||||
|
|
||||||
@@ -146,14 +145,14 @@ int flac_decode(OutputBuffer * cb, AudioFormat * af, DecoderControl *dc) {
|
|||||||
}
|
}
|
||||||
if(dc->seek) {
|
if(dc->seek) {
|
||||||
FLAC__uint64 sampleToSeek = dc->seekWhere*
|
FLAC__uint64 sampleToSeek = dc->seekWhere*
|
||||||
af->sampleRate+0.5;
|
dc->audioFormat.sampleRate+0.5;
|
||||||
cb->end = cb->begin;
|
cb->end = cb->begin;
|
||||||
cb->wrap = 0;
|
cb->wrap = 0;
|
||||||
if(FLAC__seekable_stream_decoder_seek_absolute(flacDec,
|
if(FLAC__seekable_stream_decoder_seek_absolute(flacDec,
|
||||||
sampleToSeek))
|
sampleToSeek))
|
||||||
{
|
{
|
||||||
data.time = ((float)sampleToSeek)/
|
data.time = ((float)sampleToSeek)/
|
||||||
af->sampleRate;
|
dc->audioFormat.sampleRate;
|
||||||
data.position = 0;
|
data.position = 0;
|
||||||
}
|
}
|
||||||
dc->seek = 0;
|
dc->seek = 0;
|
||||||
@@ -354,13 +353,17 @@ void flacMetadata(const FLAC__SeekableStreamDecoder *dec,
|
|||||||
|
|
||||||
switch(block->type) {
|
switch(block->type) {
|
||||||
case FLAC__METADATA_TYPE_STREAMINFO:
|
case FLAC__METADATA_TYPE_STREAMINFO:
|
||||||
data->af->bits = block->data.stream_info.bits_per_sample;
|
data->dc->audioFormat.bits =
|
||||||
data->af->bits = 16;
|
block->data.stream_info.bits_per_sample;
|
||||||
data->af->sampleRate = block->data.stream_info.sample_rate;
|
data->dc->audioFormat.sampleRate =
|
||||||
data->af->channels = block->data.stream_info.channels;
|
block->data.stream_info.sample_rate;
|
||||||
data->cb->totalTime =
|
data->dc->audioFormat.channels =
|
||||||
|
block->data.stream_info.channels;
|
||||||
|
data->dc->totalTime =
|
||||||
((float)block->data.stream_info.total_samples)/
|
((float)block->data.stream_info.total_samples)/
|
||||||
data->af->sampleRate;
|
data->dc->audioFormat.sampleRate;
|
||||||
|
getOutputAudioFormat(&(data->dc->audioFormat),
|
||||||
|
&(data->cb->audioFormat));
|
||||||
break;
|
break;
|
||||||
case FLAC__METADATA_TYPE_VORBIS_COMMENT:
|
case FLAC__METADATA_TYPE_VORBIS_COMMENT:
|
||||||
flacParseReplayGain(block,data);
|
flacParseReplayGain(block,data);
|
||||||
@@ -370,7 +373,7 @@ void flacMetadata(const FLAC__SeekableStreamDecoder *dec,
|
|||||||
}
|
}
|
||||||
|
|
||||||
int flacSendChunk(FlacData * data) {
|
int flacSendChunk(FlacData * data) {
|
||||||
doReplayGain(data->chunk,data->chunk_length,data->af,
|
doReplayGain(data->chunk,data->chunk_length,&(data->dc->audioFormat),
|
||||||
data->replayGainScale);
|
data->replayGainScale);
|
||||||
|
|
||||||
switch(sendDataToOutputBuffer(data->cb,data->dc,data->chunk,
|
switch(sendDataToOutputBuffer(data->cb,data->dc,data->chunk,
|
||||||
@@ -413,7 +416,7 @@ FLAC__StreamDecoderWriteStatus flacWrite(const FLAC__SeekableStreamDecoder *dec,
|
|||||||
c_chan++, d_samp++) {
|
c_chan++, d_samp++) {
|
||||||
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->af->bits/8);i++) {
|
for(i=0;i<(data->dc->audioFormat.bits/8);i++) {
|
||||||
if(data->chunk_length>=CHUNK_SIZE) {
|
if(data->chunk_length>=CHUNK_SIZE) {
|
||||||
if(flacSendChunk(data)<0) {
|
if(flacSendChunk(data)<0) {
|
||||||
return FLAC__STREAM_DECODER_WRITE_STATUS_ABORT;
|
return FLAC__STREAM_DECODER_WRITE_STATUS_ABORT;
|
||||||
|
@@ -25,7 +25,7 @@
|
|||||||
|
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
|
|
||||||
int flac_decode(OutputBuffer * cb, AudioFormat * af, DecoderControl * dc);
|
int flac_decode(OutputBuffer * cb, DecoderControl * dc);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
/* vim:set shiftwidth=8 tabstop=8 expandtab: */
|
/* vim:set shiftwidth=8 tabstop=8 expandtab: */
|
||||||
|
@@ -523,7 +523,7 @@ void initAudioFormatFromMp3DecodeData(mp3DecodeData * data, AudioFormat * af) {
|
|||||||
af->channels = MAD_NCHANNELS(&(data->frame).header);
|
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;
|
mp3DecodeData data;
|
||||||
|
|
||||||
if(openMp3(dc->file,&data) < 0) {
|
if(openMp3(dc->file,&data) < 0) {
|
||||||
@@ -531,8 +531,10 @@ int mp3_decode(OutputBuffer * cb, AudioFormat * af, DecoderControl * dc) {
|
|||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
initAudioFormatFromMp3DecodeData(&data,af);
|
initAudioFormatFromMp3DecodeData(&data, &(dc->audioFormat));
|
||||||
cb->totalTime = data.totalTime;
|
getOutputAudioFormat(&(dc->audioFormat), &(cb->audioFormat));
|
||||||
|
|
||||||
|
dc->totalTime = data.totalTime;
|
||||||
dc->start = 0;
|
dc->start = 0;
|
||||||
dc->state = DECODE_STATE_DECODE;
|
dc->state = DECODE_STATE_DECODE;
|
||||||
|
|
||||||
|
@@ -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(OutputBuffer * cb, AudioFormat * af, DecoderControl * dc);
|
int mp3_decode(OutputBuffer * cb, DecoderControl * dc);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
@@ -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_t * mp4fh;
|
||||||
mp4ff_callback_t * mp4cb;
|
mp4ff_callback_t * mp4cb;
|
||||||
int32_t track;
|
int32_t track;
|
||||||
@@ -152,7 +152,7 @@ int mp4_decode(OutputBuffer * cb, AudioFormat * af, DecoderControl * dc) {
|
|||||||
#endif
|
#endif
|
||||||
faacDecSetConfiguration(decoder,config);
|
faacDecSetConfiguration(decoder,config);
|
||||||
|
|
||||||
af->bits = 16;
|
dc->audioFormat.bits = 16;
|
||||||
|
|
||||||
mp4Buffer = NULL;
|
mp4Buffer = NULL;
|
||||||
mp4BufferSize = 0;
|
mp4BufferSize = 0;
|
||||||
@@ -169,8 +169,8 @@ int mp4_decode(OutputBuffer * cb, AudioFormat * af, DecoderControl * dc) {
|
|||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
af->sampleRate = sampleRate;
|
dc->audioFormat.sampleRate = sampleRate;
|
||||||
af->channels = channels;
|
dc->audioFormat.channels = channels;
|
||||||
time = mp4ff_get_track_duration_use_offsets(mp4fh,track);
|
time = mp4ff_get_track_duration_use_offsets(mp4fh,track);
|
||||||
scale = mp4ff_time_scale(mp4fh,track);
|
scale = mp4ff_time_scale(mp4fh,track);
|
||||||
|
|
||||||
@@ -184,7 +184,7 @@ int mp4_decode(OutputBuffer * cb, AudioFormat * af, DecoderControl * dc) {
|
|||||||
free(mp4cb);
|
free(mp4cb);
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
cb->totalTime = ((float)time)/scale;
|
dc->totalTime = ((float)time)/scale;
|
||||||
|
|
||||||
numSamples = mp4ff_num_samples(mp4fh,track);
|
numSamples = mp4ff_num_samples(mp4fh,track);
|
||||||
|
|
||||||
@@ -255,8 +255,10 @@ int mp4_decode(OutputBuffer * cb, AudioFormat * af, DecoderControl * dc) {
|
|||||||
#ifdef HAVE_FAACDECFRAMEINFO_SAMPLERATE
|
#ifdef HAVE_FAACDECFRAMEINFO_SAMPLERATE
|
||||||
scale = frameInfo.samplerate;
|
scale = frameInfo.samplerate;
|
||||||
#endif
|
#endif
|
||||||
af->sampleRate = scale;
|
dc->audioFormat.sampleRate = scale;
|
||||||
af->channels = frameInfo.channels;
|
dc->audioFormat.channels = frameInfo.channels;
|
||||||
|
getOutputAudioFormat(&(dc->audioFormat),
|
||||||
|
&(cb->audioFormat));
|
||||||
dc->state = DECODE_STATE_DECODE;
|
dc->state = DECODE_STATE_DECODE;
|
||||||
dc->start = 0;
|
dc->start = 0;
|
||||||
}
|
}
|
||||||
|
@@ -29,7 +29,7 @@
|
|||||||
|
|
||||||
int mp4_getAACTrack(mp4ff_t *infile);
|
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 mp4_inputStreamReadCallback(void *inStream, void *buffer,
|
||||||
uint32_t length);
|
uint32_t length);
|
||||||
|
@@ -142,7 +142,7 @@ float ogg_getReplayGainScale(char ** comments) {
|
|||||||
return 1.0;
|
return 1.0;
|
||||||
}
|
}
|
||||||
|
|
||||||
int ogg_decode(OutputBuffer * cb, AudioFormat * af, DecoderControl * dc)
|
int ogg_decode(OutputBuffer * cb, DecoderControl * dc)
|
||||||
{
|
{
|
||||||
OggVorbis_File vf;
|
OggVorbis_File vf;
|
||||||
ov_callbacks callbacks;
|
ov_callbacks callbacks;
|
||||||
@@ -167,12 +167,13 @@ int ogg_decode(OutputBuffer * cb, AudioFormat * af, DecoderControl * dc)
|
|||||||
|
|
||||||
{
|
{
|
||||||
vorbis_info *vi=ov_info(&vf,-1);
|
vorbis_info *vi=ov_info(&vf,-1);
|
||||||
af->bits = 16;
|
dc->audioFormat.bits = 16;
|
||||||
af->channels = vi->channels;
|
dc->audioFormat.channels = vi->channels;
|
||||||
af->sampleRate = vi->rate;
|
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->state = DECODE_STATE_DECODE;
|
||||||
dc->start = 0;
|
dc->start = 0;
|
||||||
|
|
||||||
@@ -203,7 +204,8 @@ int ogg_decode(OutputBuffer * cb, AudioFormat * af, DecoderControl * dc)
|
|||||||
if((test = ov_bitrate_instant(&vf))>0) {
|
if((test = ov_bitrate_instant(&vf))>0) {
|
||||||
bitRate = test/1000;
|
bitRate = test/1000;
|
||||||
}
|
}
|
||||||
doReplayGain(chunk,ret,af,replayGainScale);
|
doReplayGain(chunk,ret,&(dc->audioFormat),
|
||||||
|
replayGainScale);
|
||||||
sendDataToOutputBuffer(cb,dc,chunk,ret,
|
sendDataToOutputBuffer(cb,dc,chunk,ret,
|
||||||
ov_time_tell(&vf),bitRate);
|
ov_time_tell(&vf),bitRate);
|
||||||
if(dc->stop) break;
|
if(dc->stop) break;
|
||||||
|
@@ -25,7 +25,7 @@
|
|||||||
|
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
|
|
||||||
int ogg_decode(OutputBuffer * cb, AudioFormat * af, DecoderControl * dc);
|
int ogg_decode(OutputBuffer * cb, DecoderControl * dc);
|
||||||
|
|
||||||
int getOggTotalTime(char * file);
|
int getOggTotalTime(char * file);
|
||||||
|
|
||||||
|
@@ -21,6 +21,7 @@
|
|||||||
|
|
||||||
#include "mpd_types.h"
|
#include "mpd_types.h"
|
||||||
#include "decode.h"
|
#include "decode.h"
|
||||||
|
#include "audio.h"
|
||||||
|
|
||||||
#define OUTPUT_BUFFER_DC_STOP -1
|
#define OUTPUT_BUFFER_DC_STOP -1
|
||||||
#define OUTPUT_BUFFER_DC_SEEK -2
|
#define OUTPUT_BUFFER_DC_SEEK -2
|
||||||
@@ -34,7 +35,7 @@ typedef struct _OutputBuffer {
|
|||||||
mpd_sint16 volatile end;
|
mpd_sint16 volatile end;
|
||||||
mpd_sint16 volatile next;
|
mpd_sint16 volatile next;
|
||||||
mpd_sint8 volatile wrap;
|
mpd_sint8 volatile wrap;
|
||||||
float totalTime;
|
AudioFormat audioFormat;
|
||||||
} OutputBuffer;
|
} OutputBuffer;
|
||||||
|
|
||||||
void flushOutputBuffer(OutputBuffer * cb);
|
void flushOutputBuffer(OutputBuffer * cb);
|
||||||
|
@@ -33,5 +33,8 @@ void pcm_volumeChange(char * buffer, int bufferSize, AudioFormat * format,
|
|||||||
void pcm_mix(char * buffer1, char * buffer2, size_t bufferSize1,
|
void pcm_mix(char * buffer1, char * buffer2, size_t bufferSize1,
|
||||||
size_t bufferSize2, AudioFormat * format, float portion1);
|
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
|
#endif
|
||||||
/* vim:set shiftwidth=4 tabstop=8 expandtab: */
|
/* vim:set shiftwidth=4 tabstop=8 expandtab: */
|
||||||
|
@@ -35,7 +35,6 @@ extern int buffered_chunks;
|
|||||||
|
|
||||||
typedef struct _PlayerData {
|
typedef struct _PlayerData {
|
||||||
OutputBuffer buffer;
|
OutputBuffer buffer;
|
||||||
AudioFormat audioFormat;
|
|
||||||
PlayerControl playerControl;
|
PlayerControl playerControl;
|
||||||
DecoderControl decoderControl;
|
DecoderControl decoderControl;
|
||||||
} PlayerData;
|
} PlayerData;
|
||||||
|
Reference in New Issue
Block a user