From b72f591641e9d311e813fb8e2ece643cc6562e56 Mon Sep 17 00:00:00 2001
From: Warren Dukes <warren.dukes@gmail.com>
Date: Sun, 21 Mar 2004 18:12:37 +0000
Subject: parse length from Aac files and ID3 tags

git-svn-id: https://svn.musicpd.org/mpd/trunk@346 09075e82-0dd4-0310-85a5-a0d7c8717e4f
---
 src/decode.h |  1 +
 src/player.c |  4 ++++
 src/song.c   |  6 +++++
 src/tag.c    | 71 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++-
 src/tag.h    |  2 ++
 5 files changed, 83 insertions(+), 1 deletion(-)

(limited to 'src')

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
 
-- 
cgit v1.2.3