diff options
author | Andreas Huber <andih@google.com> | 2009-12-07 09:56:32 -0800 |
---|---|---|
committer | Andreas Huber <andih@google.com> | 2009-12-07 11:02:28 -0800 |
commit | dacaa73ae5010b66f4224d70a520945e5b653544 (patch) | |
tree | a2c9e71b6337dd25d149bd5fa43f7a782e9387fb /media/libstagefright/codecs/aacdec/get_tns.cpp | |
parent | 5921fb51e0219ddd7cad439a73495f320c57d50e (diff) | |
download | frameworks_base-dacaa73ae5010b66f4224d70a520945e5b653544.zip frameworks_base-dacaa73ae5010b66f4224d70a520945e5b653544.tar.gz frameworks_base-dacaa73ae5010b66f4224d70a520945e5b653544.tar.bz2 |
Initial check in of stagefright software AAC decoder based on PV source code.
Diffstat (limited to 'media/libstagefright/codecs/aacdec/get_tns.cpp')
-rw-r--r-- | media/libstagefright/codecs/aacdec/get_tns.cpp | 573 |
1 files changed, 573 insertions, 0 deletions
diff --git a/media/libstagefright/codecs/aacdec/get_tns.cpp b/media/libstagefright/codecs/aacdec/get_tns.cpp new file mode 100644 index 0000000..e0b021b --- /dev/null +++ b/media/libstagefright/codecs/aacdec/get_tns.cpp @@ -0,0 +1,573 @@ +/* ------------------------------------------------------------------ + * 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: get_tns.c + + Date: 10/25/2000 + +------------------------------------------------------------------------------ + REVISION HISTORY + + Description: Modified from original shareware code + + Description: Modified to pass variables by reference to eliminate use + of global variables. + + Description: Brought code in-line with PV standards. Some minor + optimizations (count-down for loops, etc.) were made. + + Description: Made cosmetic changes as suggested during review. Also, + changed calculation of s_mask and n_mask from table-based to being + calculated based on res_index. Also, the flag coef_res was changed + from having a range of [3,4] to having a range of [0,1], which corresponds + exactly with the true value that is passed via the bitstream. + + Description: Modified to use more efficient TNS memory structure. + + Description: Updated to reflect more efficient usage of memory by the TNS + filters. + + Description: Updated the SW template to include the full pathname to the + source file and a slightly modified copyright header. + + Description: Moved pInputStream to be the 2nd parameter, for a slight + optimization on some platforms. + + Description: Moved pSfbTop outside of the loops, since its value does + not change. + + Description: Replace some instances of getbits to get1bits + when only 1 bit is read. + + Who: Date: + Description: + +------------------------------------------------------------------------------ + INPUT AND OUTPUT DEFINITIONS + + Inputs: + FrameInfo *pFrameInfo + Pointer to structure that holds information about each block. + (long block flag, + number of subblocks, + scalefactor bands per subblock, etc.) + + BITS *pInputStream + Pointer to a BITS structure that is + passed on to function getbits to pull information from the bitstream. + + TNS_Frame_info *pTnsFrameInfo + Pointer to filter data structure - to be populated by this function. + + Local Stores/Buffers/Pointers Needed: + None + + Global Stores/Buffers/Pointers Needed: + None + + Outputs: + None + + Pointers and Buffers Modified: + TNS_frame_info *pTnsFrameInfo + + pTnsFrameInfo->n_filt = Number of tns filters to be applied to the data. + + pTnsFrameInfo->filt[]->order = The order of each individual TNS filter. + + pTnsFrameInfo->filt[]->coef_res = The resolution of the filter coefficients + + pTnsFrameInfo->filt[]->start_band = start of spectral band + + pTnsFrameInfo->filt[]->stop_band = end of spectral band + + pTnsFrameInfo->filt[]->coef[] = Each filter's coefficients are filled with + data read from the input bitstream. + + pTnsFrameInfo->filt[]->direction = A flag is set for each TNS filter. + + If the direction flag (on the bitstream) = 0, then the filter + is applied to the block of spectral data in normal (upward) fashion. + + If the direction flag (on the bitstream) = 1, then the filter + is applied in a reverse (downward) fashion. + (Starting with the last element in the block of data.) + + The value stored in filt[]->direction maps the values [0,1] to [1,-1] for + a more intuitive storage of this flag's meaning. + + Local Stores Modified: + + Global Stores Modified: + + +------------------------------------------------------------------------------ + FUNCTION DESCRIPTION + + This function reads the TNS filter information from the bitstream, and stores + the filter order, LPC coefficients, and the number of TNS filters to + be applied in the structure TNS_frame_info. + +------------------------------------------------------------------------------ + REQUIREMENTS + + This code should match the ISO code in functionality, with the exception + that coef_res has range of [0,1] (PV code) instead of [3,4] (ISO code) + + coef_res is only used by tns_decode_coef. + +------------------------------------------------------------------------------ + REFERENCES + (1) ISO/IEC 14496-3:1999(E) + Part 3 + Subpart 4.6.8 (Temporal Noise Shaping) + + (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 + + +------------------------------------------------------------------------------ + 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 "get_tns.h" +#include "s_mc_info.h" +#include "s_frameinfo.h" +#include "s_tnsfilt.h" +#include "s_tns_frame_info.h" +#include "s_bits.h" +#include "ibstream.h" +#include "e_window_sequence.h" +#include "e_progconfigconst.h" + +#include "tns_decode_coef.h" + + +/*---------------------------------------------------------------------------- +; MACROS +; Define module specific macros here +----------------------------------------------------------------------------*/ +#define SCALE_FACTOR_BAND_OFFSET(x) ( ((x) > 0) ? pSFB_top[(x)-1] : 0 ) +#define MINIMUM(x,y) ( ((x) < (y)) ? (x) : (y) ) + +/*---------------------------------------------------------------------------- +; 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 +----------------------------------------------------------------------------*/ +/* + * The entries in the ensuing tables provide the maximum permissable + * number of scalefactor bands for each TNS filter. This value is effected + * by the sampling rate, and window type. + */ + +const Int tns_max_bands_tbl_long_wndw[(1<<LEN_SAMP_IDX)] = + {31, /* 96000 Hz */ + 31, /* 88200 Hz */ + 34, /* 64000 Hz */ + 40, /* 48000 Hz */ + 42, /* 44100 Hz */ + 51, /* 32000 Hz */ + 46, /* 24000 Hz */ + 46, /* 22050 Hz */ + 42, /* 16000 Hz */ + 42, /* 12000 Hz */ + 42, /* 11025 Hz */ + 39, /* 8000 Hz */ + 0, + 0, + 0, + 0 + }; + +const Int tns_max_bands_tbl_short_wndw[(1<<LEN_SAMP_IDX)] = + {9, /* 96000 Hz */ + 9, /* 88200 Hz */ + 10, /* 64000 Hz */ + 14, /* 48000 Hz */ + 14, /* 44100 Hz */ + 14, /* 32000 Hz */ + 14, /* 24000 Hz */ + 14, /* 22050 Hz */ + 14, /* 16000 Hz */ + 14, /* 12000 Hz */ + 14, /* 11025 Hz */ + 14, /* 8000 Hz */ + 0, + 0, + 0, + 0 + }; + +/* + * For completeness, here are the table entries for object types that make + * use of PQF filter bank. We do not currently support this; these are + * given here only to ease future implementation. + * + * const Int tns_max_bands_tbl_long_wndw_PQF[(1<<LEN_SAMP_IDX)] = + * {28, ; 96000 + * 28, ; 88200 + * 27, ; 64000 + * 26, ; 48000 + * 26, ; 44100 + * 26, ; 32000 + * 29, ; 24000 + * 29, ; 22050 + * 23, ; 16000 + * 23, ; 12000 + * 23, ; 11025 + * 19, ; 8000 + * 0, + * 0, + * 0, + * 0}; + * + * const Int tns_max_bands_tbl_short_wndw_PQF[(1<<LEN_SAMP_IDX)] = + * {7, ; 96000 + * 7, ; 88200 + * 7, ; 64000 + * 6, ; 48000 + * 6, ; 44100 + * 6, ; 32000 + * 7, ; 24000 + * 7, ; 22050 + * 8, ; 16000 + * 8, ; 12000 + * 8, ; 11025 + * 7, ; 8000 + * 0, + * 0, + * 0, + * 0}; + */ + +/*---------------------------------------------------------------------------- +; 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 get_tns( + const Int max_bands, + BITS * const pInputStream, + const WINDOW_SEQUENCE wnd_seq, + const FrameInfo * const pFrameInfo, + const MC_Info * const pMC_Info, + TNS_frame_info * const pTnsFrameInfo, + Int32 scratchTnsDecCoefMem[]) +{ + + const Int16 * const pSFB_top = pFrameInfo->win_sfb_top[0]; + + Int f; + Int t; + Int win; + UInt tempInt; + + Int num_filt_bits; + Int num_order_bits; + Int num_start_band_bits; + + Int top; + Int res; + Int res_index; + Int compress; + + Int sfb_per_win; + + Int32 *pLpcCoef; + Int32 *pStartLpcCoef; + Int s_mask; + Int n_mask; + + Int tns_bands; + UInt max_order; + Int coef_res; + + + TNSfilt *pFilt; + + if (wnd_seq != EIGHT_SHORT_SEQUENCE) + { + num_filt_bits = 2; + num_order_bits = 5; + num_start_band_bits = 6; + + tns_bands = tns_max_bands_tbl_long_wndw[pMC_Info->sampling_rate_idx]; + + /* + * Definition from 14496-3:1999 doc. Our first encoder follows this rule, + * later encoders don't + */ + + if (pMC_Info->sampling_rate_idx > 4) /* if (sampling_rate <= 32000 */ + { + max_order = 20; + } + else + { + max_order = 12; + } + } + else + { + num_filt_bits = 1; + num_order_bits = 3; + num_start_band_bits = 4; + + tns_bands = tns_max_bands_tbl_short_wndw[pMC_Info->sampling_rate_idx]; + + max_order = 7; + } + + /* + * After this branch, tns_bands will be equal to the minimum of + * the passed in variable, nbands, and the result from the + * tns_max_bands_tbl + */ + + if (max_bands < tns_bands) + { + tns_bands = max_bands; + } + + sfb_per_win = pFrameInfo->sfb_per_win[0]; + + win = 0; + + pLpcCoef = pTnsFrameInfo->lpc_coef; + + pFilt = pTnsFrameInfo->filt; + + do + { + tempInt = get9_n_lessbits(num_filt_bits, + pInputStream); + + pTnsFrameInfo->n_filt[win] = tempInt; + + if (tempInt != 0) + { + /* + * coef_res = [0, 1] + * Switch between a resolution of 3 and 4 bits respectively + * + * if coef_res = 0, the coefficients have a range of + * + * -4 -3 -2 -1 0 1 2 3 + * + * if coef_res = 1, the coefficients have a range of + * + * -8 -7 -6 -5 -4 -3 -2 -1 0 1 2 3 4 5 6 7 + * + * The arrays in ./src/tns_tab.c are completely based on + * the value of coef_res. + */ + res = get1bits( + pInputStream); + + /* res is post-incremented for correct calculation of res_index */ + coef_res = res++; + + top = sfb_per_win; + + for (f = pTnsFrameInfo->n_filt[win]; f > 0; f--) + { + tempInt = MINIMUM(top, tns_bands); + + pFilt->stop_coef = SCALE_FACTOR_BAND_OFFSET(tempInt); + + pFilt->stop_band = tempInt; + + top -= get9_n_lessbits(num_start_band_bits, + pInputStream); + + tempInt = MINIMUM(top, tns_bands); + + pFilt->start_coef = SCALE_FACTOR_BAND_OFFSET(tempInt); + + pFilt->start_band = tempInt; + + tempInt = get9_n_lessbits(num_order_bits, + pInputStream); + + pFilt->order = tempInt; + + if (tempInt != 0) + { + if (tempInt > max_order) + { + pFilt->order = max_order; + } + + /* + * This maps the bitstream's [0,1] to + * pFilt->direction = [1,-1] + */ + + tempInt = get1bits(pInputStream); + + pFilt->direction = (-(Int)tempInt) | 0x1; + + /* + * compress = [0,1] + * If compress is true, the MSB has + * been omitted from transmission (Ref. 1) + * + * For coef_res = 0, this limits the range of + * transmitted coefficients to... + * + * -2 -1 0 1 + * + * For coef_res = 1, the coefficients have + * a range of... + * + * -4 -3 -2 -1 0 1 2 3 + */ + compress = get1bits(pInputStream); + + /* + * res has a range of [1,2] + * compress has a range of [0,1] + * So (res - compress) has range [0,2]; + */ + res_index = res - compress; + + s_mask = 2 << res_index; + + /* + * If res_index = 0, grab 2 bits of data + * If res_index = 1, grab 3 bits of data + * If res_index = 2, grab 4 bits of data + */ + res_index += 2; + + pStartLpcCoef = pLpcCoef; + + for (t = pFilt->order; t > 0; t--) + { + /* + * These are the encoded coefficients, which will + * later be decoded into LPC coefficients by + * the function tns_decode_coef() + */ + tempInt = get9_n_lessbits(res_index, + pInputStream); + + n_mask = -((Int)tempInt & s_mask); + + /* + * n_mask is used to sign_extend the + * value, if it is negative. + * + */ + *(pLpcCoef++) = tempInt | n_mask; + } + + /* Decode the TNS coefficients */ + + tempInt = pFilt->stop_coef - pFilt->start_coef; + + if (tempInt > 0) + { + pFilt->q_lpc = + tns_decode_coef( + pFilt->order, + coef_res, + pStartLpcCoef, + scratchTnsDecCoefMem); + } + + } /* if (pTnsFilt->order != 0) */ + + pFilt++; + + } /* END for (f=pTnsInfo->n_filt; f>0; f--, pTnsFilt++) */ + + } /* if (pTnsInfo->n_filt != 0) */ + + win++; + + } + while (win < pFrameInfo->num_win); + + return; + +} /* get_tns */ |