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

aac decoding!

need to work on seeking for AAC also, don't reset cb->begin on seek to 0, instead just set cb->end=cb->begin, works much better for disabling seeking (like ADIF AAC's) git-svn-id: https://svn.musicpd.org/mpd/trunk@356 09075e82-0dd4-0310-85a5-a0d7c8717e4f
parent 4c1eb922
...@@ -2,8 +2,6 @@ ...@@ -2,8 +2,6 @@
* (c)2003-2004 by Warren Dukes (shank@mercury.chem.pitt.edu) * (c)2003-2004 by Warren Dukes (shank@mercury.chem.pitt.edu)
* This project's homepage is: http://www.musicpd.org * This project's homepage is: http://www.musicpd.org
* *
* libaudiofile (wave) support added by Eric Wong <normalperson@yhbt.net>
*
* This program is free software; you can redistribute it and/or modify * 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 * it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or * the Free Software Foundation; either version 2 of the License, or
...@@ -196,7 +194,11 @@ int initAacBuffer(char * file, AacBuffer * b, float * length) { ...@@ -196,7 +194,11 @@ int initAacBuffer(char * file, AacBuffer * b, float * length) {
if(*length!=0 && bitRate!=0) *length = *length*8.0/bitRate; if(*length!=0 && bitRate!=0) *length = *length*8.0/bitRate;
} }
if(*length<0) return -1; if(*length<0) {
fclose(b->infile);
if(b->buffer) free(b->buffer);
return -1;
}
return 0; return 0;
} }
...@@ -215,59 +217,29 @@ int getAacTotalTime(char * file) { ...@@ -215,59 +217,29 @@ int getAacTotalTime(char * file) {
int aac_decode(Buffer * cb, AudioFormat * af, DecoderControl * dc) { int aac_decode(Buffer * cb, AudioFormat * af, DecoderControl * dc) {
/*FILE * fh;
mp4ff_t * mp4fh;
mp4ff_callback_t * mp4cb;
int32_t track;
float time; float time;
int32_t scale; float totalTime;
faacDecHandle decoder; faacDecHandle decoder;
faacDecFrameInfo frameInfo; faacDecFrameInfo frameInfo;
faacDecConfigurationPtr config; faacDecConfigurationPtr config;
unsigned char * mp4Buffer; size_t bread;
int mp4BufferSize;
unsigned long sampleRate; unsigned long sampleRate;
unsigned char channels; unsigned char channels;
long sampleId;
long numSamples;
int eof = 0; int eof = 0;
long dur;
unsigned int sampleCount; unsigned int sampleCount;
char * sampleBuffer; char * sampleBuffer;
size_t sampleBufferLen; size_t sampleBufferLen;
unsigned int initial = 1;
int chunkLen = 0; int chunkLen = 0;
float * seekTable; /*float * seekTable;
long seekTableEnd = -1; long seekTableEnd = -1;
int seekPositionFound = 0; int seekPositionFound = 0;*/
long offset;
mpd_uint16 bitRate = 0; mpd_uint16 bitRate = 0;
AacBuffer b;
fh = fopen(dc->file,"r"); printf("aac_decode!\n");
if(!fh) {
ERROR("failed to open %s\n",dc->file);
return -1;
}
mp4cb = malloc(sizeof(mp4ff_callback_t));
mp4cb->read = mp4_readCallback;
mp4cb->seek = mp4_seekCallback;
mp4cb->user_data = fh;
mp4fh = mp4ff_open_read(mp4cb);
if(!mp4fh) {
ERROR("Input does not appear to be a mp4 stream.\n");
free(mp4cb);
fclose(fh);
return -1;
}
track = mp4_getAACTrack(mp4fh); if(initAacBuffer(dc->file,&b,&totalTime) < 0) {
if(track < 0) { ERROR("Not AAC file no ADTS or ADIF headers found.\n");
ERROR("No AAC track found in mp4 stream.\n");
mp4ff_close(mp4fh);
fclose(fh);
free(mp4cb);
return -1; return -1;
} }
...@@ -285,48 +257,33 @@ int aac_decode(Buffer * cb, AudioFormat * af, DecoderControl * dc) { ...@@ -285,48 +257,33 @@ int aac_decode(Buffer * cb, AudioFormat * af, DecoderControl * dc) {
af->bits = 16; af->bits = 16;
mp4Buffer = NULL; fillAacBuffer(&b);
mp4BufferSize = 0; if((bread = faacDecInit(decoder,b.buffer,b.bytesIntoBuffer,
mp4ff_get_decoder_config(mp4fh,track,&mp4Buffer,&mp4BufferSize); &sampleRate,&channels)) < 0)
if(faacDecInit2(decoder,mp4Buffer,mp4BufferSize,&sampleRate,&channels)
< 0)
{ {
ERROR("Error initializing AAC decoder library.\n"); ERROR("Error not a AAC stream.\n");
faacDecClose(decoder); faacDecClose(decoder);
mp4ff_close(mp4fh); fclose(b.infile);
free(mp4cb); if(b.buffer) free(b.buffer);
fclose(fh);
return -1; return -1;
} }
af->sampleRate = sampleRate; af->sampleRate = sampleRate;
af->channels = channels; af->channels = channels;
time = mp4ff_get_track_duration_use_offsets(mp4fh,track);
scale = mp4ff_time_scale(mp4fh,track);
if(mp4Buffer) free(mp4Buffer); cb->totalTime = totalTime+0.5;
if(scale < 0) {
ERROR("Error getting audio format of mp4 AAC track.\n");
faacDecClose(decoder);
mp4ff_close(mp4fh);
fclose(fh);
free(mp4cb);
return -1;
}
cb->totalTime = ((float)time)/scale;
numSamples = mp4ff_num_samples(mp4fh,track);
dc->state = DECODE_STATE_DECODE; dc->state = DECODE_STATE_DECODE;
dc->start = 0; dc->start = 0;
time = 0.0; time = 0.0;
seekTable = malloc(sizeof(float)*numSamples); advanceAacBuffer(&b,bread);
fillAacBuffer(&b);
/*seekTable = malloc(sizeof(float)*numSamples);*/
for(sampleId=0; sampleId<numSamples && !eof; sampleId++) { do {
if(dc->seek && seekTableEnd>1 && /*if(dc->seek && seekTableEnd>1 &&
seekTable[seekTableEnd]>=dc->seekWhere) seekTable[seekTableEnd]>=dc->seekWhere)
{ {
int i = 2; int i = 2;
...@@ -335,9 +292,6 @@ int aac_decode(Buffer * cb, AudioFormat * af, DecoderControl * dc) { ...@@ -335,9 +292,6 @@ int aac_decode(Buffer * cb, AudioFormat * af, DecoderControl * dc) {
time = seekTable[sampleId]; time = seekTable[sampleId];
} }
dur = mp4ff_get_sample_duration(mp4fh,track,sampleId);
offset = mp4ff_get_sample_offset(mp4fh,track,sampleId);
if(sampleId>seekTableEnd) { if(sampleId>seekTableEnd) {
seekTable[sampleId] = time; seekTable[sampleId] = time;
seekTableEnd = sampleId; seekTableEnd = sampleId;
...@@ -358,42 +312,36 @@ int aac_decode(Buffer * cb, AudioFormat * af, DecoderControl * dc) { ...@@ -358,42 +312,36 @@ int aac_decode(Buffer * cb, AudioFormat * af, DecoderControl * dc) {
dc->seek = 0; dc->seek = 0;
} }
if(dc->seek) continue; if(dc->seek) continue;*/
if(mp4ff_read_sample(mp4fh,track,sampleId,&mp4Buffer, if(dc->seek) {
&mp4BufferSize) == 0) /*chunkLen = 0;
{ cb->wrap = 0;
eof = 1; cb->end = 0;*/
continue; dc->seekError = 1;
dc->seek = 0;
} }
sampleBuffer = faacDecDecode(decoder,&frameInfo,b.buffer,
b.bytesIntoBuffer);
advanceAacBuffer(&b,frameInfo.bytesconsumed);
sampleBuffer = faacDecDecode(decoder,&frameInfo,mp4Buffer,
mp4BufferSize);
if(mp4Buffer) free(mp4Buffer);
if(frameInfo.error > 0) { if(frameInfo.error > 0) {
eof = 1; eof = 1;
break; break;
} }
if(channels*(dur+offset) > frameInfo.samples) { sampleCount = (unsigned long)(frameInfo.samples);
dur = frameInfo.samples;
offset = 0;
}
sampleCount = (unsigned long)(dur*channels);
if(sampleCount>0) { if(sampleCount>0) {
initial =0;
bitRate = frameInfo.bytesconsumed*8.0* bitRate = frameInfo.bytesconsumed*8.0*
frameInfo.channels*scale/ frameInfo.channels*sampleRate/
frameInfo.samples/1024+0.5; frameInfo.samples/1024+0.5;
time+= (float)(frameInfo.samples)/channels/sampleRate;
} }
sampleBufferLen = sampleCount*2; sampleBufferLen = sampleCount*2;
sampleBuffer+=offset*channels*2;
while(sampleBufferLen>0 && !dc->seek) { while(sampleBufferLen>0 && !dc->seek) {
size_t size = sampleBufferLen>CHUNK_SIZE-chunkLen ? size_t size = sampleBufferLen>CHUNK_SIZE-chunkLen ?
CHUNK_SIZE-chunkLen: CHUNK_SIZE-chunkLen:
...@@ -427,7 +375,11 @@ int aac_decode(Buffer * cb, AudioFormat * af, DecoderControl * dc) { ...@@ -427,7 +375,11 @@ int aac_decode(Buffer * cb, AudioFormat * af, DecoderControl * dc) {
} }
} }
} }
}
fillAacBuffer(&b);
if(b.bytesIntoBuffer==0) eof = 1;
} while (!eof);
if(!dc->stop && !dc->seek && chunkLen>0) { if(!dc->stop && !dc->seek && chunkLen>0) {
cb->chunkSize[cb->end] = chunkLen; cb->chunkSize[cb->end] = chunkLen;
...@@ -440,11 +392,10 @@ int aac_decode(Buffer * cb, AudioFormat * af, DecoderControl * dc) { ...@@ -440,11 +392,10 @@ int aac_decode(Buffer * cb, AudioFormat * af, DecoderControl * dc) {
chunkLen = 0; chunkLen = 0;
} }
free(seekTable); /*free(seekTable);*/
faacDecClose(decoder); faacDecClose(decoder);
mp4ff_close(mp4fh); fclose(b.infile);
fclose(fh); if(b.buffer) free(b.buffer);
free(mp4cb);
if(dc->seek) dc->seek = 0; if(dc->seek) dc->seek = 0;
...@@ -452,7 +403,7 @@ int aac_decode(Buffer * cb, AudioFormat * af, DecoderControl * dc) { ...@@ -452,7 +403,7 @@ int aac_decode(Buffer * cb, AudioFormat * af, DecoderControl * dc) {
dc->state = DECODE_STATE_STOP; dc->state = DECODE_STATE_STOP;
dc->stop = 0; dc->stop = 0;
} }
else dc->state = DECODE_STATE_STOP;*/ else dc->state = DECODE_STATE_STOP;
return 0; return 0;
} }
......
...@@ -2,8 +2,6 @@ ...@@ -2,8 +2,6 @@
* (c)2003-2004 by Warren Dukes (shank@mercury.chem.pitt.edu) * (c)2003-2004 by Warren Dukes (shank@mercury.chem.pitt.edu)
* This project's homepage is: http://www.musicpd.org * This project's homepage is: http://www.musicpd.org
* *
* libaudiofile (wave) support added by Eric Wong <normalperson@yhbt.net>
*
* This program is free software; you can redistribute it and/or modify * 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 * it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or * the Free Software Foundation; either version 2 of the License, or
......
...@@ -86,7 +86,7 @@ int audiofile_decode(Buffer * cb, AudioFormat * af, DecoderControl * dc) ...@@ -86,7 +86,7 @@ int audiofile_decode(Buffer * cb, AudioFormat * af, DecoderControl * dc)
while(!eof) { while(!eof) {
if(dc->seek) { if(dc->seek) {
cb->end = 0; cb->end = cb->begin;
cb->wrap = 0; cb->wrap = 0;
current = dc->seekWhere * af->sampleRate; current = dc->seekWhere * af->sampleRate;
afSeekFrame(af_fp, AF_DEFAULT_TRACK,current); afSeekFrame(af_fp, AF_DEFAULT_TRACK,current);
......
...@@ -40,6 +40,7 @@ ...@@ -40,6 +40,7 @@
#endif #endif
#ifdef HAVE_FAAD #ifdef HAVE_FAAD
#include "mp4_decode.h" #include "mp4_decode.h"
#include "aac_decode.h"
#endif #endif
#include <signal.h> #include <signal.h>
...@@ -159,11 +160,11 @@ void decodeSeek(PlayerControl * pc, AudioFormat * af, DecoderControl * dc, ...@@ -159,11 +160,11 @@ void decodeSeek(PlayerControl * pc, AudioFormat * af, DecoderControl * dc,
pc->totalTime-0.1 : pc->totalTime-0.1 :
pc->seekWhere; pc->seekWhere;
dc->seekWhere = 0 > dc->seekWhere ? 0 : dc->seekWhere; dc->seekWhere = 0 > dc->seekWhere ? 0 : dc->seekWhere;
cb->begin = 0; dc->seekError = 0;
dc->seek = 1; dc->seek = 1;
pc->elapsedTime = dc->seekWhere;
pc->bitRate = 0; pc->bitRate = 0;
while(*decode_pid>0 && dc->seek) usleep(1000); while(*decode_pid>0 && dc->seek) usleep(1000);
if(dc->seekError) pc->elapsedTime = dc->seekWhere;
} }
} }
pc->seek = 0; pc->seek = 0;
...@@ -229,6 +230,9 @@ int decoderInit(PlayerControl * pc, Buffer * cb, AudioFormat *af, ...@@ -229,6 +230,9 @@ int decoderInit(PlayerControl * pc, Buffer * cb, AudioFormat *af,
break; break;
#endif #endif
#ifdef HAVE_FAAD #ifdef HAVE_FAAD
case DECODE_TYPE_AAC:
dc->error = aac_decode(cb,af,dc);
break;
case DECODE_TYPE_MP4: case DECODE_TYPE_MP4:
dc->error = mp4_decode(cb,af,dc); dc->error = mp4_decode(cb,af,dc);
break; break;
......
...@@ -21,6 +21,8 @@ ...@@ -21,6 +21,8 @@
#include "../config.h" #include "../config.h"
#include "mpd_types.h"
#include <stdio.h> #include <stdio.h>
#include <sys/param.h> #include <sys/param.h>
...@@ -38,11 +40,12 @@ ...@@ -38,11 +40,12 @@
#define DECODE_ERROR_UNKTYPE 1 #define DECODE_ERROR_UNKTYPE 1
typedef struct _DecoderControl { typedef struct _DecoderControl {
int state; mpd_sint8 state;
int stop; mpd_sint8 stop;
int start; mpd_sint8 start;
int error; mpd_uint16 error;
int seek; mpd_sint8 seek;
mpd_sint8 seekError;
double seekWhere; double seekWhere;
char file[MAXPATHLEN+1]; char file[MAXPATHLEN+1];
} DecoderControl; } DecoderControl;
......
...@@ -104,7 +104,7 @@ void flacPlayFile(char *file, Buffer * cb, AudioFormat * af, ...@@ -104,7 +104,7 @@ void flacPlayFile(char *file, Buffer * cb, AudioFormat * af,
if(dc->seek) { if(dc->seek) {
FLAC__uint64 sampleToSeek = dc->seekWhere* FLAC__uint64 sampleToSeek = dc->seekWhere*
af->sampleRate+0.5; af->sampleRate+0.5;
cb->end = 0; cb->end = cb->begin;
cb->wrap = 0; cb->wrap = 0;
if(FLAC__file_decoder_seek_absolute(flacDec, if(FLAC__file_decoder_seek_absolute(flacDec,
sampleToSeek)) sampleToSeek))
......
...@@ -487,7 +487,7 @@ int mp3Read(mp3DecodeData * data, Buffer * cb, DecoderControl * dc) { ...@@ -487,7 +487,7 @@ int mp3Read(mp3DecodeData * data, Buffer * cb, DecoderControl * dc) {
if(dc->seek) { if(dc->seek) {
long i = 0; long i = 0;
cb->wrap = 0; cb->wrap = 0;
cb->end = 0; cb->end = cb->begin;
data->muteFrame = 1; data->muteFrame = 1;
while(i<data->highestFrame && dc->seekWhere > while(i<data->highestFrame && dc->seekWhere >
((float)mad_timer_count(data->times[i], ((float)mad_timer_count(data->times[i],
......
...@@ -2,8 +2,6 @@ ...@@ -2,8 +2,6 @@
* (c)2003-2004 by Warren Dukes (shank@mercury.chem.pitt.edu) * (c)2003-2004 by Warren Dukes (shank@mercury.chem.pitt.edu)
* This project's homepage is: http://www.musicpd.org * This project's homepage is: http://www.musicpd.org
* *
* libaudiofile (wave) support added by Eric Wong <normalperson@yhbt.net>
*
* This program is free software; you can redistribute it and/or modify * 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 * it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or * the Free Software Foundation; either version 2 of the License, or
...@@ -149,7 +147,7 @@ int mp4_decode(Buffer * cb, AudioFormat * af, DecoderControl * dc) { ...@@ -149,7 +147,7 @@ int mp4_decode(Buffer * cb, AudioFormat * af, DecoderControl * dc) {
if(faacDecInit2(decoder,mp4Buffer,mp4BufferSize,&sampleRate,&channels) if(faacDecInit2(decoder,mp4Buffer,mp4BufferSize,&sampleRate,&channels)
< 0) < 0)
{ {
ERROR("Error initializing AAC decoder library.\n"); ERROR("Error not a AAC stream.\n");
faacDecClose(decoder); faacDecClose(decoder);
mp4ff_close(mp4fh); mp4ff_close(mp4fh);
free(mp4cb); free(mp4cb);
...@@ -210,7 +208,7 @@ int mp4_decode(Buffer * cb, AudioFormat * af, DecoderControl * dc) { ...@@ -210,7 +208,7 @@ int mp4_decode(Buffer * cb, AudioFormat * af, DecoderControl * dc) {
if(dc->seek && seekPositionFound) { if(dc->seek && seekPositionFound) {
seekPositionFound = 0; seekPositionFound = 0;
chunkLen = 0; chunkLen = 0;
cb->end = 0; cb->end = cb->begin;
cb->wrap = 0; cb->wrap = 0;
dc->seek = 0; dc->seek = 0;
} }
...@@ -233,7 +231,7 @@ int mp4_decode(Buffer * cb, AudioFormat * af, DecoderControl * dc) { ...@@ -233,7 +231,7 @@ int mp4_decode(Buffer * cb, AudioFormat * af, DecoderControl * dc) {
} }
if(channels*(dur+offset) > frameInfo.samples) { if(channels*(dur+offset) > frameInfo.samples) {
dur = frameInfo.samples; dur = frameInfo.samples/channels;
offset = 0; offset = 0;
} }
......
...@@ -2,8 +2,6 @@ ...@@ -2,8 +2,6 @@
* (c)2003-2004 by Warren Dukes (shank@mercury.chem.pitt.edu) * (c)2003-2004 by Warren Dukes (shank@mercury.chem.pitt.edu)
* This project's homepage is: http://www.musicpd.org * This project's homepage is: http://www.musicpd.org
* *
* libaudiofile (wave) support added by Eric Wong <normalperson@yhbt.net>
*
* This program is free software; you can redistribute it and/or modify * 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 * it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or * the Free Software Foundation; either version 2 of the License, or
......
...@@ -95,7 +95,7 @@ int ogg_decode(Buffer * cb, AudioFormat * af, DecoderControl * dc) ...@@ -95,7 +95,7 @@ int ogg_decode(Buffer * cb, AudioFormat * af, DecoderControl * dc)
while(!eof) { while(!eof) {
if(dc->seek) { if(dc->seek) {
cb->end = 0; cb->end = cb->begin;
cb->wrap = 0; cb->wrap = 0;
chunkpos = 0; chunkpos = 0;
ov_time_seek_page(&vf,dc->seekWhere); ov_time_seek_page(&vf,dc->seekWhere);
......
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