diff --git a/src/decode.h b/src/decode.h index ea52dd858..9f6e2f0e5 100644 --- a/src/decode.h +++ b/src/decode.h @@ -29,6 +29,7 @@ #define DECODE_TYPE_FLAC 2 #define DECODE_TYPE_AUDIOFILE 3 #define DECODE_TYPE_MP4 4 +#define DECODE_TYPE_AAC 5 #define DECODE_STATE_STOP 0 #define DECODE_STATE_DECODE 1 diff --git a/src/player.c b/src/player.c index d6a79b74a..81b78ca39 100644 --- a/src/player.c +++ b/src/player.c @@ -178,6 +178,7 @@ int playerPlay(FILE * fp, char * utf8file) { else if(isWave(utf8file,NULL)) pc->decodeType = DECODE_TYPE_AUDIOFILE; #endif #ifdef HAVE_FAAD + else if(isAac(utf8file,NULL)) pc->decodeType = DECODE_TYPE_AAC; else if(isMp4(utf8file,NULL)) pc->decodeType = DECODE_TYPE_MP4; #endif else { @@ -336,6 +337,9 @@ int queueSong(char * utf8file) { } #endif #ifdef HAVE_AUDIOFILE + else if(isAac(utf8file,NULL)) { + pc->decodeType = DECODE_TYPE_AAC; + } else if(isMp4(utf8file,NULL)) { pc->decodeType = DECODE_TYPE_MP4; } diff --git a/src/song.c b/src/song.c index ac60692ad..377487cbd 100644 --- a/src/song.c +++ b/src/song.c @@ -79,6 +79,9 @@ Song * newSong(char * utf8file) { } #endif #ifdef HAVE_FAAD + else if(isAac(utf8file,&(song->mtime))) { + song->tag = aacTagDup(utf8file); + } else if(isMp4(utf8file,&(song->mtime))) { song->tag = mp4TagDup(utf8file); } @@ -246,6 +249,9 @@ int updateSongInfo(Song * song) { } #endif #ifdef HAVE_FAAD + else if(isAac(utf8file,&(song->mtime))) { + song->tag = aacTagDup(utf8file); + } else if(isMp4(utf8file,&(song->mtime))) { song->tag = mp4TagDup(utf8file); } diff --git a/src/tag.c b/src/tag.c index 73821c74e..d8af2b49f 100644 --- a/src/tag.c +++ b/src/tag.c @@ -267,13 +267,82 @@ int adtsParse(AacBuffer * b, float * length) { } else bytesPerFrame = 0; if(framesPerSec!=0) *length = (float)frames/framesPerSec; - else *length = 1; return 1; } +#define AAC_MAX_CHANNELS 6 + MpdTag * aacTagDup(char * utf8file) { MpdTag * ret = NULL; + AacBuffer b; + size_t fileread; + size_t bread; + size_t tagsize; + float length = -1; + + memset(&b,0,sizeof(AacBuffer)); + + blockSignals(); + + b.infile = fopen(rmp2amp(utf8ToFsCharset(utf8file)),"r"); + if(b.infile == NULL) return NULL; + + fseek(b.infile,0,SEEK_END); + fileread = ftell(b.infile); + fseek(b.infile,0,SEEK_SET); + + b.buffer = malloc(FAAD_MIN_STREAMSIZE*AAC_MAX_CHANNELS); + memset(b.buffer,0,FAAD_MIN_STREAMSIZE*AAC_MAX_CHANNELS); + + bread = fread(b.buffer,1,FAAD_MIN_STREAMSIZE*AAC_MAX_CHANNELS,b.infile); + 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((b.buffer[0] == 0xFF) && ((b.buffer[1] & 0xF6) == 0xF0)) { + adtsParse(&b,&length); + fseek(b.infile,tagsize, SEEK_SET); + + bread = fread(b.buffer,1,FAAD_MIN_STREAMSIZE*AAC_MAX_CHANNELS, + b.infile); + 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) length = length*8.0/bitRate; + } + + if(b.buffer) free(b.buffer); + fclose(b.infile); + + if(length>=0) { + if((ret = id3Dup(utf8file))==NULL) ret = newMpdTag(); + ret->time = length+0.5; + } return ret; } diff --git a/src/tag.h b/src/tag.h index d6ca809df..180e81d33 100644 --- a/src/tag.h +++ b/src/tag.h @@ -40,6 +40,8 @@ MpdTag * mp3TagDup(char * utf8file); #endif #ifdef HAVE_FAAD +MpdTag * aacTagDup(char * utf8file); + MpdTag * mp4TagDup(char * utf8file); #endif