| /* ------------------------------------------------------------------ |
| * 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: ./src/fwd_short_complex_rot.c |
| Funtions: fwd_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*FWD_SHORT_CX_ROT_LENGTH elements), with freq. 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*FWD_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 |
| |
| fwd_short_complex_rot() performs the complex rotation for the MDCT |
| for the case of short windows. It performs digit reverse ordering as well |
| word normalization to ensure 16 by 16 bit multiplications. |
| |
| ------------------------------------------------------------------------------ |
| REQUIREMENTS |
| |
| fwd_short_complex_rot() should execute a pre-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 "fwd_short_complex_rot.h" |
| #include "digit_reversal_tables.h" |
| #include "imdct_fxp.h" |
| #include "pv_normalize.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 fwd_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 cos_n; |
| Int32 sin_n; |
| Int32 temp_re_32; |
| Int32 temp_im_32; |
| |
| Int32 *pData_in_ref; |
| |
| Int32 *pData_out_1; |
| Int32 *pData_out_2; |
| Int32 *pData_out_3; |
| Int32 *pData_out_4; |
| |
| pTable = digit_reverse_64; |
| p_rotate = exp_rotation_N_256; |
| |
| pData_in_ref = Data_in; |
| |
| exp = 16 - pv_normalize(max); |
| |
| if (exp < 0) |
| { |
| exp = 0; |
| } |
| |
| pData_out_1 = Data_out; |
| pData_out_2 = &Data_out[TWICE_FWD_SHORT_CX_ROT_LENGTH_m_1]; |
| pData_out_3 = &Data_out[TWICE_FWD_SHORT_CX_ROT_LENGTH]; |
| pData_out_4 = &Data_out[FOUR_FWD_SHORT_CX_ROT_LENGTH_m_1]; |
| |
| /* |
| * Data_out |
| * >>>> <<<< |
| * pData_out_3 pData_out_4 |
| * | | | | | |
| * pData_out_1 pData_out_2 |
| * >>>> <<<< |
| */ |
| |
| |
| for (i = FWD_SHORT_CX_ROT_LENGTH; i != 0; i--) |
| { |
| /* |
| * Perform digit reversal by accessing index I from table |
| */ |
| |
| I = *pTable++; |
| pData_in_1 = pData_in_ref + I; |
| |
| /* |
| * cos_n + j*sin_n == exp(j(2pi/N)(k+1/8)) |
| */ |
| |
| sin_n = *p_rotate++; |
| cos_n = sin_n >> 16; |
| sin_n = sin_n & 0xFFFF; |
| |
| /* |
| * Use auxiliary variables to avoid double accesses to memory. |
| * Data in is scaled to use only lower 16 bits. |
| */ |
| |
| temp_re = *(pData_in_1++) >> exp; |
| temp_im = *(pData_in_1) >> exp; |
| |
| /* |
| * Pre-rotation |
| */ |
| |
| temp_re_32 = (temp_re * cos_n + temp_im * sin_n) >> 16; |
| temp_im_32 = (temp_im * cos_n - temp_re * sin_n) >> 16; |
| |
| *(pData_out_1++) = - temp_re_32; |
| *(pData_out_2--) = temp_im_32; |
| *(pData_out_3++) = - temp_im_32; |
| *(pData_out_4--) = temp_re_32; |
| |
| /* |
| * Pointer increment to jump over imag (1 & 4) or real parts |
| * (2 & 3) |
| */ |
| |
| pData_out_1++; |
| pData_out_2--; |
| pData_out_3++; |
| pData_out_4--; |
| |
| } /* for(i) */ |
| |
| return (exp); |
| } |