2
** FAAD2 - Freeware Advanced Audio (AAC) Decoder including SBR decoding
3
** Copyright (C) 2003 M. Bakker, Ahead Software AG, http://www.nero.com
5
** This program is free software; you can redistribute it and/or modify
6
** it under the terms of the GNU General Public License as published by
7
** the Free Software Foundation; either version 2 of the License, or
8
** (at your option) any later version.
10
** This program is distributed in the hope that it will be useful,
11
** but WITHOUT ANY WARRANTY; without even the implied warranty of
12
** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13
** GNU General Public License for more details.
15
** You should have received a copy of the GNU General Public License
16
** along with this program; if not, write to the Free Software
17
** Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
19
** Any non-GPL usage of this software or parts of this software is strictly
22
** Commercial non-GPL licensing of this software is possible.
23
** For more info contact Ahead Software through Mpeg4AAClicense@nero.com.
25
** $Id: aacinfo.c,v 1.4 2003/07/29 08:20:11 menno Exp $
29
#define WIN32_LEAN_AND_MEAN
33
#include "filestream.h"
36
#define ADIF_MAX_SIZE 30 /* Should be enough */
37
#define ADTS_MAX_SIZE 10 /* Should be enough */
39
static int sample_rates[] = {96000,88200,64000,48000,44100,32000,24000,22050,16000,12000,11025,8000};
41
static int read_ADIF_header(FILE_STREAM *file, faadAACInfo *info)
44
unsigned char buffer[ADIF_MAX_SIZE];
48
/* Get ADIF header data */
51
if(read_buffer_filestream(file, buffer, ADIF_MAX_SIZE) < 0)
54
/* copyright string */
56
skip_size += 9; /* skip 9 bytes */
58
bitstream = buffer[0 + skip_size] & 0x10;
59
info->bitrate = ((unsigned int)(buffer[0 + skip_size] & 0x0F)<<19)|
60
((unsigned int)buffer[1 + skip_size]<<11)|
61
((unsigned int)buffer[2 + skip_size]<<3)|
62
((unsigned int)buffer[3 + skip_size] & 0xE0);
66
info->object_type = ((buffer[6 + skip_size]&0x01)<<1)|((buffer[7 + skip_size]&0x80)>>7);
67
sf_idx = (buffer[7 + skip_size]&0x78)>>3;
69
info->object_type = (buffer[4 + skip_size] & 0x18)>>3;
70
sf_idx = ((buffer[4 + skip_size] & 0x07)<<1)|((buffer[5 + skip_size] & 0x80)>>7);
72
info->sampling_rate = sample_rates[sf_idx];
77
static int read_ADTS_header(FILE_STREAM *file, faadAACInfo *info,
78
unsigned long **seek_table, int *seek_table_len,
79
int tagsize, int no_seek_table)
81
/* Get ADTS header data */
82
unsigned char buffer[ADTS_MAX_SIZE];
83
int frames, framesinsec=0, t_framelength = 0, frame_length, sr_idx, ID;
86
float frames_per_sec = 0;
88
unsigned long *tmp_seek_table = NULL;
92
/* Read all frames to ensure correct time and bitrate */
93
for(frames=0; /* */; frames++, framesinsec++)
95
/* If streaming, only go until we hit 5 seconds worth */
104
pos = tell_filestream(file);
106
/* 12 bit SYNCWORD */
107
bytes = read_buffer_filestream(file, buffer, ADTS_MAX_SIZE);
109
if(bytes != ADTS_MAX_SIZE)
111
/* Bail out if no syncword found */
116
if (!((buffer[0] == 0xFF)&&((buffer[1] & 0xF6) == 0xF0)))
121
/* fixed ADTS header is the same for every frame, so we read it only once */
122
/* Syncword found, proceed to read in the fixed ADTS header */
123
ID = buffer[1] & 0x08;
124
info->object_type = (buffer[2]&0xC0)>>6;
125
sr_idx = (buffer[2]&0x3C)>>2;
126
info->channels = ((buffer[2]&0x01)<<2)|((buffer[3]&0xC0)>>6);
128
frames_per_sec = sample_rates[sr_idx] / 1024.f;
131
/* ...and the variable ADTS header */
134
} else { /* MPEG-2 */
137
frame_length = ((((unsigned int)buffer[3] & 0x3)) << 11)
138
| (((unsigned int)buffer[4]) << 3) | (buffer[5] >> 5);
140
t_framelength += frame_length;
144
if(framesinsec == 43)
147
if(framesinsec == 0 && seek_table_len)
149
tmp_seek_table = (unsigned long *) realloc(tmp_seek_table, (second + 1) * sizeof(unsigned long));
150
tmp_seek_table[second] = pos;
156
/* NOTE: While simply skipping ahead by reading may seem to be more work than seeking,
157
it is actually much faster, and keeps compatibility with streaming */
158
for(i=0; i < frame_length - ADTS_MAX_SIZE; i++)
160
if(read_byte_filestream(file) < 0)
167
*seek_table_len = second;
168
*seek_table = tmp_seek_table;
171
info->sampling_rate = sample_rates[sr_idx];
172
info->bitrate = (int)(((t_framelength / frames) * (info->sampling_rate/1024.0)) +0.5)*8;
176
/* Since we only use 5 seconds of aac data to get a rough bitrate, we must use a different
177
method of calculating the overall length */
178
if(filelength_filestream(file))
180
info->length = (int)((filelength_filestream(file)/(((info->bitrate*8)/1024)*16))*1000);
184
/* Since the server didnt tell us how long the file is,
185
we have no way of determining length */
191
info->length = (int)((float)(frames/frames_per_sec))*1000;
197
int get_AAC_format(char *filename, faadAACInfo *info,
198
unsigned long **seek_table, int *seek_table_len,
201
unsigned long tagsize;
204
unsigned long file_len;
205
unsigned char adxx_id[5];
208
memset(info, 0, sizeof(faadAACInfo));
210
file = open_filestream(filename);
215
file_len = filelength_filestream(file);
217
/* Skip the tag, if it's there */
218
tmp = read_buffer_filestream(file, buffer, 10);
220
if (StringComp(buffer, "ID3", 3) == 0)
224
/* high bit is not used */
225
tagsize = (buffer[6] << 21) | (buffer[7] << 14) |
226
(buffer[8] << 7) | (buffer[9] << 0);
228
for(i=0; i < tagsize; i++)
229
if(read_byte_filestream(file) < 0)
238
/* Simple hack to reset to the beginning */
239
file->buffer_offset = 0;
240
file->file_offset = 0;
246
tmp = read_buffer_filestream(file, adxx_id, 2);
247
//seek_filestream(file, tagsize, FILE_BEGIN);
252
/* Determine the header type of the file, check the first two bytes */
253
if(StringComp(adxx_id, "AD", 2) == 0)
255
/* We think its an ADIF header, but check the rest just to make sure */
256
tmp = read_buffer_filestream(file, adxx_id + 2, 2);
258
if(StringComp(adxx_id, "ADIF", 4) == 0)
260
read_ADIF_header(file, info);
265
/* No ADIF, check for ADTS header */
266
if ((adxx_id[0] == 0xFF)&&((adxx_id[1] & 0xF6) == 0xF0))
268
/* ADTS header located */
269
/* Since this routine must work for streams, we can't use the seek function to go backwards, thus
270
we have to use a quick hack as seen below to go back where we need to. */
272
if(file->buffer_offset >= 2)
274
// simple seeking hack, though not really safe, the probability of it causing a problem is low.
275
file->buffer_offset -= 2;
276
file->file_offset -= 2;
279
read_ADTS_header(file, info, seek_table, seek_table_len, tagsize,
284
/* Unknown/headerless AAC file, assume format: */
286
info->bitrate = 128000;
287
info->sampling_rate = 44100;
289
info->headertype = 0;
290
info->object_type = 1;
294
close_filestream(file);
299
int StringComp(char const *str1, char const *str2, unsigned long len)
301
signed int c1 = 0, c2 = 0;
307
if (c1 == 0 || c1 != c2)
315
/* Program to test aacinfo functionality */
319
void main(int argc, char *argv[])
322
unsigned long *seek_table = NULL;
323
int seek_table_len = 0;
324
char *header, *object;
328
fprintf(stderr, "USAGE: aacinfo aacfile.aac\n");
332
get_AAC_format(argv[1], &info, &seek_table, &seek_table_len, 0);
334
fprintf(stdout, "MPEG version: %d\n", info.version);
335
fprintf(stdout, "channels: %d\n", info.channels);
336
fprintf(stdout, "sampling_rate: %d\n", info.sampling_rate);
337
fprintf(stdout, "bitrate: %d\n", info.bitrate);
338
fprintf(stdout, "length: %.3f\n", (float)info.length/1000.0);
340
switch (info.object_type)
355
fprintf(stdout, "object_type: %s\n", object);
357
switch (info.headertype)
369
fprintf(stdout, "headertype: %s\n", header);
2
** FAAD2 - Freeware Advanced Audio (AAC) Decoder including SBR decoding
3
** Copyright (C) 2003 M. Bakker, Ahead Software AG, http://www.nero.com
5
** This program is free software; you can redistribute it and/or modify
6
** it under the terms of the GNU General Public License as published by
7
** the Free Software Foundation; either version 2 of the License, or
8
** (at your option) any later version.
10
** This program is distributed in the hope that it will be useful,
11
** but WITHOUT ANY WARRANTY; without even the implied warranty of
12
** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13
** GNU General Public License for more details.
15
** You should have received a copy of the GNU General Public License
16
** along with this program; if not, write to the Free Software
17
** Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
19
** Any non-GPL usage of this software or parts of this software is strictly
22
** Commercial non-GPL licensing of this software is possible.
23
** For more info contact Ahead Software through Mpeg4AAClicense@nero.com.
25
** $Id: aacinfo.c,v 1.4 2003/07/29 08:20:11 menno Exp $
29
#define WIN32_LEAN_AND_MEAN
33
#include "filestream.h"
36
#define ADIF_MAX_SIZE 30 /* Should be enough */
37
#define ADTS_MAX_SIZE 10 /* Should be enough */
39
static int sample_rates[] = {96000,88200,64000,48000,44100,32000,24000,22050,16000,12000,11025,8000};
41
static int read_ADIF_header(FILE_STREAM *file, faadAACInfo *info)
44
unsigned char buffer[ADIF_MAX_SIZE];
48
/* Get ADIF header data */
51
if(read_buffer_filestream(file, buffer, ADIF_MAX_SIZE) < 0)
54
/* copyright string */
56
skip_size += 9; /* skip 9 bytes */
58
bitstream = buffer[0 + skip_size] & 0x10;
59
info->bitrate = ((unsigned int)(buffer[0 + skip_size] & 0x0F)<<19)|
60
((unsigned int)buffer[1 + skip_size]<<11)|
61
((unsigned int)buffer[2 + skip_size]<<3)|
62
((unsigned int)buffer[3 + skip_size] & 0xE0);
66
info->object_type = ((buffer[6 + skip_size]&0x01)<<1)|((buffer[7 + skip_size]&0x80)>>7);
67
sf_idx = (buffer[7 + skip_size]&0x78)>>3;
69
info->object_type = (buffer[4 + skip_size] & 0x18)>>3;
70
sf_idx = ((buffer[4 + skip_size] & 0x07)<<1)|((buffer[5 + skip_size] & 0x80)>>7);
72
info->sampling_rate = sample_rates[sf_idx];
77
static int read_ADTS_header(FILE_STREAM *file, faadAACInfo *info,
78
unsigned long **seek_table, int *seek_table_len,
79
int tagsize, int no_seek_table)
81
/* Get ADTS header data */
82
unsigned char buffer[ADTS_MAX_SIZE];
83
int frames, framesinsec=0, t_framelength = 0, frame_length, sr_idx, ID;
86
float frames_per_sec = 0;
88
unsigned long *tmp_seek_table = NULL;
92
/* Read all frames to ensure correct time and bitrate */
93
for(frames=0; /* */; frames++, framesinsec++)
95
/* If streaming, only go until we hit 5 seconds worth */
104
pos = tell_filestream(file);
106
/* 12 bit SYNCWORD */
107
bytes = read_buffer_filestream(file, buffer, ADTS_MAX_SIZE);
109
if(bytes != ADTS_MAX_SIZE)
111
/* Bail out if no syncword found */
116
if (!((buffer[0] == 0xFF)&&((buffer[1] & 0xF6) == 0xF0)))
121
/* fixed ADTS header is the same for every frame, so we read it only once */
122
/* Syncword found, proceed to read in the fixed ADTS header */
123
ID = buffer[1] & 0x08;
124
info->object_type = (buffer[2]&0xC0)>>6;
125
sr_idx = (buffer[2]&0x3C)>>2;
126
info->channels = ((buffer[2]&0x01)<<2)|((buffer[3]&0xC0)>>6);
128
frames_per_sec = sample_rates[sr_idx] / 1024.f;
131
/* ...and the variable ADTS header */
134
} else { /* MPEG-2 */
137
frame_length = ((((unsigned int)buffer[3] & 0x3)) << 11)
138
| (((unsigned int)buffer[4]) << 3) | (buffer[5] >> 5);
140
t_framelength += frame_length;
144
if(framesinsec == 43)
147
if(framesinsec == 0 && seek_table_len)
149
tmp_seek_table = (unsigned long *) realloc(tmp_seek_table, (second + 1) * sizeof(unsigned long));
150
tmp_seek_table[second] = pos;
156
/* NOTE: While simply skipping ahead by reading may seem to be more work than seeking,
157
it is actually much faster, and keeps compatibility with streaming */
158
for(i=0; i < frame_length - ADTS_MAX_SIZE; i++)
160
if(read_byte_filestream(file) < 0)
167
*seek_table_len = second;
168
*seek_table = tmp_seek_table;
171
info->sampling_rate = sample_rates[sr_idx];
172
info->bitrate = (int)(((t_framelength / frames) * (info->sampling_rate/1024.0)) +0.5)*8;
176
/* Since we only use 5 seconds of aac data to get a rough bitrate, we must use a different
177
method of calculating the overall length */
178
if(filelength_filestream(file))
180
info->length = (int)((filelength_filestream(file)/(((info->bitrate*8)/1024)*16))*1000);
184
/* Since the server didnt tell us how long the file is,
185
we have no way of determining length */
191
info->length = (int)((float)(frames/frames_per_sec))*1000;
197
int get_AAC_format(char *filename, faadAACInfo *info,
198
unsigned long **seek_table, int *seek_table_len,
201
unsigned long tagsize;
204
unsigned long file_len;
205
unsigned char adxx_id[5];
208
memset(info, 0, sizeof(faadAACInfo));
210
file = open_filestream(filename);
215
file_len = filelength_filestream(file);
217
/* Skip the tag, if it's there */
218
tmp = read_buffer_filestream(file, buffer, 10);
220
if (StringComp(buffer, "ID3", 3) == 0)
224
/* high bit is not used */
225
tagsize = (buffer[6] << 21) | (buffer[7] << 14) |
226
(buffer[8] << 7) | (buffer[9] << 0);
228
for(i=0; i < tagsize; i++)
229
if(read_byte_filestream(file) < 0)
238
/* Simple hack to reset to the beginning */
239
file->buffer_offset = 0;
240
file->file_offset = 0;
246
tmp = read_buffer_filestream(file, adxx_id, 2);
247
//seek_filestream(file, tagsize, FILE_BEGIN);
252
/* Determine the header type of the file, check the first two bytes */
253
if(StringComp(adxx_id, "AD", 2) == 0)
255
/* We think its an ADIF header, but check the rest just to make sure */
256
tmp = read_buffer_filestream(file, adxx_id + 2, 2);
258
if(StringComp(adxx_id, "ADIF", 4) == 0)
260
read_ADIF_header(file, info);
265
/* No ADIF, check for ADTS header */
266
if ((adxx_id[0] == 0xFF)&&((adxx_id[1] & 0xF6) == 0xF0))
268
/* ADTS header located */
269
/* Since this routine must work for streams, we can't use the seek function to go backwards, thus
270
we have to use a quick hack as seen below to go back where we need to. */
272
if(file->buffer_offset >= 2)
274
// simple seeking hack, though not really safe, the probability of it causing a problem is low.
275
file->buffer_offset -= 2;
276
file->file_offset -= 2;
279
read_ADTS_header(file, info, seek_table, seek_table_len, tagsize,
284
/* Unknown/headerless AAC file, assume format: */
286
info->bitrate = 128000;
287
info->sampling_rate = 44100;
289
info->headertype = 0;
290
info->object_type = 1;
294
close_filestream(file);
299
int StringComp(char const *str1, char const *str2, unsigned long len)
301
signed int c1 = 0, c2 = 0;
307
if (c1 == 0 || c1 != c2)
315
/* Program to test aacinfo functionality */
319
void main(int argc, char *argv[])
322
unsigned long *seek_table = NULL;
323
int seek_table_len = 0;
324
char *header, *object;
328
fprintf(stderr, "USAGE: aacinfo aacfile.aac\n");
332
get_AAC_format(argv[1], &info, &seek_table, &seek_table_len, 0);
334
fprintf(stdout, "MPEG version: %d\n", info.version);
335
fprintf(stdout, "channels: %d\n", info.channels);
336
fprintf(stdout, "sampling_rate: %d\n", info.sampling_rate);
337
fprintf(stdout, "bitrate: %d\n", info.bitrate);
338
fprintf(stdout, "length: %.3f\n", (float)info.length/1000.0);
340
switch (info.object_type)
355
fprintf(stdout, "object_type: %s\n", object);
357
switch (info.headertype)
369
fprintf(stdout, "headertype: %s\n", header);
b'\\ No newline at end of file'