1 /*
2  * @(#)AudioFormatAAC.java - parse Audioheaders,
3  *
4  * Copyright (c) 2007-2008 by dvb.matt, All Rights Reserved.
5  *
6  * This file is part of ProjectX, a free Java based demux utility.
7  * By the authors, ProjectX is intended for educational purposes only,
8  * as a non-commercial test project.
9  *
10  * The part of audio parsing was derived from the MPEG/Audio
11  * Software Simulation Group's audio codec and ATSC A/52 in a special modified manner.
12  *
13  *
14  * This program is free software; you can redistribute it and/or modify
15  * it under the terms of the GNU General Public License as published by
16  * the Free Software Foundation; either version 2 of the License, or
17  * (at your option) any later version.
18  *
19  * This program is distributed in the hope that it will be useful,
20  * but WITHOUT ANY WARRANTY; without even the implied warranty of
21  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
22  * GNU General Public License for more details.
23  *
24  * You should have received a copy of the GNU General Public License
25  * along with this program; if not, write to the Free Software
26  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
27  *
28  */
29 
30 package net.sourceforge.dvb.projectx.audio;
31 
32 import net.sourceforge.dvb.projectx.audio.AudioFormat;
33 import net.sourceforge.dvb.projectx.common.Common;
34 
35 public class AudioFormatAAC extends AudioFormat {
36 
37 //unused !!
38 
AudioFormatAAC()39 	public AudioFormatAAC()
40 	{
41 		super();
42 	}
43 
44 	/**
45 	 *
46 	 */
47 	private int[] frequency_index = {
48 		96000, 88200, 64000, 48000, 44100, 32000,
49 		24000, 22050, 16000, 12000, 11025, 8000, 0, 0, 0, 0
50 	};
51 
52 
53 	/**
54 	 *
55 	 */
56 	private int[] bitrate_index = {
57 		32000, 56000, 64000, 96000, 112000, 128000,
58 		192000, 224000, 256000, 320000, 384000,
59 		448000, 512000, 576000, 640000, 768000,
60 	};
61 
62 	/**
63 	 *
64 	 */
65 	private String[] acmod = {
66 		"1", "DM", "2/0", "2/0"
67 	};
68 
69 	/**
70 	 *
71 	 */
72 	private int[] channels = {
73 		1,2,2,2, 2,3,3,4, 4,5,6,6, 7,8,0,0,
74 	};
75 
76 	/**
77 	 * parse aac Header
78 	 */
parseHeader(byte[] frame, int pos)79 	public int parseHeader(byte[] frame, int pos)
80 	{
81 		boolean latm = false;
82 		int aac_length = 0;
83 
84 		// 0x2B7 LATM
85 		latm = frame[pos] == 0x56 && (0xE0 & frame[pos + 1]) == 0xE0;
86 
87 		if (latm)
88 		{
89 			aac_length = 3 + ((0x1F & frame[pos + 1])<<8 | (0xFF & frame[pos + 2]));
90 			pos += 3;
91 		}
92 
93 		if (frame.length == 4) //pushmpa = 4!
94 			return (latm && (0xFF & frame[pos]) == 0xFF ? aac_length : -1);
95 
96 		//syncword ADTS
97 		if ((0xFF & frame[pos]) != 0xFF && (0xE0 & frame[pos + 1]) != 0xE0)
98 			return -1;
99 
100 		//ADTS fixed
101 		setID(1 & frame[pos + 1]>>>3);
102 		setLayer(3 & frame[pos + 1]>>>1);
103 		setProtectionBit(1 ^ (1 & frame[pos + 1]));
104 		setMode(3 & frame[pos + 2]>>>6); //profile
105 		setSamplingFrequency(frequency_index[0xF & frame[pos + 2]>>>2]);
106 		setPrivateBit(1 & frame[pos + 2]>>>1);
107 		setChannel(7 & frame[pos + 2]<<2 | 3 & frame[pos + 3]>>>6); //see specif.
108 		setCopyright(1 & frame[pos + 3]>>>5);
109 		setOriginal(1 & frame[pos + 3]>>>4); //home
110 		setEmphasis(3 & frame[pos + 3]>>>2);
111 	//	setFrameTimeLength(169344000.0 / getSamplingFrequency());
112 		setFrameTimeLength(3840);
113 		setBitrate(1000);
114 
115 		//ADTS variabel
116 		//copyright_identification_bit 1 bslbf    pos+3
117 		//copyright_identification_start 1 bslbf  pos+3
118 		setSizeBase((0xFF & frame[pos + 4])<<5 | (0x1F & frame[pos + 5]>>3)); //frame_length 13 bslbf
119 		setSize(getSizeBase());
120 		//adts_buffer_fullness 11 bslbf
121 		//number_of_raw_data_blocks_in_frame 2 uimsfb
122 
123 		return getLayer();
124 	}
125 
126 	/**
127 	 * parse next aac Header
128 	 */
parseNextHeader(byte[] frame, int pos)129 	public int parseNextHeader(byte[] frame, int pos)
130 	{
131 		boolean latm = false;
132 		int aac_length = 0;
133 
134 		latm = frame[pos] == 0x56 && (0xE0 & frame[pos + 1]) == 0xE0;
135 
136 		if (latm)
137 		{
138 			aac_length = 3 + ((0x1F & frame[pos + 1])<<8 | (0xFF & frame[pos + 2]));
139 			pos += 3;
140 		}
141 
142 		if ((0xFF & frame[pos]) != 0xFF && (0xE0 & frame[pos + 1]) != 0xE0)
143 			return -1;
144 
145 		setNextID(1 & frame[pos + 1]>>>3);
146 		setNextLayer(3 & frame[pos + 1]>>>1);
147 		setNextProtectionBit(1 ^ (1 & frame[pos + 1]));
148 		setNextMode(3 & frame[pos + 2]>>>6); //profile
149 		setNextSamplingFrequency(frequency_index[0xF & frame[pos + 2]>>>2]);
150 		setNextPrivateBit(1 & frame[pos + 2]>>>1);
151 		setNextChannel(7 & frame[pos + 2]<<2 | 3 & frame[pos + 3]>>>6); //see specif.
152 		setNextCopyright(1 & frame[pos + 3]>>>5);
153 		setNextOriginal(1 & frame[pos + 3]>>>4); //home
154 		setNextEmphasis(3 & frame[pos + 3]>>>2);
155 	//	setNextFrameTimeLength(169344000.0 / getNextSamplingFrequency());
156 		setNextFrameTimeLength(3840);
157 		setNextBitrate(1000);
158 
159 		//ADTS variabel
160 		//copyright_identification_bit 1 bslbf    pos+3
161 		//copyright_identification_start 1 bslbf  pos+3
162 		setNextSizeBase((0xFF & frame[pos + 4])<<5 | (0x1F & frame[pos + 5]>>3)); //frame_length 13 bslbf
163 		setNextSize(getNextSizeBase());
164 		//adts_buffer_fullness 11 bslbf
165 		//number_of_raw_data_blocks_in_frame 2 uimsfb
166 
167 		return getNextLayer();
168 	}
169 
170 	/**
171 	 * verify current & last header
172 	 */
compareHeader()173 	public int compareHeader()
174 	{
175 		if (getLastID() != getID())
176 			return 0x1;
177 
178 		else if (getLastLayer() != getLayer())
179 			return 0x2;
180 
181 		else if (getLastSamplingFrequency() != getSamplingFrequency())
182 			return 0x4;
183 
184 		else if (getLastBitrate() != getBitrate())
185 			return 0x8;
186 
187 		else if (getLastMode() != getMode())
188 			return 0x10;
189 
190 		else if (getLastModeExtension() != getModeExtension())
191 			return 0x20;
192 
193 		else if (getLastSize() != getSize())
194 			return 0x40;
195 
196 		else
197 			return 0;
198 	}
199 
200 	/**
201 	 * display last aac header
202 	 */
displayHeader()203 	public String displayHeader()
204 	{
205 		return ("AAC, " + acmod[getLastMode()] + "(" + channels[getLastChannel()] + "), " + getLastSamplingFrequency() + "Hz, " + (getLastBitrate() / 1000.0) + "kbps, " + getLastSize() + "BpF");
206 	}
207 
208 }