aboutsummaryrefslogtreecommitdiffstats
path: root/src/aac_decode.c
diff options
context:
space:
mode:
authorWarren Dukes <warren.dukes@gmail.com>2004-05-31 02:56:14 +0000
committerWarren Dukes <warren.dukes@gmail.com>2004-05-31 02:56:14 +0000
commit9f0cbe9e496d950e796e3b07bca8db8841bb2798 (patch)
tree488d281135b4c9c404aa9d2e6ff7f9915b924fb3 /src/aac_decode.c
parent3aba9b2a668170babcafe4a4ee9b6ca684ed51e4 (diff)
downloadmpd-9f0cbe9e496d950e796e3b07bca8db8841bb2798.tar.gz
mpd-9f0cbe9e496d950e796e3b07bca8db8841bb2798.tar.xz
mpd-9f0cbe9e496d950e796e3b07bca8db8841bb2798.zip
aac_plugin
git-svn-id: https://svn.musicpd.org/mpd/trunk@1250 09075e82-0dd4-0310-85a5-a0d7c8717e4f
Diffstat (limited to 'src/aac_decode.c')
-rw-r--r--src/aac_decode.c400
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: */