📄 aac_dec_decoding_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) 2003-2006 Intel Corporation. All Rights Reserved.
//
// Intel(R) Integrated Performance Primitives AAC Decode Sample for Windows*
//
// By downloading and installing this sample, you hereby agree that the
// accompanying Materials are being provided to you under the terms and
// conditions of the End User License Agreement for the Intel(R) Integrated
// Performance Primitives product previously accepted by you. Please refer
// to the file ippEULA.rtf or ippEULA.txt located in the root directory of your Intel(R) IPP
// product installation for more information.
//
// MPEG-4 and AAC are international standards promoted by ISO, IEC, ITU, ETSI
// and other organizations. Implementations of these standards, or the standard
// enabled platforms may require licenses from various entities, including
// Intel Corporation.
//
*/
#include "aac_dec_int.h"
#include "aac_dec_own.h"
#include "aac_dec_own_int.h"
/********************************************************************/
static Ipp32s is_intensity(s_SE_Individual_channel_stream *pData,
Ipp32s group,
Ipp32s sfb);
static Ipp32s is_noise(s_SE_Individual_channel_stream *pData,
Ipp32s group,
Ipp32s sfb);
/********************************************************************/
Ipp32s aacidec_ics_apply_scale_factors(s_SE_Individual_channel_stream *pData,
Ipp32s *p_spectrum)
{
Ipp32s g;
Ipp32s w_num;
if (pData->window_sequence != EIGHT_SHORT_SEQUENCE) {
ippsPow43Scale_16s32s_Sf(pData->spectrum_data, p_spectrum, pData->sf[0],
pData->sfb_offset_long_window,
SF_OFFSET, pData->max_sfb, 1, -2);
ippsZero_32s(p_spectrum + pData->sfb_offset_long_window[pData->max_sfb],
1024 - pData->sfb_offset_long_window[pData->max_sfb]);
} else {
Ipp16s *ptr = pData->spectrum_data;
for (g = 0; g < pData->num_window_groups; g++) {
w_num = pData->len_window_group[g];
ippsPow43Scale_16s32s_Sf(ptr, p_spectrum, pData->sf[g],
pData->sfb_offset_short_window,
SF_OFFSET, pData->max_sfb, w_num, -5);
p_spectrum +=
w_num * pData->sfb_offset_short_window[pData->max_sfb];
ptr +=
w_num * pData->sfb_offset_short_window[pData->max_sfb];
}
}
return 0;
}
/********************************************************************/
Ipp32s aacidec_cpe_apply_ms(sCpe_channel_element *pElement,
Ipp32s *l_spec,
Ipp32s *r_spec)
{
Ipp32s i, g, sfb;
Ipp32s tmp;
Ipp32s *sfb_offset;
Ipp32s num_window_groups = pElement->streams[0].num_window_groups;
Ipp32s max_sfb = pElement->streams[0].max_sfb;
s_SE_Individual_channel_stream *p_ics_right;
p_ics_right = &pElement->streams[1];
sfb_offset =
pElement->streams[0].window_sequence == EIGHT_SHORT_SEQUENCE ?
pElement->streams[0].sfb_offset_short_window :
pElement->streams[0].sfb_offset_long_window;
if (pElement->ms_mask_present >= 1) {
for (g = 0; g < num_window_groups; g++) {
Ipp32s len_window_group = pElement->streams[0].len_window_group[g];
for (sfb = 0; sfb < max_sfb; sfb++) {
if ((pElement->ms_used[g][sfb] || pElement->ms_mask_present == 2) &&
!is_intensity(p_ics_right, g, sfb) &&
!is_noise(p_ics_right, g, sfb)) {
for (i = sfb_offset[sfb] * len_window_group;
i < sfb_offset[sfb + 1] * len_window_group; i++) {
tmp = l_spec[i] - r_spec[i];
l_spec[i] = l_spec[i] + r_spec[i];
r_spec[i] = tmp;
}
}
}
l_spec += sfb_offset[max_sfb] * len_window_group;
r_spec += sfb_offset[max_sfb] * len_window_group;
}
}
return 0;
}
/********************************************************************/
static Ipp32s invert_intensity(sCpe_channel_element *pElement,
Ipp32s group,
Ipp32s sfb)
{
if (pElement->ms_mask_present == 1)
return (1 - 2 * pElement->ms_used[group][sfb]);
return 1;
}
/********************************************************************/
static Ipp32s pow2table[] = {1073741824, 1276901417, 1518500250, 1805811301};
/********************************************************************/
Ipp32s aacidec_cpe_apply_intensity(sCpe_channel_element *pElement,
Ipp32s *l_spec,
Ipp32s *r_spec)
{
Ipp32s i, g, sfb;
Ipp32s group;
Ipp32s *sfb_offset;
Ipp32s num_window_groups;
Ipp32s max_sfb;
s_SE_Individual_channel_stream *p_ics_right;
p_ics_right = &pElement->streams[1];
sfb_offset =
pElement->streams[0].window_sequence == EIGHT_SHORT_SEQUENCE ?
pElement->streams[0].sfb_offset_short_window :
pElement->streams[0].sfb_offset_long_window;
num_window_groups = p_ics_right->num_window_groups;
max_sfb = p_ics_right->max_sfb;
group = 0;
for (g = 0; g < num_window_groups; g++) {
Ipp32s len_window_group = p_ics_right->len_window_group[g];
for (sfb = 0; sfb < max_sfb; sfb++) {
Ipp32s tmp0 = is_intensity(p_ics_right, g, sfb);
if (tmp0) {
Ipp32s tmp1 = invert_intensity(pElement, g, sfb);
Ipp32s itmp = -p_ics_right->sf[g][sfb];
Ipp32s exp = 30 - (itmp >> 2);
Ipp32s mant = pow2table[itmp & 3];
tmp0 = tmp0 * tmp1;
mant = mant * tmp0;
if (exp > 63) exp = 63;
for (i = sfb_offset[sfb] * len_window_group;
i < sfb_offset[sfb + 1] * len_window_group; i++) {
r_spec[i] = (Ipp32s)(((Ipp64s)l_spec[i] * mant) >> exp);
}
}
}
l_spec += sfb_offset[max_sfb] * len_window_group;
r_spec += sfb_offset[max_sfb] * len_window_group;
}
return 0;
}
/********************************************************************/
static Ipp32s is_intensity(s_SE_Individual_channel_stream *pData,
Ipp32s group,
Ipp32s sfb)
{
switch (pData->sfb_cb[group][sfb]) {
case INTENSITY_HCB:
return 1;
case INTENSITY_HCB2:
return -1;
default:
return 0;
}
}
/********************************************************************/
static Ipp32s is_noise(s_SE_Individual_channel_stream *pData,
Ipp32s group,
Ipp32s sfb)
{
if (pData->sfb_cb[group][sfb] == NOISE_HCB)
return 1;
return 0;
}
/********************************************************************/
static void noise_generator(Ipp32s *dst,
Ipp32s len,
Ipp32s *noiseState,
Ipp32s *norm,
Ipp32s *scale)
{
Ipp64s norml, ltemp;
Ipp32s normi;
Ipp32s seed, i;
Ipp32s shift;
norml = 0;
seed = *noiseState;
if (len == 1) shift = 0;
else {
Ipp32s tmp = len - 1;
shift = -1;
while (tmp > 0) {
shift++;
tmp >>= 1;
}
}
for (i = 0; i < len; i++) {
seed = (1664525L * seed) + 1013904223L;
dst[i] = (Ipp32s)seed;
norml += ((Ipp64s)seed * seed) >> shift;
}
*noiseState = seed;
normi = (Ipp32s)(norml >> 32);
while (normi < 1073741824) {
shift--;
normi <<= 1;
}
ltemp = ((Ipp64s)normi * normi ) >> 32; /* Q30 */
ltemp = ltemp * 13563; /* Q44 */
ltemp -= (Ipp64s)normi * 16760; /* Q44 */
ltemp += 39107824713728L; /* Q44 */
normi = (Ipp32s)(ltemp >> 14); /* Q30 */
shift += (30 * 2 + 31 + 32);
if (shift & 1) {
normi = (Ipp32s)(((Ipp64s)normi * 1518500250) >> 31);
shift--;
}
*scale = shift >> 1;
*norm = normi;
}
/********************************************************************/
Ipp32s aacidec_apply_pns(s_SE_Individual_channel_stream *pDataL,
s_SE_Individual_channel_stream *pDataR,
Ipp32s *p_spectrumL,
Ipp32s *p_spectrumR,
Ipp32s numCh,
Ipp32s ms_mask_present,
Ipp32s ms_used[8][49],
Ipp32s *noiseState)
{
Ipp32s i, g, sfb, ich;
Ipp32s norm;
Ipp32s normScale;
Ipp32s *sfb_offset;
Ipp32s num_window_groups, max_sfb;
s_SE_Individual_channel_stream *pData = pDataL;
Ipp32s *p_spectrum = p_spectrumL;
Ipp32s *p_spectrum_l = p_spectrumL;
for (ich = 0; ich < numCh; ich++) {
sfb_offset = pData->window_sequence == EIGHT_SHORT_SEQUENCE ?
pData->sfb_offset_short_window : pData->sfb_offset_long_window;
num_window_groups = pData->num_window_groups;
max_sfb = pData->max_sfb;
for (g = 0; g < num_window_groups; g++) {
Ipp32s len_window_group = pData->len_window_group[g];
for (sfb = 0; sfb < max_sfb; sfb++) {
if (pData->sfb_cb[g][sfb] == NOISE_HCB) {
Ipp32s tmp = 0;
if ((ich == 1) && (ms_mask_present >= 1)) {
if ((ms_used[g][sfb] != 0) || (ms_mask_present == 2)) {
tmp = 1;
}
}
if (tmp) {
Ipp32s itmp = pData->sf[g][sfb] - pDataL->sf[g][sfb];
Ipp32s exp = 30 - (itmp >> 2);
Ipp32s mant = pow2table[itmp & 3];
if (exp > 0) {
if (exp > 63) exp = 63;
for (i = sfb_offset[sfb] * len_window_group;
i < sfb_offset[sfb + 1] * len_window_group; i++) {
p_spectrum[i] = (Ipp32s)(((Ipp64s)p_spectrum_l[i] * mant) >> exp);
}
} else {
for (i = sfb_offset[sfb] * len_window_group;
i < sfb_offset[sfb + 1] * len_window_group; i++) {
p_spectrum[i] = (Ipp32s)(((Ipp64s)p_spectrum_l[i] * mant) << exp);
}
}
} else {
Ipp32s itmp = pData->sf[g][sfb];
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -