diff options
Diffstat (limited to 'src/aac_decode.c')
-rw-r--r-- | src/aac_decode.c | 400 |
1 files changed, 0 insertions, 400 deletions
diff --git a/src/aac_decode.c b/src/aac_decode.c deleted file mode 100644 index 6dbaea1bc..000000000 --- a/src/aac_decode.c +++ /dev/null @@ -1,400 +0,0 @@ -/* 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 - */ - -#include "aac_decode.h" - -#ifdef HAVE_FAAD - -#define AAC_MAX_CHANNELS 6 - -#include "command.h" -#include "utils.h" -#include "audio.h" -#include "log.h" -#include "inputStream.h" -#include "outputBuffer.h" - -#include <stdio.h> -#include <unistd.h> -#include <stdlib.h> -#include <string.h> -#include <faad.h> - -/* all code here is either based on or copied from FAAD2's frontend code */ -typedef struct { - InputStream * inStream; - long bytesIntoBuffer; - long bytesConsumed; - long fileOffset; - unsigned char *buffer; - int atEof; -} AacBuffer; - -void fillAacBuffer(AacBuffer *b) { - if(b->bytesConsumed > 0) { - int bread; - - if(b->bytesIntoBuffer) { - memmove((void *)b->buffer,(void*)(b->buffer+ - b->bytesConsumed),b->bytesIntoBuffer); - } - - if(!b->atEof) { - bread = readFromInputStream(b->inStream, - (void *)(b->buffer+b->bytesIntoBuffer), - 1,b->bytesConsumed); - if(bread!=b->bytesConsumed) b->atEof = 1; - b->bytesIntoBuffer+=bread; - } - - b->bytesConsumed = 0; - - if(b->bytesIntoBuffer > 3) { - if(memcmp(b->buffer,"TAG",3)==0) b->bytesIntoBuffer = 0; - } - if(b->bytesIntoBuffer > 11) { - if(memcmp(b->buffer,"LYRICSBEGIN",11)==0) { - b->bytesIntoBuffer = 0; - } - } - if(b->bytesIntoBuffer > 8) { - if(memcmp(b->buffer,"APETAGEX",8)==0) { - b->bytesIntoBuffer = 0; - } - } - } -} - -void advanceAacBuffer(AacBuffer * b, int bytes) { - b->fileOffset+=bytes; - b->bytesConsumed = bytes; - b->bytesIntoBuffer-=bytes; -} - -static int adtsSampleRates[] = {96000,88200,64000,48000,44100,32000,24000,22050, - 16000,12000,11025,8000,7350,0,0,0}; - -int adtsParse(AacBuffer * b, float * length) { - int frames, frameLength; - int tFrameLength = 0; - int sampleRate = 0; - float framesPerSec, bytesPerFrame; - - /* Read all frames to ensure correct time and bitrate */ - for(frames = 0; ;frames++) { - fillAacBuffer(b); - - if(b->bytesIntoBuffer > 7) { - /* check syncword */ - if (!((b->buffer[0] == 0xFF) && - ((b->buffer[1] & 0xF6) == 0xF0))) - { - break; - } - - if(frames==0) { - sampleRate = adtsSampleRates[ - (b->buffer[2]&0x3c)>>2]; - } - - frameLength = ((((unsigned int)b->buffer[3] & 0x3)) - << 11) | (((unsigned int)b->buffer[4]) - << 3) | (b->buffer[5] >> 5); - - tFrameLength+=frameLength; - - if(frameLength > b->bytesIntoBuffer) break; - - advanceAacBuffer(b,frameLength); - } - else break; - } - - framesPerSec = (float)sampleRate/1024.0; - if(frames!=0) { - bytesPerFrame = (float)tFrameLength/(float)(frames*1000); - } - else bytesPerFrame = 0; - if(framesPerSec!=0) *length = (float)frames/framesPerSec; - - return 1; -} - -void initAacBuffer(InputStream * inStream, AacBuffer * b, float * length, - size_t * retFileread, size_t * retTagsize) -{ - size_t fileread; - size_t bread; - size_t tagsize; - - if(length) *length = -1; - - memset(b,0,sizeof(AacBuffer)); - - b->inStream = inStream; - - fileread = inStream->size; - - b->buffer = malloc(FAAD_MIN_STREAMSIZE*AAC_MAX_CHANNELS); - memset(b->buffer,0,FAAD_MIN_STREAMSIZE*AAC_MAX_CHANNELS); - - bread = readFromInputStream(inStream,b->buffer,1, - FAAD_MIN_STREAMSIZE*AAC_MAX_CHANNELS); - b->bytesIntoBuffer = bread; - b->bytesConsumed = 0; - b->fileOffset = 0; - - if(bread!=FAAD_MIN_STREAMSIZE*AAC_MAX_CHANNELS) b->atEof = 1; - - tagsize = 0; - if(!memcmp(b->buffer,"ID3",3)) { - tagsize = (b->buffer[6] << 21) | (b->buffer[7] << 14) | - (b->buffer[8] << 7) | (b->buffer[9] << 0); - - tagsize+=10; - advanceAacBuffer(b,tagsize); - fillAacBuffer(b); - } - - if(retFileread) *retFileread = fileread; - if(retTagsize) *retTagsize = tagsize; - - if(length==NULL) return; - - if((b->buffer[0] == 0xFF) && ((b->buffer[1] & 0xF6) == 0xF0)) { - adtsParse(b, length); - seekInputStream(b->inStream, tagsize, SEEK_SET); - - bread = readFromInputStream(b->inStream, b->buffer, 1, - FAAD_MIN_STREAMSIZE*AAC_MAX_CHANNELS); - if(bread != FAAD_MIN_STREAMSIZE*AAC_MAX_CHANNELS) b->atEof = 1; - else b->atEof = 0; - b->bytesIntoBuffer = bread; - b->bytesConsumed = 0; - b->fileOffset = tagsize; - } - else if(memcmp(b->buffer,"ADIF",4) == 0) { - int bitRate; - int skipSize = (b->buffer[4] & 0x80) ? 9 : 0; - bitRate = ((unsigned int)(b->buffer[4 + skipSize] & 0x0F)<<19) | - ((unsigned int)b->buffer[5 + skipSize]<<11) | - ((unsigned int)b->buffer[6 + skipSize]<<3) | - ((unsigned int)b->buffer[7 + skipSize] & 0xE0); - - *length = fileread; - if(*length!=0 && bitRate!=0) *length = *length*8.0/bitRate; - } -} - -float getAacFloatTotalTime(char * file) { - AacBuffer b; - float length; - size_t fileread, tagsize; - faacDecHandle decoder; - faacDecConfigurationPtr config; - unsigned long sampleRate; - unsigned char channels; - InputStream inStream; - size_t bread; - - if(openInputStream(&inStream,file) < 0) return -1; - - initAacBuffer(&inStream,&b,&length,&fileread,&tagsize); - - if(length < 0) { - decoder = faacDecOpen(); - - config = faacDecGetCurrentConfiguration(decoder); - config->outputFormat = FAAD_FMT_16BIT; - faacDecSetConfiguration(decoder,config); - - fillAacBuffer(&b); -#ifdef HAVE_FAAD_BUFLEN_FUNCS - bread = faacDecInit(decoder,b.buffer,b.bytesIntoBuffer, - &sampleRate,&channels); -#else - bread = faacDecInit(decoder,b.buffer,&sampleRate,&channels); -#endif - if(bread >= 0 && sampleRate > 0 && channels > 0) length = 0; - - faacDecClose(decoder); - } - - if(b.buffer) free(b.buffer); - closeInputStream(&inStream); - - return length; -} - -int getAacTotalTime(char * file) { - int time = -1; - float length; - - if((length = getAacFloatTotalTime(file))>=0) time = length+0.5; - - return time; -} - - -int aac_decode(OutputBuffer * cb, DecoderControl * dc) { - float time; - float totalTime; - faacDecHandle decoder; - faacDecFrameInfo frameInfo; - faacDecConfigurationPtr config; - size_t bread; - unsigned long sampleRate; - unsigned char channels; - int eof = 0; - unsigned int sampleCount; - char * sampleBuffer; - size_t sampleBufferLen; - /*float * seekTable; - long seekTableEnd = -1; - int seekPositionFound = 0;*/ - mpd_uint16 bitRate = 0; - AacBuffer b; - InputStream inStream; - - if((totalTime = getAacFloatTotalTime(dc->file)) < 0) return -1; - - if(openInputStream(&inStream,dc->file) < 0) return -1; - - initAacBuffer(&inStream,&b,NULL,NULL,NULL); - - decoder = faacDecOpen(); - - config = faacDecGetCurrentConfiguration(decoder); - config->outputFormat = FAAD_FMT_16BIT; -#ifdef HAVE_FAACDECCONFIGURATION_DOWNMATRIX - config->downMatrix = 1; -#endif -#ifdef HAVE_FAACDECCONFIGURATION_DONTUPSAMPLEIMPLICITSBR - config->dontUpSampleImplicitSBR = 0; -#endif - faacDecSetConfiguration(decoder,config); - - fillAacBuffer(&b); - -#ifdef HAVE_FAAD_BUFLEN_FUNCS - bread = faacDecInit(decoder,b.buffer,b.bytesIntoBuffer, - &sampleRate,&channels); -#else - bread = faacDecInit(decoder,b.buffer,&sampleRate,&channels); -#endif - if(bread < 0) { - ERROR("Error not a AAC stream.\n"); - faacDecClose(decoder); - closeInputStream(b.inStream); - if(b.buffer) free(b.buffer); - return -1; - } - - dc->audioFormat.bits = 16; - - dc->totalTime = totalTime; - - time = 0.0; - - advanceAacBuffer(&b,bread); - - while(!eof) { - fillAacBuffer(&b); - - if(b.bytesIntoBuffer==0) { - eof = 1; - break; - } - -#ifdef HAVE_FAAD_BUFLEN_FUNCS - sampleBuffer = faacDecDecode(decoder,&frameInfo,b.buffer, - b.bytesIntoBuffer); -#else - sampleBuffer = faacDecDecode(decoder,&frameInfo,b.buffer); -#endif - - if(frameInfo.error > 0) { - ERROR("error decoding AAC file: %s\n",dc->file); - ERROR("faad2 error: %s\n", - faacDecGetErrorMessage(frameInfo.error)); - eof = 1; - break; - } - -#ifdef HAVE_FAACDECFRAMEINFO_SAMPLERATE - sampleRate = frameInfo.samplerate; -#endif - - if(dc->state != DECODE_STATE_DECODE) { - dc->audioFormat.channels = frameInfo.channels; - dc->audioFormat.sampleRate = sampleRate; - getOutputAudioFormat(&(dc->audioFormat), - &(cb->audioFormat)); - dc->state = DECODE_STATE_DECODE; - } - - advanceAacBuffer(&b,frameInfo.bytesconsumed); - - sampleCount = (unsigned long)(frameInfo.samples); - - if(sampleCount>0) { - bitRate = frameInfo.bytesconsumed*8.0* - frameInfo.channels*sampleRate/ - frameInfo.samples/1000+0.5; - time+= (float)(frameInfo.samples)/frameInfo.channels/ - sampleRate; - } - - sampleBufferLen = sampleCount*2; - - sendDataToOutputBuffer(cb, NULL, dc, 0, sampleBuffer, - sampleBufferLen, time, bitRate); - if(dc->seek) { - dc->seekError = 1; - dc->seek = 0; - } - else if(dc->stop) { - eof = 1; - break; - } - } while (!eof); - - flushOutputBuffer(cb); - - faacDecClose(decoder); - closeInputStream(b.inStream); - if(b.buffer) free(b.buffer); - - if(dc->state != DECODE_STATE_DECODE) return -1; - - if(dc->seek) { - dc->seekError = 1; - dc->seek = 0; - } - - if(dc->stop) { - dc->state = DECODE_STATE_STOP; - dc->stop = 0; - } - else dc->state = DECODE_STATE_STOP; - - return 0; -} - -#endif /* HAVE_FAAD */ -/* vim:set shiftwidth=4 tabstop=8 expandtab: */ |