have been doing a voice project, to the test phase, not very busy recently, want to put the content of the previous work to tidy up.
For the AAC audio format basics, refer to Wikipedia http://en.wikipedia.org/wiki/Advanced_Audio_Coding
AAC Audio Format Analysis
AAC audio formats are ADIF and Adts:
ADIF: Audio Data Interchange Format. The feature of this format is that it can be determined to find the beginning of this audio data, without the need to start decoding in the middle of the audio stream, that is, its decoding must be at the beginning of a well-defined definition. Therefore, this format is commonly used in disk files.
ADTS: Audio data stream Transport stream. The feature of this format is that it is a bit stream with a synchronized word, and the decoding can begin anywhere in the stream. Its characteristics are similar to the MP3 data stream format.
Simply put, Adts can be decoded at any frame, meaning it has header information for each frame. ADIF has only one unified head, so you must get all the data after decoding. And the two kinds of header format is also different, the current generally encoded and extracted is the ADTS format of the audio stream.
Voice system for real-time requirements of high, basically is such a process, the acquisition of audio data, local code, data upload, server processing, data issued, local decoding
Adts is a frame sequence, which has the characteristics of flow, which is more suitable for the transmission and processing of audio streams.
ADTS Frame structure:
Adts Frame Header structure:
Serial number |
Domain |
Length (BITS) |
Description |
1 |
Syncword |
12 |
All bits must is 1 |
2 |
MPEG version |
1 |
0 for MPEG-4, 1 for MPEG-2 |
3 |
Layer |
2 |
Always 0 |
4 |
Protection Absent |
1 |
ET to 1 if there are no CRC and 0 if there is CRC |
5 |
Profile |
2 |
The MPEG-4 Audio Object Type minus 1 |
6 |
MPEG-4 Sampling Frequency Index |
4 |
MPEG-4 sampling Frequency Index (Forbidden) |
7 |
Private Stream |
1 |
Set to 0 when encoding, ignore when decoding |
8 |
MPEG-4 Channel Configuration |
3 |
MPEG-4 channel configuration (in the case of 0, the channel configuration was sent via an inband PCE) |
9 |
Originality |
1 |
Set to 0 when encoding, ignore when decoding |
10 |
Home |
1 |
Set to 0 when encoding, ignore when decoding |
11 |
Copyrighted Stream |
1 |
Set to 0 when encoding, ignore when decoding |
12 |
Copyrighted Start |
1 |
Set to 0 when encoding, ignore when decoding |
13 |
Frame Length |
13 |
This value must include 7 or 9 bytes of header Length:framelength = (Protectionabsent = = 1? 7:9) + Size (aacframe) |
14 |
Buffer fullness |
11 |
Buffer fullness |
15 |
Number of AAC Frames |
2 |
Number of AAC frames (RDBS) in ADTS frame minus 1, for maximum compatibility always use 1 AAC frame per ADTS fram E |
16 |
Crc |
16 |
CRC if protection absent is 0 |
A AC decode
In terms of decoding, the use of open source faad,http://www.audiocoding.com/faad2.html
After the SDK is decompressed, the Docs directory has a detailed API documentation, which is mainly used in the following categories:
Neaacdechandle Neaacapi Neaacdecopen (void);
Create a decoding environment and return a handle
void Neaacapi neaacdecclose (Neaacdechandle hdecoder);
Turn off decoding environment
Neaacdecconfigurationptr Neaacapi neaacdecgetcurrentconfiguration (Neaacdechandle hDecoder);
Get the configuration of the current decoder library
Char Neaacapi neaacdecsetconfiguration (neaacdechandle hdecoder, neaacdecconfigurationptr config);
Set up a configuration structure for the decoder library
Char *channels);
Initializing the Decoder library
Long buffer_size);
Decode AAC Data
The above API has made a simple package, wrote a decoding class, covering the basic usage of the Faad library, interested friends can see
MyAACDecoder.h:
/**
*
* Filename:myaacdecoder.h
* Summary:convert AAC to wave
* Email: [Email protected]
*
*/
#ifndef __myaacdecoder_h__
#define __myaacdecoder_h__
"Buffer.h"
"Mytools.h"
"WaveFormat.h"
"Faad.h"
#include <iostream>
namespace Std;
Class Myaacdecoder {
Public
Myaacdecoder ();
~myaacdecoder ();
int32_t Decode (char *aacbuf, uint32_t aacbuflen);
const {
Return _mybuffer. Data ();
}
const {
Return _mybuffer. Length ();
}
const {
return _wave_format.getheaderdata ();
}
const {
return _wave_format.getheaderlength ();
}
Private
Myaacdecoder (const myaacdecoder &DEC);
Operator= (const myaacdecoder &RHS);
Init AAC Decoder
int32_t _init_aac_decoder (char *aacbuf, int32_t aacbuflen);
Destroy AAC Decoder
void _destroy_aac_decoder ();
Parse AAC ADTS header, get frame length
uint32_t _get_frame_length (const;
AAC Decoder Properties
Neaacdechandle _handle;
Long _samplerate;
Char _channel;
Buffer _mybuffer;
Waveformat _wave_format;
};
/*__myaacdecoder_h__*/
MyAACDecoder.cpp:
"MyAACDecoder.h"
Myaacdecoder::myaacdecoder (): _handle (NULL), _samplerate (44100), _channel (2), _mybuffer (4096, 4096) {
}
Myaacdecoder::~myaacdecoder () {
_destroy_aac_decoder ();
}
int32_t Myaacdecoder::D ecode (char *aacbuf, uint32_t aacbuflen) {
int32_t res = 0;
if (!_handle) {
if (_init_aac_decoder (AACBUF, aacbuflen)! = 0) {
ERR1 (":::: Init AAC Decoder failed::::");
return-1;
}
}
Clean _mybuffer
_mybuffer. Clean ();
uint32_t Donelen = 0;
uint32_t Wav_data_len = 0;
while (Donelen < Aacbuflen) {
uint32_t Framelen = _get_frame_length (aacbuf + Donelen);
if (Donelen + Framelen > Aacbuflen) {
Break
}
Decode
Neaacdecframeinfo info;
char*) Aacbuf + Donelen, Framelen);
if (buf && info.error = = 0) {
if (info.samplerate = = 44100) {
44100Hz
src:2048 samples, 4096 bytes
dst:2048 samples, 4096 bytes
uint32_t Tmplen = info.samples * 16/8;
_mybuffer. Fill ((char*) buf, Tmplen);
Wav_data_len + = Tmplen;
if (info.samplerate = = 22050) {
22050Hz
src:1024 samples, 2048 bytes
dst:2048 samples, 4096 bytes
Short *ori = (short*) buf;
Short tmpbuf[info.samples * 2];
uint32_t Tmplen = info.samples * 16/8 * 2;
for (int32_t i = 0, j = 0; i < info.samples; i + = 2) {
Tmpbuf[j++] = Ori[i];
Tmpbuf[j++] = ori[i + 1];
Tmpbuf[j++] = Ori[i];
Tmpbuf[j++] = ori[i + 1];
}
_mybuffer. Fill ((char*) tmpbuf, Tmplen);
Wav_data_len + = Tmplen;
}
else {
ERR1 ("Neaacdecdecode () failed");
}
Donelen + = Framelen;
}
Generate Wave Header
_wave_format.setsamplerate (_samplerate);
_wave_format.setchannel (_channel);
_wave_format.setsamplebit (16);
_wave_format.setbandwidth (_samplerate * _channel/8);
_wave_format.setdatalength (Wav_data_len);
_wave_format.settotallength (Wav_data_len + 44);
_wave_format. Generateheader ();
return 0;
}
uint32_t myaacdecoder::_get_frame_length (const {
uint32_t len = * (uint32_t *) (Aac_header + 3);
Little Endian
Len = Len << 6;
Len = Len >> 19;
return Len;
}
int32_t Myaacdecoder::_init_aac_decoder (char* aacbuf, int32_t aacbuflen) {
Long cap = Neaacdecgetcapabilities ();
_handle = Neaacdecopen ();
if (!_handle) {
ERR1 ("Neaacdecopen () failed");
_destroy_aac_decoder ();
return-1;
}
Neaacdecconfigurationptr conf = neaacdecgetcurrentconfiguration (_handle);
if (!conf) {
ERR1 ("neaacdecgetcurrentconfiguration () failed");
_destroy_aac_decoder ();
return-1;
}
Neaacdecsetconfiguration (_handle, conf);
char *) aacbuf, Aacbuflen, &_samplerate, &_channel);
if (Res < 0) {
ERR1 ("Neaacdecinit () failed");
_destroy_aac_decoder ();
return-1;
}
fprintf (stdout, "samplerate =%d\n", _samplerate);
fprintf (stdout, "Channel =%d\n", _channel);
fprintf (stdout, ":::: Init AAC decoder done:::: \ n");
return 0;
}
void Myaacdecoder::_destroy_aac_decoder () {
if (_handle) {
Neaacdecclose (_handle);
_handle = NULL;
}
}
AAC Format Analysis