diff options
Diffstat (limited to 'media/libstagefright/codecs/aacdec/apply_tns.cpp')
-rw-r--r-- | media/libstagefright/codecs/aacdec/apply_tns.cpp | 424 |
1 files changed, 424 insertions, 0 deletions
diff --git a/media/libstagefright/codecs/aacdec/apply_tns.cpp b/media/libstagefright/codecs/aacdec/apply_tns.cpp new file mode 100644 index 0000000..96ecd27 --- /dev/null +++ b/media/libstagefright/codecs/aacdec/apply_tns.cpp @@ -0,0 +1,424 @@ +/* ------------------------------------------------------------------ + * 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: apply_tns.c + +------------------------------------------------------------------------------ + INPUT AND OUTPUT DEFINITIONS + + Inputs: + coef = Array of input coefficients. + [Int32 *, length 1024] + + q_format = Array of q-formats, one per scalefactor band, for the + entire frame. In the case of tns_inv_filter, only the + first element is used, since the input to tns_inv_filter + is all of the same q-format. + [Int * const, length MAX_SFB] + + pFrameInfo = Pointer to structure that holds information about each group. + (long block flag, number of windows, scalefactor bands + per group, etc.) + [const FrameInfo * const] + + pTNS_frame_info = pointer to structure containing the details on each + TNS filter (order, filter coefficients, + coefficient res., etc.) + [TNS_frame_info * const] + + inverse_flag = TRUE if inverse filter is to be applied. + FALSE if forward filter is to be applied. + [Bool] + + scratch_Int_buffer = Pointer to scratch memory to store the + filter's state memory. Used by both + tns_inv_filter. + [Int *, length TNS_MAX_ORDER] + + Local Stores/Buffers/Pointers Needed: + None + + Global Stores/Buffers/Pointers Needed: + None + + Outputs: + None + + Pointers and Buffers Modified: + coef[] = TNS altered data. + q_format = q-formats in TNS scalefactor bands may be modified. + + Local Stores Modified: + None + + Global Stores Modified: + None + +------------------------------------------------------------------------------ + FUNCTION DESCRIPTION + + This function applies either the TNS forward or TNS inverse filter, based + on inverse_flag being FALSE or TRUE, respectively. + + For the TNS forward filter, the data fed into tns_ar_filter is normalized + all to the same q-format. + +------------------------------------------------------------------------------ + REQUIREMENTS + + The input, coef, should use all 32-bits, else the scaling by tns_ar_filter + may eliminate the data. + +------------------------------------------------------------------------------ + REFERENCES + + (1) ISO/IEC 14496-3:1999(E) + Part 3 + Subpart 4.6.8 (Temporal Noise Shaping) + +------------------------------------------------------------------------------ + PSEUDO-CODE + + NO PSEUDO-CODE + +------------------------------------------------------------------------------ + 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 "s_tns_frame_info.h" +#include "s_tnsfilt.h" +#include "s_frameinfo.h" +#include "tns_inv_filter.h" +#include "tns_ar_filter.h" +#include "apply_tns.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 apply_tns( + Int32 coef[], + Int q_format[], + const FrameInfo * const pFrameInfo, + TNS_frame_info * const pTNS_frame_info, + const Bool inverse_flag, + Int32 scratch_Int_buffer[]) +{ + Int num_tns_bands; + Int num_TNS_coef; + + Int f; + + Int tempInt; + Int tempInt2; + + Int sfb_per_win; + Int sfbWidth; + + Int coef_per_win; + Int min_q; + Int win; + + Int32 *pCoef = coef; + Int32 *pTempCoef; + + Int *pStartQformat = q_format; + + Int *pQformat; + Int32 *pLpcCoef; + + Int sfb_offset; + + const Int16 *pWinSfbTop; + + TNSfilt *pFilt; + + coef_per_win = pFrameInfo->coef_per_win[0]; + sfb_per_win = pFrameInfo->sfb_per_win[0]; + + win = 0; + + pLpcCoef = pTNS_frame_info->lpc_coef; + + pFilt = pTNS_frame_info->filt; + + do + { + for (f = pTNS_frame_info->n_filt[win]; f > 0; f--) + { + /* Skip to the next filter if the order is 0 */ + tempInt = pFilt->order; + + if (tempInt > 0) + { + /* + * Do not call tns_ar_filter or tns_inv_filter + * if the difference + * between start_coef and stop_stop is <= 0. + * + */ + num_TNS_coef = (pFilt->stop_coef - pFilt->start_coef); + + if (num_TNS_coef > 0) + { + if (inverse_flag != FALSE) + { + tns_inv_filter( + &(pCoef[pFilt->start_coef]), + num_TNS_coef, + pFilt->direction, + pLpcCoef, + pFilt->q_lpc, + pFilt->order, + scratch_Int_buffer); + } + else + { + num_tns_bands = (pFilt->stop_band - pFilt->start_band); + + /* + * pQformat is initialized only once. + * + * Here is how TNS is applied on scalefactor bands + * + * [0][1][2][3][4][5][6][7][8] + * | \ + * start_band stop_band + * + * In this example, TNS would be applied to 8 + * scalefactor bands, 0-7. + * + * pQformat is initially set to &(pStartQformat[8]) + * + * 1st LOOP + * Entry: pQformat = &(pStartQformat[8]) + * + * pQformat is pre-decremented 8 times in the + * search for min_q + * + * Exit: pQformat = &(pStartQformat[0]) + * + * 2nd LOOP + * Entry: pQformat = &(pStartQformat[0]) + * + * pQformat is post-incremented 8 times in the + * normalization of the data loop. + * + * Exit: pQformat = &(pStartQformat[8] + * + * + * shift_amt = tns_ar_filter(...) + * + * 3rd LOOP + * Entry: pQformat = &(pStartQformat[8]) + * + * pQformat is pre-decremented 8 times in the + * adjustment of the q-format to min_q - shift_amt + * + * Exit: pQformat = &(pStartQformat[0]) + * + */ + + pQformat = + &(pStartQformat[pFilt->stop_band]); + + /* + * Scan the array of q-formats and find the minimum over + * the range where the filter is to be applied. + * + * At the end of this scan, + * pQformat = &(q-format[pFilt->start_band]); + * + */ + + min_q = INT16_MAX; + + for (tempInt = num_tns_bands; tempInt > 0; tempInt--) + { + tempInt2 = *(--pQformat); + + if (tempInt2 < min_q) + { + min_q = tempInt2; + } + } /* for(tempInt = num_bands; tempInt > 0; tempInt--)*/ + + /* + * Set up the pointers so we can index into coef[] + * on a scalefactor band basis. + */ + tempInt = pFilt->start_band; + + tempInt--; + + /* Initialize sfb_offset and pWinSfbTop */ + if (tempInt >= 0) + { + pWinSfbTop = + &(pFrameInfo->win_sfb_top[win][tempInt]); + + sfb_offset = *(pWinSfbTop++); + } + else + { + pWinSfbTop = pFrameInfo->win_sfb_top[win]; + sfb_offset = 0; + } + + pTempCoef = pCoef + pFilt->start_coef; + + /* Scale the data in the TNS bands to min_q q-format */ + for (tempInt = num_tns_bands; tempInt > 0; tempInt--) + { + sfbWidth = *(pWinSfbTop++) - sfb_offset; + + sfb_offset += sfbWidth; + + tempInt2 = *(pQformat++) - min_q; + + /* + * This should zero out the data in one scalefactor + * band if it is so much less than the neighboring + * scalefactor bands. + * + * The only way this "should" happen is if one + * scalefactor band contains zero data. + * + * Zero data can be of any q-format, but we always + * set it very high to avoid the zero-data band being + * picked as the one to normalize to in the scan for + * min_q. + * + */ + if (tempInt2 > 31) + { + tempInt2 = 31; + } + + for (sfbWidth >>= 2; sfbWidth > 0; sfbWidth--) + { + *(pTempCoef++) >>= tempInt2; + *(pTempCoef++) >>= tempInt2; + *(pTempCoef++) >>= tempInt2; + *(pTempCoef++) >>= tempInt2; + } + + } /* for(tempInt = num_bands; tempInt > 0; tempInt--)*/ + + tempInt2 = + tns_ar_filter( + &(pCoef[pFilt->start_coef]), + num_TNS_coef, + pFilt->direction, + pLpcCoef, + pFilt->q_lpc, + pFilt->order); + + /* + * Update the q-format for all the scalefactor bands + * taking into account the adjustment caused by + * tns_ar_filter + */ + + min_q -= tempInt2; + + for (tempInt = num_tns_bands; tempInt > 0; tempInt--) + { + *(--pQformat) = min_q; + } + + } /* if (inverse_flag != FALSE) */ + + } /* if (num_TNS_coef > 0) */ + + pLpcCoef += pFilt->order; + + } /* if (tempInt > 0) */ + + pFilt++; + + } /* for (f = pTNSinfo->n_filt; f > 0; f--) */ + + pCoef += coef_per_win; + pStartQformat += sfb_per_win; + + win++; + + } + while (win < pFrameInfo->num_win); + + return; + +} /* apply_tns() */ |