diff options
Diffstat (limited to 'media/libstagefright/codecs/aacdec/pns_intensity_right.cpp')
-rw-r--r-- | media/libstagefright/codecs/aacdec/pns_intensity_right.cpp | 653 |
1 files changed, 653 insertions, 0 deletions
diff --git a/media/libstagefright/codecs/aacdec/pns_intensity_right.cpp b/media/libstagefright/codecs/aacdec/pns_intensity_right.cpp new file mode 100644 index 0000000..f2d50c1 --- /dev/null +++ b/media/libstagefright/codecs/aacdec/pns_intensity_right.cpp @@ -0,0 +1,653 @@ +/* ------------------------------------------------------------------ + * Copyright (C) 1998-2009 PacketVideo + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either + * express or implied. + * See the License for the specific language governing permissions + * and limitations under the License. + * ------------------------------------------------------------------- + */ +/* + + Pathname: pns_intensity_right.c + +------------------------------------------------------------------------------ + INPUT AND OUTPUT DEFINITIONS + + Inputs: + + hasmask = mask status for the frame. Enumerated. + + pFrameInfo = Pointer to structure that holds information about each group. + (long block flag, number of windows, scalefactor bands + per group, etc.) + [const pFrameInfo * const] + + group = Array that contains indexes of the + first window in the next group. + [const Int *, length num_win] + + mask_map = Array that denotes whether M/S stereo is turned on for + each grouped scalefactor band. + [const Int *, length MAX_SFB] + + codebook_map = Array that denotes which Huffman codebook was used for + the encoding of each grouped scalefactor band. + [const Int *, length MAX_SFB] + + factorsL = Array of grouped scalefactors for left chan. + [const Int *, length MAX_SFB] + + factorsR = Array of scalefactors for right chan. + [const Int *, length MAX_SFB] + + sfb_prediction_used = Flag that denotes the activation of long term prediction + on a per-scalefactor band, non-grouped basis. + [const Int *, length MAX_SFB] + + ltp_data_present = Flag that indicates whether LTP is enbaled for this frame. + [const Bool] + + coefLeft = Array containing the fixed-point spectral coefficients + for the left channel. + [Int32 *, length 1024] + + coefRight = Array containing the fixed-point spectral coefficients + for the right channel. + [Int32 *, length 1024] + + q_formatLeft = The Q-format for the left channel's fixed-point spectral + coefficients, on a per-scalefactor band, non-grouped basis. + [Int *, length MAX_SFB] + + q_formatRight = The Q-format for the right channel's fixed-point spectral + coefficients, on a per-scalefactor band, non-grouped basis. + [Int *, length MAX_SFB] + + pCurrentSeed = Pointer to the current seed for the random number + generator in the function gen_rand_vector(). + [Int32 * const] + + Local Stores/Buffers/Pointers Needed: + None + + Global Stores/Buffers/Pointers Needed: + None + + Outputs: + None + + Pointers and Buffers Modified: + coefLeft = Contains the new spectral information. + + coefRight = Contains the new spectral information. + + q_formatLeft = Q-format may be updated with changed to fixed-point + data in coefLeft. + + q_formatRight = Q-format may be updated with changed to fixed-point + data in coefRight. + + pCurrentSeed = Value pointed to by pCurrentSeed updated by calls + to gen_rand_vector(). + + Local Stores Modified: + None + + Global Stores Modified: + None + +------------------------------------------------------------------------------ + FUNCTION DESCRIPTION + + This function steps through all of the scalefactor bands, looking for + either PNS or IS to be enabled on the right channel. + + If the codebook used is >= NOISE_HCB, the code then checks for the use + of Huffman codebooks NOISE_HCB, INTENSITY_HCB, or INTENSITY_HCB2. + + When a SFB utilizing the codebook NOISE_HCB is detected, a check is made to + see if M/S has also been enabled for that SFB. + + If M/S is not enabled, the band's spectral information is filled with + scaled random data. The scaled random data is generated by the function + gen_rand_vector. This is done across all windows in the group. + + If M/S is enabled, the band's spectral information is derived from the data + residing in the same band on the left channel. The information on the right + channel has independent scaling, so this is a bit more involved than a + direct copy of the information on the left channel. This is done by calling + the inline function pns_corr(). + + When a SFB utilizing an intensity codebook is detected, the band's spectral + information is generated from the information on the left channel. + This is done across all windows in the group. M/S being enabled has the + effect of reversing the sign of the data on the right channel. This code + resides in the inline function intensity_right(). + +------------------------------------------------------------------------------ + REQUIREMENTS + + +------------------------------------------------------------------------------ + REFERENCES + + (1) ISO/IEC 14496-3:1999(E) + Part 3 + Subpart 4.6.7.1 M/S stereo + Subpart 4.6.7.2.3 Decoding Process (Intensity Stereo) + Subpart 4.6.12.3 Decoding Process (PNS) + Subpart 4.6.2 ScaleFactors + + (2) MPEG-2 NBC Audio Decoder + "This software module was originally developed by AT&T, Dolby + Laboratories, Fraunhofer Gesellschaft IIS in the course of development + of the MPEG-2 NBC/MPEG-4 Audio standard ISO/IEC 13818-7, 14496-1,2 and + 3. This software module is an implementation of a part of one or more + MPEG-2 NBC/MPEG-4 Audio tools as specified by the MPEG-2 NBC/MPEG-4 + Audio standard. ISO/IEC gives users of the MPEG-2 NBC/MPEG-4 Audio + standards free license to this software module or modifications thereof + for use in hardware or software products claiming conformance to the + MPEG-2 NBC/MPEG-4 Audio standards. Those intending to use this software + module in hardware or software products are advised that this use may + infringe existing patents. The original developer of this software + module and his/her company, the subsequent editors and their companies, + and ISO/IEC have no liability for use of this software module or + modifications thereof in an implementation. Copyright is not released + for non MPEG-2 NBC/MPEG-4 Audio conforming products.The original + developer retains full right to use the code for his/her own purpose, + assign or donate the code to a third party and to inhibit third party + from using the code for non MPEG-2 NBC/MPEG-4 Audio conforming products. + This copyright notice must be included in all copies or derivative + works." + Copyright(c)1996. + +------------------------------------------------------------------------------ + PSEUDO-CODE + pCoefRight = coefRight; + pCoefLeft = coefLeft; + + window_start = 0; + tot_sfb = 0; + start_indx = 0; + + coef_per_win = pFrameInfo->coef_per_win[0]; + + sfb_per_win = pFrameInfo->sfb_per_win[0]; + + DO + pBand = pFrameInfo->win_sfb_top[window_start]; + + partition = *pGroup; + pGroup = pGroup + 1; + + band_start = 0; + + wins_in_group = (partition - window_start); + + FOR (sfb = sfb_per_win; sfb > 0; sfb--) + + band_stop = *(pBand); + pBand = pBand + 1; + + codebook = *(pCodebookMap); + pCodebookMap = pCodebookMap + 1; + + mask_enabled = *(pMaskMap); + pMaskMap = pMaskMap + 1; + + band_length = band_stop - band_start; + + IF (codebook == NOISE_HCB) + + sfb_prediction_used[tot_sfb] &= ltp_data_present; + + IF (sfb_prediction_used[tot_sfb] == FALSE) + + mask_enabled = mask_enabled AND hasmask; + + IF (mask_enabled == FALSE) + + pWindow_CoefR = &(pCoefRight[band_start]); + + start_indx = tot_sfb; + + FOR (win_indx = wins_in_group; + win_indx > 0; + win_indx--) + + CALL + q_formatRight[start_indx] = + gen_rand_vector( + pWindow_CoefR, + band_length, + pCurrentSeed, + *(pFactorsRight)); + MODIFYING + pCoefRight[band_start] + RETURNING + q_formatRight[start_indx] + + pWindow_CoefR += coef_per_win; + + start_indx = start_indx + sfb_per_win; + + ENDFOR + + ELSE + CALL + pns_corr( + (*(pFactorsRight) - + *(pFactorsLeft) ), + coef_per_win, + sfb_per_win, + wins_in_group, + band_length, + q_formatLeft[tot_sfb], + &(q_formatRight[tot_sfb]), + &(pCoefLeft[band_start]), + &(pCoefRight[band_start])); + + MODIFYING + pCoefRightt[band_start] + q_formatRight[tot_sfb] + RETURNING + NONE + ENDIF + + ENDIF + + ELSE IF (codebook >= INTENSITY_HCB2) + + mask_enabled = mask_enabled AND hasmask; + + CALL + intensity_right( + *(pFactorsRight), + coef_per_win, + sfb_per_win, + wins_in_group, + band_length, + codebook, + mask_enabled, + &(q_formatLeft[tot_sfb]), + &(q_formatRight[tot_sfb]), + &(pCoefLeft[band_start]), + &(pCoefRight[band_start])); + + MODIFYING + pCoefRightt[band_start] + q_formatRight[tot_sfb] + RETURNING + NONE + + ENDIF + + band_start = band_stop; + + tot_sfb = tot_sfb + 1; + + ENDFOR + + coef_per_win = coef_per_win * (wins_in_group); + + wins_in_group = wins_in_group - 1; + + tot_sfb = tot_sfb + sfb_per_win * wins_in_group; + pFactorsRight = pFactorsRight + sfb_per_win * wins_in_group; + pFactorsLeft = pFactorsLeft + sfb_per_win * wins_in_group; + + pCoefRight = pCoefRight + coef_per_win; + pCoefLeft = pCoefLeft + coef_per_win; + + window_start = partition; + + WHILE (partition < pFrameInfo->num_win); + + return; + +------------------------------------------------------------------------------ + RESOURCES USED + When the code is written for a specific target processor the + resources used should be documented below. + + STACK USAGE: [stack count for this module] + [variable to represent + stack usage for each subroutine called] + + where: [stack usage variable] = stack usage for [subroutine + name] (see [filename].ext) + + DATA MEMORY USED: x words + + PROGRAM MEMORY USED: x words + + CLOCK CYCLES: [cycle count equation for this module] + [variable + used to represent cycle count for each subroutine + called] + + where: [cycle count variable] = cycle count for [subroutine + name] (see [filename].ext) + +------------------------------------------------------------------------------ +*/ + + +/*---------------------------------------------------------------------------- +; INCLUDES +----------------------------------------------------------------------------*/ +#include "pv_audio_type_defs.h" +#include "pns_intensity_right.h" +#include "e_huffmanconst.h" +#include "gen_rand_vector.h" +#include "intensity_right.h" +#include "pns_corr.h" + +/*---------------------------------------------------------------------------- +; MACROS +; Define module specific macros here +----------------------------------------------------------------------------*/ + +/*---------------------------------------------------------------------------- +; DEFINES +; Include all pre-processor statements here. Include conditional +; compile variables also. +----------------------------------------------------------------------------*/ + +/*---------------------------------------------------------------------------- +; LOCAL FUNCTION DEFINITIONS +; Function Prototype declaration +----------------------------------------------------------------------------*/ + +/*---------------------------------------------------------------------------- +; LOCAL STORE/BUFFER/POINTER DEFINITIONS +; Variable declaration - defined here and used outside this module +----------------------------------------------------------------------------*/ + +/*---------------------------------------------------------------------------- +; EXTERNAL FUNCTION REFERENCES +; Declare functions defined elsewhere and referenced in this module +----------------------------------------------------------------------------*/ + + +/*---------------------------------------------------------------------------- +; EXTERNAL GLOBAL STORE/BUFFER/POINTER REFERENCES +; Declare variables used in this module but defined elsewhere +----------------------------------------------------------------------------*/ + +/*---------------------------------------------------------------------------- +; FUNCTION CODE +----------------------------------------------------------------------------*/ + +void pns_intensity_right( + const Int hasmask, + const FrameInfo * const pFrameInfo, + const Int group[], + const Bool mask_map[], + const Int codebook_map[], + const Int factorsL[], + const Int factorsR[], + Int sfb_prediction_used[], + const Bool ltp_data_present, + Int32 coefLeft[], + Int32 coefRight[], + Int q_formatLeft[MAXBANDS], + Int q_formatRight[MAXBANDS], + Int32 * const pCurrentSeed) +{ + + Int32 *pCoefRight; + Int32 *pWindow_CoefR; + + Int32 *pCoefLeft; + + Int tot_sfb; + Int start_indx; + Int sfb; + + Int band_length; + Int band_start; + Int band_stop; + Int coef_per_win; + + Int codebook; + Int partition; + Int window_start; + + Int sfb_per_win; + Int wins_in_group; + Int win_indx; + + const Int16 *pBand; + const Int *pFactorsLeft = factorsL; + const Int *pFactorsRight = factorsR; + const Int *pCodebookMap = codebook_map; + const Int *pGroup = group; + const Bool *pMaskMap = mask_map; + + Bool mask_enabled; + + pCoefRight = coefRight; + pCoefLeft = coefLeft; + + window_start = 0; + tot_sfb = 0; + start_indx = 0; + + /* + * Each window in the frame should have the same number of coef's, + * so coef_per_win is constant in all the loops + */ + coef_per_win = pFrameInfo->coef_per_win[0]; + + /* + * Because the number of scalefactor bands per window should be + * constant for each frame, sfb_per_win can be determined outside + * of the loop. + * + * For 44.1 kHz sampling rate sfb_per_win = 14 for short windows + * sfb_per_win = 49 for long windows + */ + + sfb_per_win = pFrameInfo->sfb_per_win[0]; + + do + { + pBand = pFrameInfo->win_sfb_top[window_start]; + + /*---------------------------------------------------------- + Partition is equal to the first window in the next group + + { Group 0 }{ Group 1 }{ Group 2 }{Group 3} + [win 0][win 1][win 2][win 3][win 4][win 5][win 6][win 7] + + pGroup[0] = 2 + pGroup[1] = 5 + pGroup[2] = 7 + pGroup[3] = 8 + -----------------------------------------------------------*/ + partition = *(pGroup++); + + band_start = 0; + + wins_in_group = (partition - window_start); + + for (sfb = sfb_per_win; sfb > 0; sfb--) + { + /* band is offset table, band_stop is last coef in band */ + band_stop = *(pBand++); + + codebook = *(pCodebookMap++); + + mask_enabled = *(pMaskMap++); + + /* + * When a tool utilizing sfb is found, apply the correct tool + * to that sfb in each window in the group + * + * Example... sfb[3] == NOISE_HCB + * + * [ Group 1 ] + * [win 0 ][win 1 ] + * [0][1][2][X][4][5][6][7][0][1][2][X][4][5][6][7] + * + * The for(sfb) steps through the sfb's 0-7 in win 0. + * + * Finding sfb[3]'s codebook == NOISE_HCB, the code + * steps through all the windows in the group (they share + * the same scalefactors) and replaces that sfb with noise. + */ + + /* + * Experimental results suggest that ms_synt is the most + * commonly used tool, so check for it first. + * + */ + + band_length = band_stop - band_start; + + if (codebook == NOISE_HCB) + { + sfb_prediction_used[tot_sfb] &= ltp_data_present; + + if (sfb_prediction_used[tot_sfb] == FALSE) + { + /* + * The branch and the logical AND interact in the + * following manner... + * + * mask_enabled == 0 hasmask == X -- gen_rand_vector + * mask_enabled == 1 hasmask == 1 -- pns_corr + * mask_enabled == 0 hasmask == 1 -- gen_rand_vector + * mask_enabled == 1 hasmask == 2 -- gen_rand_vector + * mask_enabled == 0 hasmask == 2 -- gen_rand_vector + */ + + mask_enabled &= hasmask; + + if (mask_enabled == FALSE) + { + pWindow_CoefR = &(pCoefRight[band_start]); + + /* + * Step through all the windows in this group, + * replacing this band in each window's + * spectrum with random noise + */ + start_indx = tot_sfb; + + for (win_indx = wins_in_group; + win_indx > 0; + win_indx--) + { + + /* generate random noise */ + q_formatRight[start_indx] = + gen_rand_vector( + pWindow_CoefR, + band_length, + pCurrentSeed, + *(pFactorsRight)); + + pWindow_CoefR += coef_per_win; + + start_indx += sfb_per_win; + } + + } + else + { + pns_corr( + (*(pFactorsRight) - + *(pFactorsLeft)), + coef_per_win, + sfb_per_win, + wins_in_group, + band_length, + q_formatLeft[tot_sfb], + &(q_formatRight[tot_sfb]), + &(pCoefLeft[band_start]), + &(pCoefRight[band_start])); + + } /* if (mask_map == FALSE) */ + + } /* if (sfb_prediction_used[tot_sfb] == FALSE) */ + + } /* if (codebook == 0) */ + else if (codebook >= INTENSITY_HCB2) + { + /* + * The logical AND flags the inversion of intensity + * in the following manner. + * + * mask_enabled == X hasmask == 0 -- DO NOT INVERT + * mask_enabled == 0 hasmask == X -- DO NOT INVERT + * mask_enabled == 1 hasmask == 1 -- DO INVERT + * mask_enabled == 0 hasmask == 1 -- DO NOT INVERT + * mask_enabled == 1 hasmask == 2 -- DO NOT INVERT + * mask_enabled == 0 hasmask == 2 -- DO NOT INVERT + */ + + mask_enabled &= hasmask; + + intensity_right( + *(pFactorsRight), + coef_per_win, + sfb_per_win, + wins_in_group, + band_length, + codebook, + mask_enabled, + &(q_formatLeft[tot_sfb]), + &(q_formatRight[tot_sfb]), + &(pCoefLeft[band_start]), + &(pCoefRight[band_start])); + + } /* END else codebook must be INTENSITY_HCB or ... */ + + band_start = band_stop; + + tot_sfb++; + + pFactorsLeft++; + pFactorsRight++; + + } /* for (sfb) */ + + /* + * Increment pCoefRight and pCoefLeft by + * coef_per_win * the number of windows + */ + + pCoefRight += coef_per_win * wins_in_group; + pCoefLeft += coef_per_win * wins_in_group--; + + /* + * Increase tot_sfb by sfb_per_win times the number of windows minus 1. + * The minus 1 comes from the fact that tot_sfb is already pointing + * to the first sfb in the 2nd window of the group. + */ + tot_sfb += sfb_per_win * wins_in_group; + + pFactorsRight += sfb_per_win * wins_in_group; + pFactorsLeft += sfb_per_win * wins_in_group; + + window_start = partition; + + } + while (partition < pFrameInfo->num_win); + + /* pFrameInfo->num_win = 1 for long windows, 8 for short_windows */ + + return; + +} /* pns_intensity_right() */ + + |