📄 aac_enc_api_int.c
字号:
/*//////////////////////////////////////////////////////////////////////////////
//
// INTEL CORPORATION PROPRIETARY INFORMATION
// This software is supplied under the terms of a license agreement or
// nondisclosure agreement with Intel Corporation and may not be copied
// or disclosed except in accordance with the terms of that agreement.
// Copyright(c) 2004-2007 Intel Corporation. All Rights Reserved.
//
//
//
//
*/
#include <stdlib.h>
#include <stdio.h>
#include "aac_enc_own_int.h"
#include "aac_enc_own.h"
#include "aac_enc_int.h"
#include "aac_sfb_tables.h"
#include "aac_enc_huff_tables.h"
#include "aaccmn_const.h"
#include "aac_enc_psychoacoustic_int.h"
#include "aac_enc_filterbank_int.h"
#include "aac_enc_quantization_int.h"
#include "aac_enc_ltp_int.h"
#include "ipps.h"
/********************************************************************/
void aaciencUpdateMemMap(AACEnc *state,
Ipp32s shift)
{
Ipp32s i;
Ipp32s chNum = state->com.m_channel_number;
for (i = 0; i < 12; i++) {
AAC_UPDATE_PTR(IppsVLCEncodeSpec_32s, state->com.huffman_tables[i], shift)
}
AAC_UPDATE_PTR(sOneChannelInfo, state->com.chInfo, shift)
AAC_UPDATE_PTR(sCrcSaveTable, state->com.crcSaveTable, shift)
AAC_UPDATE_PTR(Ipp16s*, state->com.buff, shift)
for (i = 0; i < chNum; i++) {
AAC_UPDATE_PTR(Ipp16s, state->com.buff[i], shift)
}
AAC_UPDATE_PTR(Ipp16s*, state->m_buff_pointers, shift)
for (i = 0; i < 3*chNum; i++) {
AAC_UPDATE_PTR(Ipp16s, state->m_buff_pointers[i], shift)
}
AAC_UPDATE_PTR(Ipp16s*, state->ltp_buff, shift)
AAC_UPDATE_PTR(Ipp32s*, state->ltp_overlap, shift)
AAC_UPDATE_PTR(sPsychoacousticBlock, state->psychoacoustic_block, shift)
AAC_UPDATE_PTR(IppsFFTSpec_R_16s, state->psychoacoustic_block_com.pFFTSpecShort, shift)
AAC_UPDATE_PTR(IppsFFTSpec_R_16s, state->psychoacoustic_block_com.pFFTSpecLong, shift)
AAC_UPDATE_PTR(Ipp8u, state->psychoacoustic_block_com.pBuffer, shift)
AAC_UPDATE_PTR(IppsMDCTFwdSpec_16s, state->filterbank_enc.p_mdct_fwd_long, shift)
AAC_UPDATE_PTR(IppsMDCTFwdSpec_16s, state->filterbank_enc.p_mdct_fwd_short, shift)
AAC_UPDATE_PTR(Ipp8u, state->filterbank_enc.p_buffer_fwd, shift)
if (state->com.audioObjectType == AOT_AAC_LTP) {
for (i = 0; i < chNum; i++) {
AAC_UPDATE_PTR(Ipp16s, state->ltp_buff[i], shift)
}
for (i = 0; i < chNum; i++) {
AAC_UPDATE_PTR(Ipp32s, state->ltp_overlap[i], shift)
}
AAC_UPDATE_PTR(IppsFFTSpec_R_32s, state->corrFft, shift)
AAC_UPDATE_PTR(Ipp8u, state->corrBuff, shift)
}
}
/****************************************************************************/
AACStatus aaciencInit(AACEnc *state,
Ipp32s sampling_frequency,
Ipp32s chNum,
Ipp32s bit_rate,
enum AudioObjectType audioObjectType,
Ipp32s stereo_mode,
Ipp32s ns_mode,
Ipp32s *size_all)
{
AACEnc_com *state_com;
Ipp8u *ptr;
Ipp32s **ltp_overlap;
Ipp16s **m_buff_pointers;
Ipp16s **ltp_buff;
Ipp16s **buff;
Ipp32s sf_index;
Ipp32s ch;
Ipp32s i, k, w;
Ipp32s sizeOfAACenc, sizeOfOneChannelInfo, sizeOfsCrcSaveTable;
Ipp32s sizeOfPsychoacousticBlock, sizeOfPointers;
Ipp32s size, tmpSize;
Ipp32s num_sfb_for_long;
Ipp32s num_sfb_for_short;
Ipp32s* sfb_offset_for_long;
Ipp32s* sfb_offset_for_short;
Ipp32s cutoff_frequency;
Ipp32s bits_per_frame;
Ipp32s bits_for_lfe = 0;
Ipp32s lfe_channel_present;
Ipp32s max_line, max_sfb;
Ipp32s bit_rate_per_ch, inScaleFactor;
Ipp16s short_tmp, short_cutoff_frequency;
Ipp32s sce_tag;
Ipp32s cpe_tag;
Ipp32s lfe_tag;
Ipp32s num_channel;
AACStatus aacStatus = AAC_OK;
IppStatus ippStatus = ippStsNoErr;
if (chNum < 1) {
return AAC_BAD_PARAMETER;
}
sf_index = 12;
for (i = 0; i < 12; i ++) {
if (sfb_tables[i].samp_rate == sampling_frequency) {
sf_index = i;
break;
}
}
if (sf_index == 12)
return AAC_BAD_PARAMETER;
sizeOfAACenc = (sizeof(AACEnc) + 31) & (~31);
sizeOfsCrcSaveTable = (sizeof(sCrcSaveTable) + 31) & (~31);
sizeOfOneChannelInfo = (sizeof(sOneChannelInfo) + 31) & (~31);
sizeOfPsychoacousticBlock = (sizeof(sPsychoacousticBlock) + 31) & (~31);
sizeOfPointers = (chNum * (5 * sizeof(Ipp16s*) + sizeof(Ipp32s*)) + 31) & (~31);
size = sizeOfAACenc + sizeOfPointers + chNum * (sizeOfsCrcSaveTable +
sizeOfOneChannelInfo + sizeOfPsychoacousticBlock +
3 * 1024 * sizeof(Ipp16s)) + 32;
if (audioObjectType == AOT_AAC_LTP) {
size += chNum * (3072 * sizeof(Ipp16s) + 1024 * sizeof(Ipp32s));
}
ptr = (Ipp8u *)state;
if (state) {
ippsZero_8u(ptr, size);
state_com = &(state->com);
ptr = (Ipp8u *)state + sizeOfAACenc;
state_com->chInfo = (sOneChannelInfo *)ptr;
ptr += chNum * sizeOfOneChannelInfo;
state_com->crcSaveTable = (sCrcSaveTable *)ptr;
ptr += chNum * sizeOfsCrcSaveTable;
state_com->m_channel_number = chNum;
state_com->sampling_frequency_index = sf_index;
state_com->m_sampling_frequency = sampling_frequency;
state_com->m_bitrate = bit_rate;
ltp_overlap = (Ipp32s**)ptr;
m_buff_pointers = (Ipp16s**)(ltp_overlap + chNum);
ltp_buff = m_buff_pointers + 3 * chNum;
buff = ltp_buff + chNum;
ptr += sizeOfPointers;
state->psychoacoustic_block = (sPsychoacousticBlock *)ptr;
ptr += chNum * sizeOfPsychoacousticBlock;
if (audioObjectType == AOT_AAC_LTP) {
for (i = 0; i < chNum; i++) {
ltp_overlap[i] = (Ipp32s*)ptr;
ptr += 1024 * sizeof(Ipp32s);
}
for (i = 0; i < chNum; i++) {
ltp_buff[i] = (Ipp16s*)ptr;
ptr += 3072 * sizeof(Ipp16s);
}
}
for (i = 0; i < 3 * chNum; i++) {
m_buff_pointers[i] = (Ipp16s*)ptr;
ptr += 1024 * sizeof(Ipp16s);
}
state->m_buff_pointers = m_buff_pointers;
state->ltp_buff = ltp_buff;
state->ltp_overlap = ltp_overlap;
state_com->buff = buff;
state_com->m_buff_prev_index = 0;
state_com->m_buff_curr_index = 1;
state_com->m_buff_next_index = 2;
num_sfb_for_long = sfb_tables[sf_index].num_sfb_long_window;
num_sfb_for_short = sfb_tables[sf_index].num_sfb_short_window;
sfb_offset_for_short = sfb_tables[sf_index].sfb_offset_short_window;
state_com->sfb_offset_for_short_window[0] = 0;
k = 1;
for (w = 0; w < 8; w ++) {
for ( i = 0; i < num_sfb_for_short; i++) {
state_com->sfb_offset_for_short_window[k] = state_com->sfb_offset_for_short_window[k-1] +
(sfb_offset_for_short[i + 1] - sfb_offset_for_short[i]);
k++;
}
}
state_com->sfb_offset[0] = state_com->sfb_offset[1] = state_com->sfb_offset[3] =
sfb_tables[sf_index].sfb_offset_long_window;
state_com->sfb_offset[2] = state_com->sfb_offset_for_short_window;
state_com->huffman_tables[0] = (IppsVLCEncodeSpec_32s*)ptr;
aacStatus = BuildHuffmanTables((IppsVLCEncodeSpec_32s**)(&state_com->huffman_tables),
&tmpSize);
if (aacStatus != AAC_OK) return aacStatus;
size += tmpSize;
ptr = (Ipp8u*)state_com->huffman_tables[0] + tmpSize;
if (bit_rate <= 0) {
return AAC_BAD_PARAMETER;
}
lfe_channel_present = 0;
if ((chNum > 4) && ((chNum & 1) == 0))
lfe_channel_present = 1;
/* ********************************************************************* */
/* CONFIG CHANNEL ELEMENT */
/* ********************************************************************* */
i = 0;
if (chNum != 2) {
state_com->chInfo[0].element_id = ID_SCE;
i += 1;
}
for (ch = i ; ch < chNum - lfe_channel_present; ch++) {
state_com->chInfo[ch].element_id = ID_CPE;
}
if (lfe_channel_present) {
state_com->chInfo[chNum-1].element_id = ID_LFE;
}
if (chNum == 4) {
state_com->chInfo[chNum-1].element_id = ID_SCE;
}
bits_per_frame = (bit_rate * 1024)/(sfb_tables[sf_index].samp_rate);
if (bits_per_frame > 768 * 8 * chNum)
bits_per_frame = 768 * 8 * chNum;
bits_per_frame &= ~7;
bits_per_frame -= 3; /* for ID_END */
bit_rate_per_ch = bit_rate / chNum;
state->ms_mul = ((100 - (bit_rate_per_ch >> 10)) * 1638) >> 4; /* 1638 ~ 0.05 * 32768 */
if (state->ms_mul < 0) state->ms_mul = 0; /* ms_mul in Q11 */
state->ms_thr = (bit_rate_per_ch >> 14); /* in Q4 */
sfb_offset_for_long = sfb_tables[sf_index].sfb_offset_long_window;
inScaleFactor = 0;
while (bit_rate_per_ch >= 32768) {
inScaleFactor += 1;
bit_rate_per_ch >>= 1;
}
short_tmp = (Ipp16s)bit_rate_per_ch;
ippsPow34_16s_Sfs(&short_tmp, inScaleFactor, &short_cutoff_frequency, 0, 1);
cutoff_frequency = short_cutoff_frequency * 4;
max_line = (2048 * cutoff_frequency) / sampling_frequency;
max_sfb = num_sfb_for_long;
for (i = 0; i < num_sfb_for_long; i++) {
if (sfb_offset_for_long[i] > max_line) {
max_sfb = i;
break;
}
}
state_com->real_max_sfb[0] = state_com->real_max_sfb[1] =
state_com->real_max_sfb[3] = max_sfb;
state_com->real_max_line[0] = state_com->real_max_line[1] =
state_com->real_max_line[3] = sfb_offset_for_long[max_sfb];
max_line = (256 * cutoff_frequency) / sampling_frequency;
max_sfb = num_sfb_for_short;
for (i = 0; i < num_sfb_for_short; i++) {
if (sfb_offset_for_short[i] > max_line) {
max_sfb = i;
break;
}
}
state_com->real_max_sfb[2] = max_sfb;
state_com->real_max_line[2] = sfb_offset_for_short[max_sfb] * 8;
/* High AHT boundary - 15000 Hz */
max_line = (2048 * 15000 / sampling_frequency);
max_sfb = num_sfb_for_long;
for (i = 0; i < num_sfb_for_long; i++) {
if (sfb_offset_for_long[i] > max_line) {
max_sfb = i;
break;
}
}
if (max_sfb > state_com->real_max_sfb[0])
max_sfb = state_com->real_max_sfb[0];
state_com->ath_max_sfb[0] = state_com->ath_max_sfb[1] =
state_com->ath_max_sfb[3] = max_sfb;
max_line = (256 * 15000 / sampling_frequency);
max_sfb = num_sfb_for_short;
for (i = 0; i < num_sfb_for_short; i++) {
if (sfb_offset_for_short[i] > max_line) {
max_sfb = i;
break;
}
}
if (max_sfb > state_com->real_max_sfb[2])
max_sfb = state_com->real_max_sfb[2];
state_com->ath_max_sfb[2] = max_sfb;
/* max_sfb for LFE channel calculating */
if (cutoff_frequency > MAX_LFE_FREQUENCY) {
cutoff_frequency = MAX_LFE_FREQUENCY;
max_line = (2048 * cutoff_frequency) / sampling_frequency;
max_sfb = num_sfb_for_long;
for (i = 0; i < num_sfb_for_long; i++) {
if (sfb_offset_for_long[i] > max_line) {
max_sfb = i;
break;
}
}
state_com->real_max_sfb_lfe[0] = state_com->real_max_sfb_lfe[1] =
state_com->real_max_sfb_lfe[3] = max_sfb;
state_com->real_max_line_lfe[0] = state_com->real_max_line_lfe[1] =
state_com->real_max_line_lfe[3] = sfb_offset_for_long[max_sfb];
max_line = (256 * cutoff_frequency) / sampling_frequency;
max_sfb = num_sfb_for_short;
for (i = 0; i < num_sfb_for_short; i++) {
if (sfb_offset_for_short[i] > max_line) {
max_sfb = i;
break;
}
}
state_com->real_max_sfb_lfe[2] = max_sfb;
state_com->real_max_line_lfe[2] = sfb_offset_for_short[max_sfb] * 8;
} else {
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -