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 | f44de515d3b6098a0b585865c1a0c7b20d3075a6 (patch) | |
tree | 028b1d81643bbb332464b42b50a0f79ba5359142 /media/libstagefright/codecs/aacdec/inv_short_complex_rot.cpp | |
parent | bf697e37550d9e8376089b0b5e498613bede798c (diff) | |
download | frameworks_av-f44de515d3b6098a0b585865c1a0c7b20d3075a6.zip frameworks_av-f44de515d3b6098a0b585865c1a0c7b20d3075a6.tar.gz frameworks_av-f44de515d3b6098a0b585865c1a0c7b20d3075a6.tar.bz2 |
Initial check in of stagefright software AAC decoder based on PV source code.
Diffstat (limited to 'media/libstagefright/codecs/aacdec/inv_short_complex_rot.cpp')
-rw-r--r-- | media/libstagefright/codecs/aacdec/inv_short_complex_rot.cpp | 305 |
1 files changed, 305 insertions, 0 deletions
diff --git a/media/libstagefright/codecs/aacdec/inv_short_complex_rot.cpp b/media/libstagefright/codecs/aacdec/inv_short_complex_rot.cpp new file mode 100644 index 0000000..5b4f1c5 --- /dev/null +++ b/media/libstagefright/codecs/aacdec/inv_short_complex_rot.cpp @@ -0,0 +1,305 @@ +/* ------------------------------------------------------------------ + * 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: inv_short_complex_rot.c + Funtions: inv_short_complex_rot + +------------------------------------------------------------------------------ + REVISION HISTORY + + Date: 10/18/2002 + Description: + (1) Change the input argument, only a single max is passed. + (2) Eliminate search for max, a fixed shift has replaced the + search for max with minimal loss of precision. + (3) Eliminated unused variables + + Date: 10/28/2002 + Description: + (1) Added comments per code review + (2) Eliminated hardly used condition on if-else (exp==0) + + Description: + + ------------------------------------------------------------------------------ + INPUT AND OUTPUT DEFINITIONS + + Inputs: + + Data_in = Input vector (sized for short windows + 2*INV_SHORT_CX_ROT_LENGTH elements), with time domain samples + type Int32 * + + Data_out = Output vector with a post-rotation by exp(j(2pi/N)(k+1/8)), + (sized for short windows 2*INV_SHORT_CX_ROT_LENGTH) + type Int32 * + + max = Input, carries the maximum value of the input vector + "Data_in" + type Int32 + + + Local Stores/Buffers/Pointers Needed: + None + + Global Stores/Buffers/Pointers Needed: + None + + Outputs: + exp = shift factor to reflect signal scaling + + Pointers and Buffers Modified: + Results are return in "Data_out" + + Local Stores Modified: + None + + Global Stores Modified: + None +------------------------------------------------------------------------------ + FUNCTION DESCRIPTION + + inv_short_complex_rot() performs the complex rotation for the inverse MDCT + for the case of short windows. It performs digit reverse ordering as well + word normalization to ensure 16 by 16 bit multiplications. + +------------------------------------------------------------------------------ + REQUIREMENTS + + inv_short_complex_rot() should execute a post-rotation by + exp( j(2pi/N)(k+1/8)), digit reverse ordering and word normalization + +------------------------------------------------------------------------------ + REFERENCES + +------------------------------------------------------------------------------ + RESOURCES USED + When the code is written for a specific target processor the + 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 "digit_reversal_tables.h" +#include "imdct_fxp.h" +#include "inv_short_complex_rot.h" +#include "pv_normalize.h" +#include "fxp_mul32.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 VARIABLE DEFINITIONS +; Variable declaration - defined here and used outside this module +----------------------------------------------------------------------------*/ + +/*---------------------------------------------------------------------------- +; EXTERNAL FUNCTION REFERENCES +; Declare functions defined elsewhere and referenced in this module +----------------------------------------------------------------------------*/ + +/*---------------------------------------------------------------------------- +; EXTERNAL VARIABLES REFERENCES +; Declare variables used in this module but defined elsewhere +----------------------------------------------------------------------------*/ + + +Int inv_short_complex_rot( + Int32 *Data_in, + Int32 *Data_out, + Int32 max) + +{ + Int i; + Int16 I; + const Int16 *pTable; + const Int32 *p_rotate; + + Int32 *pData_in_1; + Int exp; + Int32 temp_re; + Int32 temp_im; + + Int32 exp_jw; + Int16 *pData_re; + Int16 *pData_im; + Int32 *pData_in_ref; + + Int16 temp_re_0; + Int16 temp_im_0; + Int16 temp_re_1; + Int16 temp_im_1; + Int16 *p_data_1; + Int16 *p_data_2; + Int16 *p_Data_Int_precision; + Int16 *p_Data_Int_precision_1; + Int16 *p_Data_Int_precision_2; + + Int n = 256; + Int n_2 = n >> 1; + Int n_4 = n >> 2; + Int n_8 = n >> 3; + Int n_3_4 = n_2 + n_4; + + + p_data_1 = (Int16 *)Data_out; + p_data_1 += n; + pData_re = p_data_1; + pData_im = p_data_1 + n_4; + + + p_rotate = exp_rotation_N_256; + pTable = digit_reverse_64; + + pData_in_ref = Data_in; + + exp = 16 - pv_normalize(max); + + + if (exp < 0) + { + exp = 0; + } + + exp -= 1; + + for (i = INV_SHORT_CX_ROT_LENGTH; i != 0; i--) + { + + /* + * cos_n + j*sin_n == exp(j(2pi/N)(k+1/8)) + */ + + /* + * Perform digit reversal by accessing index I from table + */ + + I = *pTable++; + pData_in_1 = pData_in_ref + I; + /* + * Use auxiliary variables to avoid double accesses to memory. + * Data in is scaled to use only lower 16 bits. + */ + + temp_im = *(pData_in_1++); + temp_re = *(pData_in_1); + + exp_jw = *p_rotate++; + + /* + * Post-rotation + */ + + *(pData_re++) = (Int16)(cmplx_mul32_by_16(temp_re, -temp_im, exp_jw) >> exp); + *(pData_im++) = (Int16)(cmplx_mul32_by_16(temp_im, temp_re, exp_jw) >> exp); + } + + + p_data_2 = pData_im - 1; + + + p_Data_Int_precision = (Int16 *)Data_out; + p_Data_Int_precision_1 = p_Data_Int_precision + n_3_4 - 1; + p_Data_Int_precision_2 = p_Data_Int_precision + n_3_4; + + for (i = n_8 >> 1; i != 0; i--) + { + temp_re_0 = (*(p_data_1++)); + temp_re_1 = (*(p_data_1++)); + temp_im_0 = (*(p_data_2--)); + temp_im_1 = (*(p_data_2--)); + + *(p_Data_Int_precision_1--) = temp_re_0; + *(p_Data_Int_precision_1--) = temp_im_0; + *(p_Data_Int_precision_1--) = temp_re_1; + *(p_Data_Int_precision_1--) = temp_im_1; + + *(p_Data_Int_precision_2++) = temp_re_0; + *(p_Data_Int_precision_2++) = temp_im_0; + *(p_Data_Int_precision_2++) = temp_re_1; + *(p_Data_Int_precision_2++) = temp_im_1; + + } + + + /* + * loop is split to avoid conditional testing inside loop + */ + + p_Data_Int_precision_2 = p_Data_Int_precision; + + for (i = n_8 >> 1; i != 0; i--) + { + + temp_re_0 = (*(p_data_1++)); + temp_re_1 = (*(p_data_1++)); + temp_im_0 = (*(p_data_2--)); + temp_im_1 = (*(p_data_2--)); + + *(p_Data_Int_precision_1--) = temp_re_0; + *(p_Data_Int_precision_1--) = temp_im_0; + *(p_Data_Int_precision_1--) = temp_re_1; + *(p_Data_Int_precision_1--) = temp_im_1; + + *(p_Data_Int_precision_2++) = (Int16)(-temp_re_0); + *(p_Data_Int_precision_2++) = (Int16)(-temp_im_0); + *(p_Data_Int_precision_2++) = (Int16)(-temp_re_1); + *(p_Data_Int_precision_2++) = (Int16)(-temp_im_1); + + } + + return (exp + 1); +} |