| /* ------------------------------------------------------------------ |
| * 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: mix_radix_fft.c |
| Funtions: mix_radix_fft |
| |
| ------------------------------------------------------------------------------ |
| REVISION HISTORY |
| |
| Description: Eliminated pointer dependency ( pData_1) on Buffer address. |
| Modified for-loop to countdown loops. |
| |
| Description: No shift information going in/out from fft_rx4_long. |
| |
| Description: |
| (1) Increased precision on the radix 2 fft coeff. (from Q10 to Q12) |
| (2) Increased precision on the input (from 0.5 to 1.0). |
| (3) Eliminated hardly used condition (exp = 0). |
| (4) Change interface to fft_rx4_long, so now the same function is |
| used for forward and inverse calculations. |
| |
| Description: per code review comments, eliminated unnecessary headers |
| |
| Who: Date: |
| Description: |
| |
| ------------------------------------------------------------------------------ |
| INPUT AND OUTPUT DEFINITIONS |
| |
| Inputs: |
| Data = Input vector, with quantized spectral with a pre-rotation |
| by exp(j(2pi/N)(k+1/8)) |
| type Int32 * |
| |
| peak_value = Input, carries the maximum value in input vector "Data" |
| Output, maximum value computed in the first FFT, used |
| to set precision on next stages |
| type Int32 * |
| |
| |
| Local Stores/Buffers/Pointers Needed: |
| None |
| |
| Global Stores/Buffers/Pointers Needed: |
| None |
| |
| Outputs: |
| exponent = shift factor to reflect signal scaling |
| |
| Pointers and Buffers Modified: |
| Results are return in "Data" |
| |
| Local Stores Modified: |
| None |
| |
| Global Stores Modified: |
| None |
| ------------------------------------------------------------------------------ |
| FUNCTION DESCRIPTION |
| |
| mix_radix_fft() mixes radix-2 and radix-4 FFT. This is needed to be able |
| to use power of 4 length when the input length sequence is a power of 2. |
| ------------------------------------------------------------------------------ |
| REQUIREMENTS |
| |
| mix_radix_fft() should support only the FFT for the long window case of |
| the inverse modified cosine transform (IMDCT) |
| ------------------------------------------------------------------------------ |
| REFERENCES |
| |
| ------------------------------------------------------------------------------ |
| PSEUDO-CODE |
| |
| |
| MODIFY( x[] ) |
| RETURN( exponent ) |
| |
| ------------------------------------------------------------------------------ |
| 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 "fft_rx4.h" |
| #include "mix_radix_fft.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 |
| ----------------------------------------------------------------------------*/ |
| |
| #ifdef __cplusplus |
| extern "C" |
| { |
| #endif |
| |
| void digit_reversal_swapping(Int32 *y, Int32 *x); |
| |
| #ifdef __cplusplus |
| } |
| #endif |
| |
| /*---------------------------------------------------------------------------- |
| ; EXTERNAL VARIABLES REFERENCES |
| ; Declare variables used in this module but defined elsewhere |
| ----------------------------------------------------------------------------*/ |
| |
| /*---------------------------------------------------------------------------- |
| ; EXTERNAL GLOBAL STORE/BUFFER/POINTER REFERENCES |
| ; Declare variables used in this module but defined elsewhere |
| ----------------------------------------------------------------------------*/ |
| |
| /*---------------------------------------------------------------------------- |
| ; FUNCTION CODE |
| ----------------------------------------------------------------------------*/ |
| |
| Int mix_radix_fft( |
| Int32 *Data, |
| Int32 *peak_value |
| ) |
| |
| { |
| |
| const Int32 *p_w; |
| Int32 *pData_1; |
| Int32 *pData_2; |
| |
| Int32 *pData_3; |
| Int32 *pData_4; |
| |
| Int32 exp_jw; |
| Int32 max1; |
| Int32 max2; |
| Int32 temp1; |
| Int32 temp2; |
| Int32 temp3; |
| Int32 temp4; |
| Int32 diff1; |
| Int32 diff2; |
| Int i; |
| Int exp; |
| |
| max1 = *peak_value; |
| p_w = w_512rx2; |
| |
| pData_1 = Data; |
| pData_3 = Data + HALF_FFT_RX4_LENGTH_FOR_LONG; |
| |
| |
| /* |
| * normalization to 0.9999 (0x7FFF) guarantees proper operation |
| */ |
| |
| exp = 8 - pv_normalize(max1); /* use 24 bits for mix radix fft */ |
| |
| if (exp < 4) |
| { |
| exp = 4; |
| } |
| |
| |
| temp1 = (*pData_3); |
| pData_4 = pData_3 + FFT_RX4_LENGTH_FOR_LONG; |
| temp2 = (*pData_4++); |
| |
| |
| |
| diff1 = (temp1 - temp2) >> exp; |
| *pData_3++ = (temp1 + temp2) >> exp; |
| |
| temp3 = (*pData_3); |
| temp4 = (*pData_4); |
| |
| *pData_4-- = -diff1; |
| *pData_3++ = (temp3 + temp4) >> exp; |
| *pData_4 = (temp3 - temp4) >> exp; |
| |
| temp1 = (*pData_1); |
| pData_2 = pData_1 + FFT_RX4_LENGTH_FOR_LONG; |
| temp2 = (*pData_2++); |
| temp4 = (*pData_2); |
| |
| *pData_1++ = (temp1 + temp2) >> exp; |
| |
| temp3 = (*pData_1); |
| diff1 = (temp1 - temp2) >> exp ; |
| |
| *pData_1++ = (temp3 + temp4) >> exp; |
| *pData_2-- = (temp3 - temp4) >> exp; |
| *pData_2 = diff1; |
| |
| temp1 = (*pData_3); |
| pData_4 = pData_3 + FFT_RX4_LENGTH_FOR_LONG; |
| temp2 = (*pData_4++); |
| |
| |
| for (i = ONE_FOURTH_FFT_RX4_LENGTH_FOR_LONG - 1; i != 0; i--) |
| { |
| /* |
| * radix 2 Butterfly |
| */ |
| |
| diff1 = (temp1 - temp2) >> (exp - 4); |
| *pData_3++ = (temp1 + temp2) >> exp; |
| |
| temp3 = (*pData_3); |
| temp4 = (*pData_4); |
| |
| exp_jw = *p_w++; |
| |
| |
| diff2 = (temp3 - temp4) >> (exp - 4); |
| *pData_3++ = (temp3 + temp4) >> exp; |
| |
| *pData_4-- = -cmplx_mul32_by_16(diff1, diff2, exp_jw) >> 3; |
| *pData_4 = cmplx_mul32_by_16(diff2, -diff1, exp_jw) >> 3; |
| |
| |
| temp1 = (*pData_1); |
| pData_2 = pData_1 + FFT_RX4_LENGTH_FOR_LONG; |
| temp2 = (*pData_2++); |
| temp4 = (*pData_2); |
| |
| *pData_1++ = (temp1 + temp2) >> exp; |
| |
| temp3 = (*pData_1); |
| diff1 = (temp1 - temp2) >> (exp - 4); |
| |
| diff2 = (temp3 - temp4) >> (exp - 4); |
| *pData_1++ = (temp3 + temp4) >> exp; |
| |
| *pData_2-- = cmplx_mul32_by_16(diff2, -diff1, exp_jw) >> 3; |
| *pData_2 = cmplx_mul32_by_16(diff1, diff2, exp_jw) >> 3; |
| |
| temp1 = (*pData_3); |
| pData_4 = pData_3 + FFT_RX4_LENGTH_FOR_LONG; |
| temp2 = (*pData_4++); |
| |
| }/* for i */ |
| |
| |
| fft_rx4_long( |
| Data, |
| &max1); |
| |
| |
| fft_rx4_long( |
| &Data[FFT_RX4_LENGTH_FOR_LONG], |
| &max2); |
| |
| digit_reversal_swapping(Data, &Data[FFT_RX4_LENGTH_FOR_LONG]); |
| |
| *peak_value = max1 | max2; |
| |
| return(exp); |
| } |
| |