blob: 6ccc023854dc336d138cec4f4a5b8722216bd68f [file] [log] [blame]
/* ------------------------------------------------------------------
* 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: trans4m_freq_2_time_fxp.c
Function: trans4m_freq_2_time_fxp
------------------------------------------------------------------------------
REVISION HISTORY
Description:
changed to decrement loop
change wnd_shape from structure to passing parameters
modified window tables from UInt to UInt16 to assure proper operation
without dubious typecast
changed logic to hit most common states first.
modified Time_data from Int to Int32 to hold
possible overflow before saturation process.
Description:
Increase processing on some loop by using more pointers
changed interface to avoid passing a pointer for wnd_shape_prev_bk, this
element is not change in this function because of this function use
in the LTP module
Description:
Added rounding to multiplication
Description:
Update input description and eliminate unneeded comments
Description:
LONG_START_WINDOW was using SHORT_WINDOW instead of
HALF_SHORT_WINDOW, causing a for loop to exceed its count
Description:
Modified structure of code so exp is not tested before it
is initialized. Also, new structure avoids double-testing
of exp_freq = ALL_ZEROS_BUFFER.
Description:
The result of a shift is undefined if the right operand is greater than
or equal to the number of bits in the left expression's type
To avoid undefined shift by 32, a check of the shift has been
added, so the function proceeds only when the exponent is less
than 32. By design the shift up is related to the global gain,
and controlled by the encoder, so saturation is not allowed.
In both short and long window, processing is skip if an all zero
input buffer or excessive down shift is detected.
Description:
Changes according to code review comments. Also, modified if-else
structure so the imdct_fxp is not called with an all zero input buffer
Description:
Replaced function buffer_normalization by buffer_adaptation, to ease
use of 16 bits. Function buffer_normalization becomes obsolete.
Description:
Modified call to imdct_fxp to reflect extended precision use. Added
routine buffer_adaptation to extract 16 MSB and keep highest.
precision. Modify casting to ensure proper operations for different
platforms
Description:
Eliminate double access to memory by loading data directly to the
time array. Also reduced cycle count and added precision by combining
downshifting in only one operation. Added adaptive rounding factor.
Change exponent threshold when operations are waived. It is use to be 32
but by combining downshifting, this new threshold is now 16. This may
avoid unneeded calculations for extremely small numbers.
Description:
Per review comments:
- Added comments to clarify buffer_adaptation function
- Deleted reference to include file "buffer_normalization.h"
- Modified IF-ELSE so long_windows case is considered first
- Eliminated extra IF when computing the rounding, so when exp ==0
less cycles are used shifting than in an extra if-else
- Corrected negative shift when computing rounding factor
- Added condition when exp > 16 (for long windows)
Description:
Modified IF-ELSE structure so now ALL_ZEROS_BUFFER condition is share
with exp > 16 condition. This avoid code duplication for both cases.
Description:
- Modified function interface to add output_buffer
- Eliminated the 32 bit version of the current output, calculations
are placed directly in output_buffer. In this way the buffer
Time_data needs only to be 1024 Int32, instead of 2048 (per channel).
Also, added the limit macro inside the function (this reduces access
to memory).
- Updated Pseudo - Code
Description:
Per review comments:
Corrected line sizes and mispelling, added comments and swap
order or switch statement for ONLY_LONG_SEQUENCE.
Description:
Eliminated adaptive rounding due to potential saturation.
Description:
Eliminated use of buffer adaptation by shifting this functionality inside
the imdct_fxp() routine. Also modified the call to imdct_fxp to accomodate
new function interface.
Modified macro limit() to save cycles when testing the most common case:
no saturation.
Description:
Changed new function interface for imdct_fxp().
Description:
Replaced for-loop with memset and memcopy.
Who: Date:
Description:
------------------------------------------------------------------------------
INPUT AND OUTPUT DEFINITIONS
Inputs:
Frequency_data = vector with spectral information, size 2048
type Int32
Time_data = buffer with data from previous Frequency to Time
conversion, used for overlap and add, size 1024
type Int32
Output_buffer = place holder for current output, size 1024
type Int16
wnd_seq = window sequence
type WINDOW_SEQUENCE
wnd_shape_prev_bk = previous window shape type
type Int
wnd_shape_this_bk = current window shape type
type Int
Q_format = Q format for the input frequency data
type Int
freq_2_time_buffer[] = scratch memory for computing FFT
type Int32
Local Stores/Buffers/Pointers Needed:
None
Global Stores/Buffers/Pointers Needed:
None
Outputs:
None
Pointers and Buffers Modified:
Output_buffer
Time_data
Frequency_data
pWnd_shape_prev_bk
Local Stores Modified:
None
Global Stores Modified:
None
------------------------------------------------------------------------------
FUNCTION DESCRIPTION
The time/frequency representation of the signal is mapped onto the time
domain by feeding it into the filterbank module. This module consists of
an inverse modified discrete cosine transform (IMDCT), and a window and an
overlap-add function. In order to adapt the time/frequency resolution of the
filterbank to the characteristics of the input signal, a block switching tool
is also adopted. N represents the window length, where N is a function of the
window_sequence. For each channel, the N/2 time-frequency values are
transformed into the N time domain values via the IMDCT. After applying the
window function, for each channel, the first half of the sequence is added to
the second half of the previous block windowed sequence to reconstruct the
output samples for each channel outi,n.
The adaptation of the time-frequency resolution of the filterbank to the
characteristics of the input signal is done by shifting between transforms
whose input lengths are either 2048 or 256 samples. By enabling the block
switching tool, the following transitions are meaningful:
from ONLY_LONG_SEQUENCE to { LONG_START_SEQUENCE
ONLY_LONG_SEQUENCE
from LONG_START_SEQUENCE to { LONG_STOP_SEQUENCE
EIGHT_SHORT_SEQUENCE
from LONG_STOP_SEQUENCE to { LONG_START_SEQUENCE
ONLY_LONG_SEQUENCE
from EIGHT_SHORT_SEQUENCE to { LONG_STOP_SEQUENCE
EIGHT_SHORT_SEQUENCE
Window shape decisions are made by the encoder on a frame-by-frame-basis.
The window selected is applicable to the second half of the window function
only, since the first half is constrained to use the appropriate window
shape from the preceding frame.
The 2048 time-domain values x'(i)(n), (i window, n sample) to be windowed are
the last 1024 values of the previous window_sequence concatenated with 1024
values of the current block. The formula below shows this fact:
| x(i-1)(n+1024) for 0 < n < 1024
x'(i)(n) {
| x(i)(n) for 1024 < n < 2048
Buffer Time_data data from previous Frequency to Time conversion, used
for overlap and add
Once the window shape is selected, the window_shape syntax element is
initialized. Together with the chosen window_sequence all information needed
for windowing exist.
With the window halves described below all window_sequences can be assembled.
For window_shape == 1, the window coefficients are given by the Kaiser -
Bessel derived (KBD) window.
Otherwise, for window_shape == 0, a sine window is employed.
The window length N can be 2048 or 256 for the KBD and the sine window.
All four window_sequences explained below have a total length of 2048
samples.
For all kinds of window_sequences the window_shape of the left half of
the first transform window is determined by the window shape of the previous
block.
In the case of EIGHT_SHORT_SEQUENCE the processing is done in-place and
in descendent order to avoid using extra memory.
The ordering is as follows:
Pn: Previous data for window n
Cn: Current data for window n
128 freq.
samples
FREQ ++++++
IN ===========================
\
\
-> 256 time
samples
P8 C8
8 #######++++++
P7 C7
7 #######++++++
: :
: :
P2 C2
2 #######++++++
P1 C1
1 #######++++++
TIME
OUT ==============================================================
------------------------------------------------------------------------------
REQUIREMENTS
This module shall implement a scheme to switch between window types
------------------------------------------------------------------------------
REFERENCES
[1] ISO 14496-3:1999, pag 111
------------------------------------------------------------------------------
PSEUDO-CODE
IF ( wnd_seq == EIGHT_SHORT_SEQUENCE)
THEN
FOR ( i=0; i<LONG_WINDOW; i++)
Time_data[LONG_WINDOW + i] = 0;
ENDFOR
FOR ( wnd=NUM_SHORT_WINDOWS-1; wnd>=0; wnd--)
pFreqInfo = &Frequency_data[ wnd*SHORT_WINDOW];
CALL IMDCT( pFreqInfo, SHORT_BLOCK1);
MODIFYING(pFreqInfo)
IF (wnd == 0)
THEN
pShort_Window_1 = &Short_Window[wnd_shape_prev_bk][0];
ELSE
pShort_Window_1 = &Short_Window[wnd_shape_this_bk][0];
ENDIF
pShort_Window_2 =
&Short_Window[wnd_shape->this_bk][SHORT_WINDOW_m_1];
FOR( i=0, j=SHORT_WINDOW; i<SHORT_WINDOW; i++, j--)
pFreqInfo[ i] *= pShort_Window_1[i];
pFreqInfo[SHORT_WINDOW+i] *= pShort_Window_2[j];
ENDFOR
FOR( i=0; i<SHORT_BLOCK1; i++)
Time_data[W_L_STOP_1 + SHORT_WINDOW*wnd + i] += pFreqInfo[i];
ENDFOR
ENDFOR
FOR ( i=0; i<LONG_WINDOW; i++)
temp = Time_data[i];
Output_buffer[i] = Time_data[i];
Time_data[i] = temp;
ENDFOR
ELSE
CALL IMDCT( Frequency_data, LONG_BLOCK1)
MODIFYING(Frequency_data)
SWITCH ( wnd_seq)
CASE ( ONLY_LONG_SEQUENCE)
pLong_Window_1 = &Long_Window[wnd_shape_prev_bk][0];
pLong_Window_2 =
&Long_Window[wnd_shape_this_bk][LONG_WINDOW_m_1];
FOR (i=0; i<LONG_WINDOW; i++)
Frequency_data[ i] *= *pLong_Window_1++;
Frequency_data[LONG_WINDOW+i] *= *pLong_Window_2--;
ENDFOR
BREAK
CASE ( LONG_START_SEQUENCE)
pLong_Window_1 = &Long_Window[wnd_shape_prev_bk][0];
FOR ( i=0; i<LONG_WINDOW; i++)
Frequency_data[ i] *= *pLong_Window_1++;
ENDFOR
pShort_Window_1 =
&Short_Window[wnd_shape_this_bk][SHORT_WINDOW_m_1];
FOR ( i=0; i<SHORT_WINDOW; i++)
Frequency_data[W_L_START_1 + i] *= *pShort_Window_1--;
ENDFOR
FOR ( i=W_L_START_2; i<LONG_BLOCK1; i++)
Frequency_data[W_L_START_2 + i] = 0;
ENDFOR
BREAK
CASE ( LONG_STOP_SEQUENCE )
FOR ( i=0; i<W_L_STOP_1; i++)
Frequency_data[ i] = 0;
ENDFOR
pShort_Window_1 = &Short_Window[wnd_shape_prev_bk][0];
FOR ( i=0; i<SHORT_WINDOW; i++)
Frequency_data[W_L_STOP_1+ i] *= *pShort_Window_1++;
ENDFOR
pLong_Window_1 =
&Long_Window[wnd_shape_this_bk][LONG_WINDOW_m_1];
FOR ( i=0; i<LONG_WINDOW; i++)
Frequency_data[LONG_WINDOW + i] *= *pLong_Window_1--;
ENDFOR
BREAK
}
FOR ( i=0; i<LONG_WINDOW; i++)
Output_buffer[i] = Frequency_data[i] + Time_data[i];
Time_data[i] = Frequency_data[LONG_WINDOW+i];
ENDFOR
}
ENDIF
------------------------------------------------------------------------------
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 "pv_audio_type_defs.h"
#include "aac_mem_funcs.h"
#include "window_block_fxp.h"
#include "imdct_fxp.h"
#include "fxp_mul32.h"
/*----------------------------------------------------------------------------
; MACROS
; limit(x) saturates any number that exceeds a 16-bit representation into a
; 16 bit number.
----------------------------------------------------------------------------*/
#define ROUNDING_SCALED (ROUNDING<<(16 - SCALING))
#if defined(PV_ARM_V5)
__inline Int16 sat(Int32 y)
{
Int32 x;
Int32 z;
__asm
{
mov x, ROUNDING_SCALED
mov y, y, lsl #(15-SCALING)
qdadd z, x, y
mov y, z, lsr #16
}
return((Int16)y);
}
#define limiter( y, x) y = sat(x);
#elif defined(PV_ARM_GCC_V5)
__inline Int16 sat(Int32 y)
{
register Int32 x;
register Int32 ra = (Int32)y;
register Int32 z = ROUNDING_SCALED;
asm volatile(
"mov %0, %1, lsl #5\n\t" // (15-SCALING) assembler does not take symbols
"qdadd %0, %2, %0\n\t"
"mov %0, %0, lsr #16"
: "=&r*i"(x)
: "r"(ra),
"r"(z));
return ((Int16)x);
}
#define limiter( y, x) y = sat(x);
#elif defined(PV_ARM_MSC_EVC_V5)
#define limiter( y, x) z = x<< (15-SCALING); \
y = _DAddSatInt( ROUNDING_SCALED, z)>>16;
#else
#define limiter( y, x) z = ((x + ROUNDING )>>SCALING); \
if ((z>>15) != (z>>31)) \
{ \
z = (z >> 31) ^ INT16_MAX; \
} \
y = (Int16)(z);
#endif
/*----------------------------------------------------------------------------
; 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
----------------------------------------------------------------------------*/
/*----------------------------------------------------------------------------
; EXTERNAL GLOBAL STORE/BUFFER/POINTER REFERENCES
; Declare variables used in this module but defined elsewhere
----------------------------------------------------------------------------*/
/*----------------------------------------------------------------------------
; FUNCTION CODE
----------------------------------------------------------------------------*/
#ifdef AAC_PLUS
void trans4m_freq_2_time_fxp_1(
Int32 Frequency_data[],
Int32 Time_data[],
Int16 Output_buffer[],
WINDOW_SEQUENCE wnd_seq,
Int wnd_shape_prev_bk,
Int wnd_shape_this_bk,
Int Q_format,
Int32 abs_max_per_window[],
Int32 freq_2_time_buffer[])
{
Int exp;
Int shift;
Int i;
Int wnd;
#if !(defined( PV_ARM_GCC_V5)||(PV_ARM_V5))
Int32 z;
#endif
Int16 *pFreqInfo;
Int32 temp;
Int32 test;
Int16 *pFreq_2_Time_data_1;
Int16 *pFreq_2_Time_data_2;
const Int16 *pLong_Window_1;
const Int16 *pLong_Window_2;
const Int16 *pShort_Window_1;
const Int16 *pShort_Window_2;
Int32 *pOverlap_and_Add_Buffer_1;
Int32 *pOverlap_and_Add_Buffer_2;
Int16 *pOutput_buffer;
Int16 *pOutput_buffer_2;
const Int16 * Long_Window_fxp[NUM_WINDOW_SHAPES];
const Int16 * Short_Window_fxp[NUM_WINDOW_SHAPES];
Long_Window_fxp[0] = Long_Window_sine_fxp;
Long_Window_fxp[1] = Long_Window_KBD_fxp;
Short_Window_fxp[0] = Short_Window_sine_fxp;
Short_Window_fxp[1] = Short_Window_KBD_fxp;
if (wnd_seq != EIGHT_SHORT_SEQUENCE)
{
pFreqInfo = (Int16 *)Frequency_data;
exp = imdct_fxp(
(Int32 *)pFreqInfo,
freq_2_time_buffer,
LONG_BLOCK1,
Q_format,
abs_max_per_window[0]);
/*
* The C Programming Language, Second Edition, Kernighan & Ritchie,
* page 206.
* "The result [of a shift] is undefined if the right operand is
* negative, or greater than or equal to the number of bits in the
* left expression's type"
* => avoid shift by 32 or 16
*/
if (exp < 16)
{
pFreq_2_Time_data_1 = pFreqInfo;
switch (wnd_seq)
{
case ONLY_LONG_SEQUENCE:
default:
pOutput_buffer = Output_buffer;
pOverlap_and_Add_Buffer_1 = Time_data;
{
const Int16 *pLong_Window_2 = &Long_Window_fxp[wnd_shape_this_bk][LONG_WINDOW_m_1];
Int32 * pFreq2T = (Int32 *)pFreqInfo;
Int32 * win = (Int32 *) & Long_Window_fxp[wnd_shape_prev_bk][0];
Int shift = exp + 15 - SCALING;
Int32 * pFreq2T_2 = &pFreq2T[HALF_LONG_WINDOW];
for (i = HALF_LONG_WINDOW; i != 0; i--)
{
Int16 win1, win2;
Int32 temp2, test2;
Int32 winx;
temp2 = *(pFreq2T++);
winx = *(win++);
test = *(pOverlap_and_Add_Buffer_1++);
test2 = *(pOverlap_and_Add_Buffer_1--);
temp = fxp_mul_16_by_16bb(temp2, winx) >> shift;
temp2 = fxp_mul_16_by_16tt(temp2, winx) >> shift;
limiter(*(pOutput_buffer++), (temp + test));
limiter(*(pOutput_buffer++), (temp2 + test2));
temp2 = *(pFreq2T_2++);
win1 = *(pLong_Window_2--);
win2 = *(pLong_Window_2--);
temp = fxp_mul_16_by_16bb(temp2, win1) >> shift;
test2 = fxp_mul_16_by_16tb(temp2, win2) >> shift;
*(pOverlap_and_Add_Buffer_1++) = temp;
*(pOverlap_and_Add_Buffer_1++) = test2;
}
}
break;
case LONG_START_SEQUENCE:
pFreq_2_Time_data_2 =
&pFreq_2_Time_data_1[ HALF_LONG_WINDOW];
pLong_Window_1 = &Long_Window_fxp[wnd_shape_prev_bk][0];
pLong_Window_2 = &pLong_Window_1[ HALF_LONG_WINDOW];
pOverlap_and_Add_Buffer_1 = &Time_data[0];
pOverlap_and_Add_Buffer_2 = &Time_data[HALF_LONG_WINDOW];
pOutput_buffer = Output_buffer;
pOutput_buffer_2 = pOutput_buffer + HALF_LONG_WINDOW;
shift = exp + 15 - SCALING;
for (i = HALF_LONG_WINDOW; i != 0; i--)
{
Int16 win1, win2;
Int16 dat1, dat2;
Int32 test1, test2;
dat1 = *(pFreq_2_Time_data_1++);
win1 = *(pLong_Window_1++);
test1 = *(pOverlap_and_Add_Buffer_1++);
dat2 = *(pFreq_2_Time_data_2++);
win2 = *(pLong_Window_2++);
test2 = *(pOverlap_and_Add_Buffer_2++);
limiter(*(pOutput_buffer++), (test1 + (fxp_mul_16_by_16(dat1, win1) >> shift)));
limiter(*(pOutput_buffer_2++), (test2 + (fxp_mul_16_by_16(dat2, win2) >> shift)));
}
/*
* data unchanged from LONG_WINDOW to W_L_START_1
* only scaled accordingly
*/
pOverlap_and_Add_Buffer_1 = &Time_data[0];
pFreq_2_Time_data_1 = &pFreqInfo[LONG_WINDOW];
exp -= SCALING;
if (exp >= 0)
{
for (i = (W_L_START_1 - LONG_WINDOW) >> 1; i != 0; i--)
{
*(pOverlap_and_Add_Buffer_1++) =
*(pFreq_2_Time_data_1++) >> exp;
*(pOverlap_and_Add_Buffer_1++) =
*(pFreq_2_Time_data_1++) >> exp;
}
}
else if (exp < 0)
{
Int shift = -exp;
for (i = (W_L_START_1 - LONG_WINDOW) >> 1; i != 0 ; i--)
{
Int32 temp2 = ((Int32) * (pFreq_2_Time_data_1++)) << shift;
*(pOverlap_and_Add_Buffer_1++) = temp2;
temp2 = ((Int32) * (pFreq_2_Time_data_1++)) << shift;
*(pOverlap_and_Add_Buffer_1++) = temp2;
}
}
else
{
for (i = (W_L_START_1 - LONG_WINDOW) >> 1; i != 0; i--)
{
*(pOverlap_and_Add_Buffer_1++) =
*(pFreq_2_Time_data_1++);
*(pOverlap_and_Add_Buffer_1++) =
*(pFreq_2_Time_data_1++);
}
}
pFreq_2_Time_data_1 = &pFreqInfo[W_L_START_1];
pFreq_2_Time_data_2 =
&pFreq_2_Time_data_1[HALF_SHORT_WINDOW];
pShort_Window_1 =
&Short_Window_fxp[wnd_shape_this_bk][SHORT_WINDOW_m_1];
pShort_Window_2 = pShort_Window_1 - HALF_SHORT_WINDOW;
pOverlap_and_Add_Buffer_2 = pOverlap_and_Add_Buffer_1 +
HALF_SHORT_WINDOW;
for (i = HALF_SHORT_WINDOW; i != 0; i--)
{
Int16 win1, win2;
Int16 dat1, dat2;
Int32 temp2;
dat1 = (*pFreq_2_Time_data_1++);
dat2 = (*pFreq_2_Time_data_2++);
win1 = *(pShort_Window_1--);
win2 = *(pShort_Window_2--);
temp = fxp_mul_16_by_16(dat1, win1) >> shift;
*(pOverlap_and_Add_Buffer_1++) = temp;
temp2 = fxp_mul_16_by_16(dat2, win2) >> shift;
*(pOverlap_and_Add_Buffer_2++) = temp2;
}
pOverlap_and_Add_Buffer_1 += HALF_SHORT_WINDOW;
pv_memset(
pOverlap_and_Add_Buffer_1,
0,
(LONG_BLOCK1 - W_L_START_2)
*sizeof(*pOverlap_and_Add_Buffer_1));
break;
case LONG_STOP_SEQUENCE:
pOverlap_and_Add_Buffer_1 = &Time_data[ W_L_STOP_2];
pOutput_buffer = &Output_buffer[W_L_STOP_2];
pFreq_2_Time_data_1 = &pFreqInfo[W_L_STOP_2];
exp -= SCALING; /* !!!! */
if (exp > 0)
{
Int16 tmp1 = (*(pFreq_2_Time_data_1++) >> exp);
temp = *(pOverlap_and_Add_Buffer_1++);
for (i = (LONG_WINDOW - W_L_STOP_2); i != 0; i--)
{
limiter(*(pOutput_buffer++), (temp + tmp1));
tmp1 = *(pFreq_2_Time_data_1++) >> exp;
temp = *(pOverlap_and_Add_Buffer_1++);
}
}
else if (exp < 0)
{
shift = -exp;
Int32 temp1 = ((Int32) * (pFreq_2_Time_data_1++)) << shift;
temp = *(pOverlap_and_Add_Buffer_1++);
for (i = (LONG_WINDOW - W_L_STOP_2); i != 0; i--)
{
limiter(*(pOutput_buffer++), (temp + temp1));
temp1 = ((Int32) * (pFreq_2_Time_data_1++)) << shift;
temp = *(pOverlap_and_Add_Buffer_1++);
}
}
else
{
Int16 tmp1 = *(pFreq_2_Time_data_1++);
temp = *(pOverlap_and_Add_Buffer_1++);
for (i = (LONG_WINDOW - W_L_STOP_2); i != 0; i--)
{
limiter(*(pOutput_buffer++), (temp + tmp1));
tmp1 = *(pFreq_2_Time_data_1++);
temp = *(pOverlap_and_Add_Buffer_1++);
}
}
pShort_Window_1 = &Short_Window_fxp[wnd_shape_prev_bk][0];
pShort_Window_2 = &pShort_Window_1[HALF_SHORT_WINDOW];
pFreq_2_Time_data_1 = &pFreqInfo[W_L_STOP_1];
pFreq_2_Time_data_2 =
&pFreq_2_Time_data_1[HALF_SHORT_WINDOW];
pOverlap_and_Add_Buffer_1 = &Time_data[ W_L_STOP_1];
pOverlap_and_Add_Buffer_2 = pOverlap_and_Add_Buffer_1
+ HALF_SHORT_WINDOW;
pOutput_buffer = &Output_buffer[W_L_STOP_1];
pOutput_buffer_2 = pOutput_buffer + HALF_SHORT_WINDOW;
exp += SCALING; /* +8 back to what it was */
shift = exp + 15 - SCALING;
for (i = HALF_SHORT_WINDOW; i != 0; i--)
{
Int16 win1;
Int16 dat1;
dat1 = *(pFreq_2_Time_data_1++);
win1 = *(pShort_Window_1++);
temp = *(pOverlap_and_Add_Buffer_1++);
test = fxp_mul_16_by_16(dat1, win1);
limiter(*(pOutput_buffer++), (temp + (test >> shift)));
dat1 = *(pFreq_2_Time_data_2++);
win1 = *(pShort_Window_2++);
temp = *(pOverlap_and_Add_Buffer_2++);
test = fxp_mul_16_by_16(dat1, win1);
limiter(*(pOutput_buffer_2++), (temp + (test >> shift)));
}
pFreq_2_Time_data_2 = &pFreqInfo[LONG_WINDOW];
pOverlap_and_Add_Buffer_1 = Time_data;
pOutput_buffer = Output_buffer;
pLong_Window_2 =
&Long_Window_fxp[wnd_shape_this_bk][LONG_WINDOW_m_1];
/*
* Copy previous time in current buffer, also copy overlap
* and add buffer
*/
for (i = W_L_STOP_1; i != 0; i--)
{
Int16 win1;
Int16 dat1;
win1 = *(pLong_Window_2--);
dat1 = *pFreq_2_Time_data_2++;
limiter(*(pOutput_buffer++), *(pOverlap_and_Add_Buffer_1));
temp = fxp_mul_16_by_16(dat1, win1) >> shift;
*(pOverlap_and_Add_Buffer_1++) = temp ;
}
for (i = (LONG_WINDOW - W_L_STOP_1); i != 0; i--)
{
temp = fxp_mul_16_by_16(*pFreq_2_Time_data_2++, *(pLong_Window_2--)) >> shift;
*(pOverlap_and_Add_Buffer_1++) = temp ;
}
break;
} /* switch (wnd_seq) */
} /* if (exp < 16) */
else
{
/* all zeros buffer or excessive down shift */
/* Overlap and add, setup buffer for next iteration */
pOverlap_and_Add_Buffer_1 = &Time_data[0];
pOutput_buffer = Output_buffer;
temp = (*pOverlap_and_Add_Buffer_1++);
for (i = LONG_WINDOW; i != 0; i--)
{
limiter(*(pOutput_buffer++), temp);
temp = (*pOverlap_and_Add_Buffer_1++);
}
pv_memset(Time_data, 0, LONG_WINDOW*sizeof(Time_data[0]));
}
}
else
{
Int32 *pScrath_mem;
Int32 *pScrath_mem_entry;
Int32 *pFrequency_data = Frequency_data;
Int32 * pOverlap_and_Add_Buffer_1;
Int32 * pOverlap_and_Add_Buffer_2;
Int32 * pOverlap_and_Add_Buffer_1x;
Int32 * pOverlap_and_Add_Buffer_2x;
/*
* Frequency_data is 2*LONG_WINDOW length but only
* the first LONG_WINDOW elements are filled in,
* then the second part can be used as scratch mem,
* then grab data from one window at a time in
* reverse order.
* The upper LONG_WINDOW Int32 are used to hold the
* computed overlap and add, used in the next call to
* this function, and also as sctrach memory
*/
/*
* Frequency_data usage for the case EIGHT_SHORT_SEQUENCE
|<----- Input Freq. data ----->|< Overlap & Add ->| Unused |-Scratch-|
| | Store for next | | memory |
| | call | | |
| | | | |
|//////////////////////////////|\\\\\\\\\\\\\\\\\\|--------|+++++++++|
| | | | |
0 LONG_WINDOW LONG_WINDOW | 2*LONG_WINDOW
+ | |
W_L_STOP_2 | |
|<-- -->|
SHORT_WINDOW +
HALF_SHORT_WINDOW
*
*/
pOverlap_and_Add_Buffer_1 = &pFrequency_data[
LONG_WINDOW + 3*SHORT_WINDOW + HALF_SHORT_WINDOW];
/*
* Initialize to zero, only the firt short window used in overlap
* and add
*/
pv_memset(
pOverlap_and_Add_Buffer_1,
0,
SHORT_WINDOW*sizeof(*pOverlap_and_Add_Buffer_1));
/*
* Showt windows are evaluated in decresing order. Windows from 7
* to 0 are break down in four cases: window numbers 7 to 5, 4, 3,
* and 2 to 0.
* The data from short windows 3 and 4 is situated at the boundary
* between the 'overlap and add' buffer and the output buffer.
*/
for (wnd = NUM_SHORT_WINDOWS - 1; wnd >= NUM_SHORT_WINDOWS / 2 + 1; wnd--)
{
pFreqInfo = (Int16 *) & pFrequency_data[ wnd*SHORT_WINDOW];
exp = imdct_fxp(
(Int32 *)pFreqInfo,
freq_2_time_buffer,
SHORT_BLOCK1,
Q_format,
abs_max_per_window[wnd]);
pOverlap_and_Add_Buffer_1 =
&pFrequency_data[ W_L_STOP_1 + SHORT_WINDOW*wnd];
pOverlap_and_Add_Buffer_2 =
pOverlap_and_Add_Buffer_1 + SHORT_WINDOW;
/*
* If all element are zero or if the exponent is bigger than
* 16 ( it becomes an undefined shift) -> skip
*/
if (exp < 16)
{
pFreq_2_Time_data_1 = &pFreqInfo[0];
pFreq_2_Time_data_2 = &pFreqInfo[SHORT_WINDOW];
/*
* Each of the eight short blocks is windowed separately.
* Window shape decisions are made on a frame-by-frame
* basis.
*/
pShort_Window_1 = &Short_Window_fxp[wnd_shape_this_bk][0];
pShort_Window_2 =
&Short_Window_fxp[wnd_shape_this_bk][SHORT_WINDOW_m_1];
/*
* For short windows from 7 to 5
* | =========================
* | | 5 6 7
* _--_ _--_ _--_ _--_ | _-|-_ _--_ _--_ _--_
* / \/ \/ \/ \|/ | \/ \/ \/ \
* / /\ /\ /\ /|\ | /\ /\ /\ \
* / / \ / \ / \ / | \ | / \ / \ / \ \
* / / \/ \/ \/ | \|/ \/ \ \ \
* --------------------------------|---[///////////////////////]--------
*
*/
shift = exp + 15 - SCALING;
for (i = SHORT_WINDOW; i != 0; i--)
{
Int16 win1, win2;
Int16 dat1, dat2;
dat2 = *(pFreq_2_Time_data_2++);
win2 = *(pShort_Window_2--);
temp = *pOverlap_and_Add_Buffer_2;
dat1 = *(pFreq_2_Time_data_1++);
win1 = *(pShort_Window_1++);
*(pOverlap_and_Add_Buffer_2++) = temp + (fxp_mul_16_by_16(dat2, win2) >> shift);
*(pOverlap_and_Add_Buffer_1++) = fxp_mul_16_by_16(dat1, win1) >> shift;
}
} /* if (exp < 16) */
else
{
pv_memset(
pOverlap_and_Add_Buffer_1,
0,
SHORT_WINDOW*sizeof(*pOverlap_and_Add_Buffer_1));
}
}/* for ( wnd=NUM_SHORT_WINDOWS-1; wnd>=NUM_SHORT_WINDOWS/2; wnd--) */
wnd = NUM_SHORT_WINDOWS / 2;
pFreqInfo = (Int16 *) & pFrequency_data[ wnd*SHORT_WINDOW];
/*
* scratch memory is allocated in an unused part of memory
*/
pScrath_mem = &pFrequency_data[ 2*LONG_WINDOW - HALF_SHORT_WINDOW];
pOverlap_and_Add_Buffer_1 = &pFrequency_data[ LONG_WINDOW];
pOverlap_and_Add_Buffer_2 = pOverlap_and_Add_Buffer_1
+ HALF_SHORT_WINDOW;
exp = imdct_fxp(
(Int32 *)pFreqInfo,
freq_2_time_buffer,
SHORT_BLOCK1,
Q_format,
abs_max_per_window[wnd]);
/*
* If all element are zero or if the exponent is bigger than
* 16 ( it becomes an undefined shift) -> skip
*/
if (exp < 16)
{
pFreq_2_Time_data_1 = &pFreqInfo[0];
pFreq_2_Time_data_2 = &pFreqInfo[SHORT_WINDOW];
pShort_Window_1 = &Short_Window_fxp[wnd_shape_this_bk][0];
pShort_Window_2 =
&Short_Window_fxp[wnd_shape_this_bk][SHORT_WINDOW_m_1];
/*
* For short window 4
* ====|===========
* | 4
* | | | |
* _--_ _--_ _--_ _-|-_ | _-|-_ _-|-_ _--_ _--_
* / \/ \/ \/ | \|/ | \/ | \/ \/ \
* / /\ /\ /\ | /|\ | /\ | /\ /\ \
* / / \ / \ / \ | / | \ | / \ | / \ / \ \
* / / \/ \/ \|/ | \|/ \|/ \/ \ \
* ------------------------------[\\\|\\\|//////]-------------------
* | | A | B | C |
* |
* W_L_STOP_1
*/
shift = exp + 15 - SCALING;
{
Int16 win1;
Int16 dat1;
/* -------- segment A ---------------*/
dat1 = *(pFreq_2_Time_data_1++);
win1 = *(pShort_Window_1++);
for (i = HALF_SHORT_WINDOW; i != 0; i--)
{
*(pScrath_mem++) = fxp_mul_16_by_16(dat1, win1) >> (shift);
dat1 = *(pFreq_2_Time_data_1++);
win1 = *(pShort_Window_1++);
}
/* -------- segment B ---------------*/
for (i = HALF_SHORT_WINDOW; i != 0; i--)
{
*(pOverlap_and_Add_Buffer_1++) = fxp_mul_16_by_16(dat1, win1) >> shift;
dat1 = *(pFreq_2_Time_data_1++);
win1 = *(pShort_Window_1++);
}
/* -------- segment C ---------------*/
temp = *pOverlap_and_Add_Buffer_2;
dat1 = *(pFreq_2_Time_data_2++);
win1 = *(pShort_Window_2--);
for (i = SHORT_WINDOW; i != 0; i--)
{
*(pOverlap_and_Add_Buffer_2++) = temp + (fxp_mul_16_by_16(dat1, win1) >> shift);
temp = *pOverlap_and_Add_Buffer_2;
dat1 = *(pFreq_2_Time_data_2++);
win1 = *(pShort_Window_2--);
}
}
} /* if (exp < 16) */
else
{
pv_memset(
pScrath_mem,
0,
HALF_SHORT_WINDOW*sizeof(*pScrath_mem));
pv_memset(
pOverlap_and_Add_Buffer_1,
0,
HALF_SHORT_WINDOW*sizeof(*pOverlap_and_Add_Buffer_1));
}
wnd = NUM_SHORT_WINDOWS / 2 - 1;
pFreqInfo = (Int16 *) & pFrequency_data[ wnd*SHORT_WINDOW];
pScrath_mem_entry =
&pFrequency_data[2*LONG_WINDOW - HALF_SHORT_WINDOW - SHORT_WINDOW];
pScrath_mem = pScrath_mem_entry;
pOverlap_and_Add_Buffer_1 = &pFrequency_data[ LONG_WINDOW];
/* point to end of buffer less HALF_SHORT_WINDOW */
pOutput_buffer_2 = &Output_buffer[LONG_WINDOW - HALF_SHORT_WINDOW];
pOutput_buffer = pOutput_buffer_2;
pOverlap_and_Add_Buffer_1x = &Time_data[W_L_STOP_1 + SHORT_WINDOW*(wnd+1)]; /* !!!! */
exp = imdct_fxp(
(Int32 *)pFreqInfo,
freq_2_time_buffer,
SHORT_BLOCK1,
Q_format,
abs_max_per_window[wnd]);
/*
* If all element are zero or if the exponent is bigger than
* 16 ( it becomes an undefined shift) -> skip
*/
if (exp < 16)
{
pFreq_2_Time_data_1 = &pFreqInfo[0];
pFreq_2_Time_data_2 = &pFreqInfo[SHORT_WINDOW];
/*
* For short window 3
* ===========|====
* 3 |
* | | | |
* _--_ _--_ _-|-_ _-|-_ | _-|-_ _--_ _--_ _--_
* / \/ \/ | \/ | \|/ | \/ \/ \/ \
* / /\ /\ | /\ | /|\ | /\ /\ /\ \
* / / \ / \ | / \ | / | \ | / \ / \ / \ \
* / / \/ \|/ \|/ | \|/ \/ \ \ \
* -----|------------------[\\\\\\|///|///]--------------------------
* | | A | B | C |
*
* W_L_STOP_1
*/
pShort_Window_1 = &Short_Window_fxp[wnd_shape_this_bk][0];
pShort_Window_2 =
&Short_Window_fxp[wnd_shape_this_bk][SHORT_WINDOW_m_1];
shift = exp + 15 - SCALING;
Int16 win1;
Int16 dat1;
/* -------- segment A ---------------*/
dat1 = *(pFreq_2_Time_data_1++);
win1 = *(pShort_Window_1++);
for (i = SHORT_WINDOW; i != 0; i--)
{
*(pScrath_mem++) = fxp_mul_16_by_16(dat1, win1) >> shift;
dat1 = *(pFreq_2_Time_data_1++);
win1 = *(pShort_Window_1++);
}
dat1 = *(pFreq_2_Time_data_2++);
win1 = *(pShort_Window_2--);
/* -------- segment B ---------------*/
for (i = HALF_SHORT_WINDOW; i != 0; i--)
{
test = fxp_mul_16_by_16(dat1, win1) >> shift;
temp = *(pScrath_mem++) + test;
test = *(pOverlap_and_Add_Buffer_1x++); /* !!!! */
limiter(*(pOutput_buffer++), (temp + test));
dat1 = *(pFreq_2_Time_data_2++);
win1 = *(pShort_Window_2--);
}
/* -------- segment C ---------------*/
for (i = HALF_SHORT_WINDOW; i != 0; i--)
{
temp = fxp_mul_16_by_16(dat1, win1) >> (shift);
*(pOverlap_and_Add_Buffer_1++) += temp;
dat1 = *(pFreq_2_Time_data_2++);
win1 = *(pShort_Window_2--);
}
} /* if (exp < 16) */
else
{
pv_memset(
pScrath_mem,
0,
SHORT_WINDOW*sizeof(*pScrath_mem));
pScrath_mem += SHORT_WINDOW;
temp = *(pScrath_mem++);
for (i = HALF_SHORT_WINDOW; i != 0; i--)
{
limiter(*(pOutput_buffer++), temp);
temp = *(pScrath_mem++);
}
}
for (wnd = NUM_SHORT_WINDOWS / 2 - 2; wnd >= 0; wnd--)
{
pOutput_buffer_2 -= SHORT_WINDOW;
pOutput_buffer = pOutput_buffer_2;
/*
* The same memory is used as scratch in every iteration
*/
pScrath_mem = pScrath_mem_entry;
pOverlap_and_Add_Buffer_2x =
&Time_data[W_L_STOP_1 + SHORT_WINDOW*(wnd+1)];
pFreqInfo = (Int16 *) & pFrequency_data[ wnd*SHORT_WINDOW];
exp = imdct_fxp(
(Int32 *)pFreqInfo,
freq_2_time_buffer,
SHORT_BLOCK1,
Q_format,
abs_max_per_window[wnd]);
/*
* If all element are zero or if the exponent is bigger than
* 16 ( it becomes an undefined shift) -> skip
*/
if (exp < 16)
{
pFreq_2_Time_data_1 = &pFreqInfo[0];
pFreq_2_Time_data_2 = &pFreqInfo[SHORT_WINDOW];
/*
* Each of the eight short blocks is windowed separately.
* Window shape decisions are made on a frame-by-frame
* basis.
*/
pShort_Window_1 = &Short_Window_fxp[wnd_shape_this_bk][0];
if (wnd == 0)
{
pShort_Window_1 =
&Short_Window_fxp[wnd_shape_prev_bk][0];
}
pShort_Window_2 =
&Short_Window_fxp[wnd_shape_this_bk][SHORT_WINDOW_m_1];
/*
* For short windows from 2 to 0
*
* =========================
* |
* 0 1 2 | |
* _--_ _--_ _--_ _-|-_ | _--_ _--_ _--_ _--_
* / \/ \/ \/ | \|/ \/ \/ \/ \
* / /\ /\ /\ | /|\ /\ /\ /\ \
* / / \ / \ / \ | / | \ / \ / \ / \ \
* / / \/ \/ \|/ | \/ \/ \ \ \
* ----[\\\\\\\\\\\\\\\\\\\\\\\\]---|-----------------------------
* |
*
* W_L_STOP_1
*/
shift = exp + 15 - SCALING;
Int16 dat1 = *(pFreq_2_Time_data_2++);
Int16 win1 = *(pShort_Window_2--);
temp = *(pScrath_mem);
for (i = SHORT_WINDOW; i != 0; i--)
{
test = fxp_mul_16_by_16(dat1, win1) >> shift;
temp += test;
dat1 = *(pFreq_2_Time_data_1++);
win1 = *(pShort_Window_1++);
limiter(*(pOutput_buffer++), (temp + *(pOverlap_and_Add_Buffer_2x++)));
*(pScrath_mem++) = fxp_mul_16_by_16(dat1, win1) >> shift;
dat1 = *(pFreq_2_Time_data_2++);
win1 = *(pShort_Window_2--);
temp = *(pScrath_mem);
}
} /* if (exp < 16) */
else
{
test = *(pScrath_mem);
temp = *(pOverlap_and_Add_Buffer_2x++);
for (i = SHORT_WINDOW; i != 0; i--)
{
limiter(*(pOutput_buffer++), (temp + test));
*(pScrath_mem++) = 0;
test = *(pScrath_mem);
temp = *(pOverlap_and_Add_Buffer_2x++);
}
}
} /* for ( wnd=NUM_SHORT_WINDOWS/2-1; wnd>=0; wnd--) */
pOverlap_and_Add_Buffer_2x = &Time_data[W_L_STOP_1];
pScrath_mem = pScrath_mem_entry;
pOutput_buffer_2 -= SHORT_WINDOW;
pOutput_buffer = pOutput_buffer_2;
test = *(pScrath_mem++);
temp = *(pOverlap_and_Add_Buffer_2x++);
for (i = SHORT_WINDOW; i != 0; i--)
{
limiter(*(pOutput_buffer++), (temp + test));
test = *(pScrath_mem++);
temp = *(pOverlap_and_Add_Buffer_2x++);
}
pOverlap_and_Add_Buffer_1x = Time_data;
pOutput_buffer = Output_buffer;
temp = *(pOverlap_and_Add_Buffer_1x++);
for (i = W_L_STOP_1; i != 0; i--)
{
limiter(*(pOutput_buffer++), temp);
temp = *(pOverlap_and_Add_Buffer_1x++);
}
pOverlap_and_Add_Buffer_1x = &Time_data[0];
pOverlap_and_Add_Buffer_2 = &pFrequency_data[LONG_WINDOW];
/*
* update overlap and add buffer,
* so is ready for next iteration
*/
for (int i = 0; i < W_L_STOP_2; i++)
{
temp = *(pOverlap_and_Add_Buffer_2++);
*(pOverlap_and_Add_Buffer_1x++) = temp;
}
pv_memset(
pOverlap_and_Add_Buffer_1x,
0,
W_L_STOP_1*sizeof(*pOverlap_and_Add_Buffer_1x));
} /* if ( wnd_seq != EIGHT_SHORT_SEQUENCE) */
}
#endif
/*----------------------------------------------------------------------------
; FUNCTION CODE
----------------------------------------------------------------------------*/
void trans4m_freq_2_time_fxp_2(
Int32 Frequency_data[],
Int32 Time_data[],
WINDOW_SEQUENCE wnd_seq,
Int wnd_shape_prev_bk,
Int wnd_shape_this_bk,
Int Q_format,
Int32 abs_max_per_window[],
Int32 freq_2_time_buffer[],
Int16 *Interleaved_output)
{
Int exp;
Int shift;
Int i;
Int wnd;
#if !(defined( PV_ARM_GCC_V5)||(PV_ARM_V5))
Int32 z;
#endif
Int16 *pFreqInfo;
Int32 temp;
Int32 test;
Int16 *pFreq_2_Time_data_1;
Int16 *pFreq_2_Time_data_2;
const Int16 *pLong_Window_1;
const Int16 *pLong_Window_2;
const Int16 *pShort_Window_1;
const Int16 *pShort_Window_2;
Int32 *pOverlap_and_Add_Buffer_1;
Int32 *pOverlap_and_Add_Buffer_2;
Int16 *pInterleaved_output;
Int16 *pInterleaved_output_2;
const Int16 * Long_Window_fxp[NUM_WINDOW_SHAPES];
const Int16 * Short_Window_fxp[NUM_WINDOW_SHAPES];
Long_Window_fxp[0] = Long_Window_sine_fxp;
Long_Window_fxp[1] = Long_Window_KBD_fxp;
Short_Window_fxp[0] = Short_Window_sine_fxp;
Short_Window_fxp[1] = Short_Window_KBD_fxp;
if (wnd_seq != EIGHT_SHORT_SEQUENCE)
{
pFreqInfo = (Int16 *)Frequency_data;
exp = imdct_fxp(
(Int32 *)pFreqInfo,
freq_2_time_buffer,
LONG_BLOCK1,
Q_format,
abs_max_per_window[0]);
/*
* The C Programming Language, Second Edition, Kernighan & Ritchie,
* page 206.
* "The result [of a shift] is undefined if the right operand is
* negative, or greater than or equal to the number of bits in the
* left expression's type"
* => avoid shift by 32 or 16
*/
if (exp < 16)
{
pFreq_2_Time_data_1 = pFreqInfo;
switch (wnd_seq)
{
case ONLY_LONG_SEQUENCE:
default:
{
pOverlap_and_Add_Buffer_1 = Time_data;
pInterleaved_output = Interleaved_output;
{
const Int16 *pLong_Window_2 = &Long_Window_fxp[wnd_shape_this_bk][LONG_WINDOW_m_1];
Int32 * pFreq2T = (Int32 *)pFreqInfo;
Int32 * pFreq2T_2 = &pFreq2T[HALF_LONG_WINDOW];
Int32 * win = (Int32 *) & Long_Window_fxp[wnd_shape_prev_bk][0];
Int shift = exp + 15 - SCALING;
for (i = HALF_LONG_WINDOW; i != 0; i--)
{
Int16 win1, win2;
Int32 temp2, test2;
Int32 winx;
temp2 = *(pFreq2T++);
winx = *(win++);
test = *(pOverlap_and_Add_Buffer_1++);
test2 = *(pOverlap_and_Add_Buffer_1--);
temp = fxp_mul_16_by_16bb(temp2, winx) >> shift;
temp2 = fxp_mul_16_by_16tt(temp2, winx) >> shift;
limiter(*(pInterleaved_output), (temp + test));
limiter(*(pInterleaved_output + 2), (temp2 + test2));
pInterleaved_output += 4;
temp2 = *(pFreq2T_2++);
win1 = *(pLong_Window_2--);
win2 = *(pLong_Window_2--);
temp = fxp_mul_16_by_16bb(temp2, win1) >> shift;
test2 = fxp_mul_16_by_16tb(temp2, win2) >> shift;
*(pOverlap_and_Add_Buffer_1++) = temp;
*(pOverlap_and_Add_Buffer_1++) = test2;
}
}
}
break;
case LONG_START_SEQUENCE:
pFreq_2_Time_data_2 =
&pFreq_2_Time_data_1[ HALF_LONG_WINDOW];
pLong_Window_1 = &Long_Window_fxp[wnd_shape_prev_bk][0];
pLong_Window_2 = &pLong_Window_1[ HALF_LONG_WINDOW];
pOverlap_and_Add_Buffer_1 = &Time_data[0];
pOverlap_and_Add_Buffer_2 = &Time_data[HALF_LONG_WINDOW];
pInterleaved_output = Interleaved_output;
pInterleaved_output_2 = pInterleaved_output + (2 * HALF_LONG_WINDOW);
/*
* process first LONG_WINDOW elements
*/
shift = exp + 15 - SCALING;
for (i = HALF_LONG_WINDOW; i != 0; i--)
{
Int16 win1, win2;
Int16 dat1, dat2;
Int32 test1, test2;
dat1 = *(pFreq_2_Time_data_1++);
win1 = *(pLong_Window_1++);
test1 = *(pOverlap_and_Add_Buffer_1++);
dat2 = *(pFreq_2_Time_data_2++);
win2 = *(pLong_Window_2++);
test2 = *(pOverlap_and_Add_Buffer_2++);
limiter(*(pInterleaved_output), (test1 + (fxp_mul_16_by_16(dat1, win1) >> shift)));
pInterleaved_output += 2;
limiter(*(pInterleaved_output_2), (test2 + (fxp_mul_16_by_16(dat2, win2) >> shift)));
pInterleaved_output_2 += 2;
}
/*
* data unchanged from LONG_WINDOW to W_L_START_1
* only scaled accordingly
*/
pOverlap_and_Add_Buffer_1 = &Time_data[0];
pFreq_2_Time_data_1 = &pFreqInfo[LONG_WINDOW];
exp -= SCALING;
if (exp >= 0)
{
for (i = (W_L_START_1 - LONG_WINDOW) >> 1; i != 0; i--)
{
*(pOverlap_and_Add_Buffer_1++) =
*(pFreq_2_Time_data_1++) >> exp;
*(pOverlap_and_Add_Buffer_1++) =
*(pFreq_2_Time_data_1++) >> exp;
}
}
else if (exp < 0)
{
Int shift = -exp;
for (i = (W_L_START_1 - LONG_WINDOW) >> 1; i != 0 ; i--)
{
Int32 temp2 = ((Int32) * (pFreq_2_Time_data_1++)) << shift;
*(pOverlap_and_Add_Buffer_1++) = temp2;
temp2 = ((Int32) * (pFreq_2_Time_data_1++)) << shift;
*(pOverlap_and_Add_Buffer_1++) = temp2;
}
}
else
{
for (i = (W_L_START_1 - LONG_WINDOW) >> 1; i != 0; i--)
{
*(pOverlap_and_Add_Buffer_1++) =
*(pFreq_2_Time_data_1++);
*(pOverlap_and_Add_Buffer_1++) =
*(pFreq_2_Time_data_1++);
}
}
pFreq_2_Time_data_1 = &pFreqInfo[W_L_START_1];
pFreq_2_Time_data_2 =
&pFreq_2_Time_data_1[HALF_SHORT_WINDOW];
pShort_Window_1 =
&Short_Window_fxp[wnd_shape_this_bk][SHORT_WINDOW_m_1];
pShort_Window_2 = pShort_Window_1 - HALF_SHORT_WINDOW;
pOverlap_and_Add_Buffer_2 = pOverlap_and_Add_Buffer_1 +
HALF_SHORT_WINDOW;
{
Int16 win1, win2;
Int16 dat1, dat2;
Int32 temp2;
for (i = HALF_SHORT_WINDOW; i != 0; i--)
{
dat1 = (*pFreq_2_Time_data_1++);
dat2 = (*pFreq_2_Time_data_2++);
win1 = *(pShort_Window_1--);
win2 = *(pShort_Window_2--);
temp = fxp_mul_16_by_16(dat1, win1) >> shift;
*(pOverlap_and_Add_Buffer_1++) = temp;
temp2 = fxp_mul_16_by_16(dat2, win2) >> shift;
*(pOverlap_and_Add_Buffer_2++) = temp2;
}
}
pOverlap_and_Add_Buffer_1 += HALF_SHORT_WINDOW;
pv_memset(
pOverlap_and_Add_Buffer_1,
0,
(LONG_BLOCK1 - W_L_START_2)
*sizeof(*pOverlap_and_Add_Buffer_1));
break;
case LONG_STOP_SEQUENCE:
pOverlap_and_Add_Buffer_1 = &Time_data[ W_L_STOP_2];
pInterleaved_output = &Interleaved_output[2*W_L_STOP_2];
pFreq_2_Time_data_1 = &pFreqInfo[W_L_STOP_2];
exp -= SCALING;
if (exp > 0)
{
Int16 tmp1 = (*(pFreq_2_Time_data_1++) >> exp);
temp = *(pOverlap_and_Add_Buffer_1++);
for (i = (LONG_WINDOW - W_L_STOP_2); i != 0; i--)
{
limiter(*(pInterleaved_output), (temp + tmp1));
pInterleaved_output += 2;
tmp1 = *(pFreq_2_Time_data_1++) >> exp;
temp = *(pOverlap_and_Add_Buffer_1++);
}
}
else if (exp < 0)
{
shift = -exp;
Int32 temp1 = ((Int32) * (pFreq_2_Time_data_1++)) << shift;
temp = *(pOverlap_and_Add_Buffer_1++);
for (i = (LONG_WINDOW - W_L_STOP_2); i != 0; i--)
{
limiter(*(pInterleaved_output), (temp + temp1));
pInterleaved_output += 2;
temp1 = ((Int32) * (pFreq_2_Time_data_1++)) << shift;
temp = *(pOverlap_and_Add_Buffer_1++);
}
}
else
{
Int16 tmp1 = *(pFreq_2_Time_data_1++);
temp = *(pOverlap_and_Add_Buffer_1++);
for (i = (LONG_WINDOW - W_L_STOP_2); i != 0; i--)
{
limiter(*(pInterleaved_output), (temp + tmp1));
pInterleaved_output += 2;
tmp1 = *(pFreq_2_Time_data_1++);
temp = *(pOverlap_and_Add_Buffer_1++);
}
}
pShort_Window_1 = &Short_Window_fxp[wnd_shape_prev_bk][0];
pShort_Window_2 = &pShort_Window_1[HALF_SHORT_WINDOW];
pFreq_2_Time_data_1 = &pFreqInfo[W_L_STOP_1];
pFreq_2_Time_data_2 =
&pFreq_2_Time_data_1[HALF_SHORT_WINDOW];
pOverlap_and_Add_Buffer_1 = &Time_data[ W_L_STOP_1];
pOverlap_and_Add_Buffer_2 = pOverlap_and_Add_Buffer_1
+ HALF_SHORT_WINDOW;
pInterleaved_output = &Interleaved_output[2*W_L_STOP_1];
pInterleaved_output_2 = pInterleaved_output + (2 * HALF_SHORT_WINDOW);
exp += SCALING; /* +8 back to what it was */
shift = exp + 15 - SCALING;
for (i = HALF_SHORT_WINDOW; i != 0; i--)
{
Int16 win1;
Int16 dat1;
dat1 = *(pFreq_2_Time_data_1++);
win1 = *(pShort_Window_1++);
temp = *(pOverlap_and_Add_Buffer_1++);
test = fxp_mul_16_by_16(dat1, win1);
limiter(*(pInterleaved_output), (temp + (test >> shift)));
pInterleaved_output += 2;
dat1 = *(pFreq_2_Time_data_2++);
win1 = *(pShort_Window_2++);
temp = *(pOverlap_and_Add_Buffer_2++);
test = fxp_mul_16_by_16(dat1, win1);
limiter(*(pInterleaved_output_2), (temp + (test >> shift)));
pInterleaved_output_2 += 2;
}
pFreq_2_Time_data_2 = &pFreqInfo[LONG_WINDOW];
pOverlap_and_Add_Buffer_1 = Time_data;
pInterleaved_output = Interleaved_output;
pLong_Window_2 =
&Long_Window_fxp[wnd_shape_this_bk][LONG_WINDOW_m_1];
/*
* Copy previous time in current buffer, also copy overlap
* and add buffer
*/
for (i = W_L_STOP_1; i != 0; i--)
{
Int16 win1;
Int16 dat1;
win1 = *(pLong_Window_2--);
dat1 = *pFreq_2_Time_data_2++;
limiter(*(pInterleaved_output), *(pOverlap_and_Add_Buffer_1));
pInterleaved_output += 2;
temp = fxp_mul_16_by_16(dat1, win1) >> shift;
*(pOverlap_and_Add_Buffer_1++) = temp ;
}
for (i = (LONG_WINDOW - W_L_STOP_1); i != 0; i--)
{
temp = fxp_mul_16_by_16(*pFreq_2_Time_data_2++, *(pLong_Window_2--)) >> shift;
*(pOverlap_and_Add_Buffer_1++) = temp ;
}
break;
} /* switch (wnd_seq) */
} /* if (exp < 16) */
else
{
/* all zeros buffer or excessive down shift */
/* Overlap and add, setup buffer for next iteration */
pOverlap_and_Add_Buffer_1 = &Time_data[0];
pInterleaved_output = Interleaved_output;
temp = (*pOverlap_and_Add_Buffer_1++);
for (i = LONG_WINDOW; i != 0; i--)
{
limiter(*(pInterleaved_output), temp);
pInterleaved_output += 2;
temp = (*pOverlap_and_Add_Buffer_1++);
}
pv_memset(Time_data, 0, LONG_WINDOW*sizeof(Time_data[0]));
}
}
else
{
Int32 *pScrath_mem;
Int32 *pScrath_mem_entry;
Int32 *pFrequency_data = Frequency_data;
Int32 * pOverlap_and_Add_Buffer_1;
Int32 * pOverlap_and_Add_Buffer_2;
Int32 * pOverlap_and_Add_Buffer_1x;
Int32 * pOverlap_and_Add_Buffer_2x;
/*
* Frequency_data is 2*LONG_WINDOW length but only
* the first LONG_WINDOW elements are filled in,
* then the second part can be used as scratch mem,
* then grab data from one window at a time in
* reverse order.
* The upper LONG_WINDOW Int32 are used to hold the
* computed overlap and add, used in the next call to
* this function, and also as sctrach memory
*/
/*
* Frequency_data usage for the case EIGHT_SHORT_SEQUENCE
|<----- Input Freq. data ----->|< Overlap & Add ->| Unused |-Scratch-|
| | Store for next | | memory |
| | call | | |
| | | | |
|//////////////////////////////|\\\\\\\\\\\\\\\\\\|--------|+++++++++|
| | | | |
0 LONG_WINDOW LONG_WINDOW | 2*LONG_WINDOW
+ | |
W_L_STOP_2 | |
|<-- -->|
SHORT_WINDOW +
HALF_SHORT_WINDOW
*
*/
pOverlap_and_Add_Buffer_1 = &pFrequency_data[
LONG_WINDOW + 3*SHORT_WINDOW + HALF_SHORT_WINDOW];
/*
* Initialize to zero, only the firt short window used in overlap
* and add
*/
pv_memset(
pOverlap_and_Add_Buffer_1,
0,
SHORT_WINDOW*sizeof(*pOverlap_and_Add_Buffer_1));
/*
* Showt windows are evaluated in decresing order. Windows from 7
* to 0 are break down in four cases: window numbers 7 to 5, 4, 3,
* and 2 to 0.
* The data from short windows 3 and 4 is situated at the boundary
* between the 'overlap and add' buffer and the output buffer.
*/
for (wnd = NUM_SHORT_WINDOWS - 1; wnd >= NUM_SHORT_WINDOWS / 2 + 1; wnd--)
{
pFreqInfo = (Int16 *) & pFrequency_data[ wnd*SHORT_WINDOW];
exp = imdct_fxp(
(Int32 *)pFreqInfo,
freq_2_time_buffer,
SHORT_BLOCK1,
Q_format,
abs_max_per_window[wnd]);
/* W_L_STOP_1 == (LONG_WINDOW - SHORT_WINDOW)>>1 */
pOverlap_and_Add_Buffer_1 =
&pFrequency_data[ W_L_STOP_1 + SHORT_WINDOW*wnd];
pOverlap_and_Add_Buffer_2 =
pOverlap_and_Add_Buffer_1 + SHORT_WINDOW;
/*
* If all element are zero or if the exponent is bigger than
* 16 ( it becomes an undefined shift) -> skip
*/
if (exp < 16)
{
pFreq_2_Time_data_1 = &pFreqInfo[0];
pFreq_2_Time_data_2 = &pFreqInfo[SHORT_WINDOW];
/*
* Each of the eight short blocks is windowed separately.
* Window shape decisions are made on a frame-by-frame
* basis.
*/
pShort_Window_1 = &Short_Window_fxp[wnd_shape_this_bk][0];
pShort_Window_2 =
&Short_Window_fxp[wnd_shape_this_bk][SHORT_WINDOW_m_1];
/*
* For short windows from 7 to 5
* | =========================
* | | 5 6 7
* _--_ _--_ _--_ _--_ | _-|-_ _--_ _--_ _--_
* / \/ \/ \/ \|/ | \/ \/ \/ \
* / /\ /\ /\ /|\ | /\ /\ /\ \
* / / \ / \ / \ / | \ | / \ / \ / \ \
* / / \/ \/ \/ | \|/ \/ \ \ \
* --------------------------------|---[///////////////////////]--------
*
*/
shift = exp + 15 - SCALING;
for (i = SHORT_WINDOW; i != 0; i--)
{
Int16 win1, win2;
Int16 dat1, dat2;
dat2 = *(pFreq_2_Time_data_2++);
win2 = *(pShort_Window_2--);
temp = *pOverlap_and_Add_Buffer_2;
dat1 = *(pFreq_2_Time_data_1++);
win1 = *(pShort_Window_1++);
*(pOverlap_and_Add_Buffer_2++) = temp + (fxp_mul_16_by_16(dat2, win2) >> shift);
*(pOverlap_and_Add_Buffer_1++) = fxp_mul_16_by_16(dat1, win1) >> shift;
}
} /* if (exp < 16) */
else
{
pv_memset(
pOverlap_and_Add_Buffer_1,
0,
SHORT_WINDOW*sizeof(*pOverlap_and_Add_Buffer_1));
}
}/* for ( wnd=NUM_SHORT_WINDOWS-1; wnd>=NUM_SHORT_WINDOWS/2; wnd--) */
wnd = NUM_SHORT_WINDOWS / 2;
pFreqInfo = (Int16 *) & pFrequency_data[ wnd*SHORT_WINDOW];
/*
* scratch memory is allocated in an unused part of memory
*/
pScrath_mem = &pFrequency_data[ 2*LONG_WINDOW - HALF_SHORT_WINDOW];
pOverlap_and_Add_Buffer_1 = &pFrequency_data[ LONG_WINDOW];
pOverlap_and_Add_Buffer_2 = pOverlap_and_Add_Buffer_1
+ HALF_SHORT_WINDOW;
exp = imdct_fxp(
(Int32 *)pFreqInfo,
freq_2_time_buffer,
SHORT_BLOCK1,
Q_format,
abs_max_per_window[wnd]);
/*
* If all element are zero or if the exponent is bigger than
* 16 ( it becomes an undefined shift) -> skip
*/
if (exp < 16)
{
pFreq_2_Time_data_1 = &pFreqInfo[0];
pFreq_2_Time_data_2 = &pFreqInfo[SHORT_WINDOW];
pShort_Window_1 = &Short_Window_fxp[wnd_shape_this_bk][0];
pShort_Window_2 =
&Short_Window_fxp[wnd_shape_this_bk][SHORT_WINDOW_m_1];
/*
* For short window 4
* ====|===========
* | 4
* | | | |
* _--_ _--_ _--_ _-|-_ | _-|-_ _-|-_ _--_ _--_
* / \/ \/ \/ | \|/ | \/ | \/ \/ \
* / /\ /\ /\ | /|\ | /\ | /\ /\ \
* / / \ / \ / \ | / | \ | / \ | / \ / \ \
* / / \/ \/ \|/ | \|/ \|/ \/ \ \
* ------------------------------[\\\|\\\|//////]-------------------
* | | A | B | C |
* |
* W_L_STOP_1
*/
shift = exp + 15 - SCALING;
{
Int16 win1;
Int16 dat1;
/* -------- segment A ---------------*/
dat1 = *(pFreq_2_Time_data_1++);
win1 = *(pShort_Window_1++);
for (i = HALF_SHORT_WINDOW; i != 0; i--)
{
*(pScrath_mem++) = fxp_mul_16_by_16(dat1, win1) >> shift;
dat1 = *(pFreq_2_Time_data_1++);
win1 = *(pShort_Window_1++);
}
/* -------- segment B ---------------*/
for (i = HALF_SHORT_WINDOW; i != 0; i--)
{
*(pOverlap_and_Add_Buffer_1++) = fxp_mul_16_by_16(dat1, win1) >> shift;
dat1 = *(pFreq_2_Time_data_1++);
win1 = *(pShort_Window_1++);
}
/* -------- segment C ---------------*/
temp = *pOverlap_and_Add_Buffer_2;
dat1 = *(pFreq_2_Time_data_2++);
win1 = *(pShort_Window_2--);
for (i = SHORT_WINDOW; i != 0; i--)
{
*(pOverlap_and_Add_Buffer_2++) = temp + (fxp_mul_16_by_16(dat1, win1) >> shift);
temp = *pOverlap_and_Add_Buffer_2;
dat1 = *(pFreq_2_Time_data_2++);
win1 = *(pShort_Window_2--);
}
}
} /* if (exp < 16) */
else
{
pv_memset(
pScrath_mem,
0,
HALF_SHORT_WINDOW*sizeof(*pScrath_mem));
pv_memset(
pOverlap_and_Add_Buffer_1,
0,
HALF_SHORT_WINDOW*sizeof(*pOverlap_and_Add_Buffer_1));
}
wnd = NUM_SHORT_WINDOWS / 2 - 1;
pFreqInfo = (Int16 *) & pFrequency_data[ wnd*SHORT_WINDOW];
pScrath_mem_entry =
&pFrequency_data[2*LONG_WINDOW - HALF_SHORT_WINDOW - SHORT_WINDOW];
pScrath_mem = pScrath_mem_entry;
pOverlap_and_Add_Buffer_1 = &pFrequency_data[ LONG_WINDOW];
/* point to end of buffer less HALF_SHORT_WINDOW */
pInterleaved_output_2 = &Interleaved_output[2*(LONG_WINDOW - HALF_SHORT_WINDOW)];
pInterleaved_output = pInterleaved_output_2;
pOverlap_and_Add_Buffer_1x = &Time_data[W_L_STOP_1 + SHORT_WINDOW*(wnd+1)];
exp = imdct_fxp(
(Int32 *)pFreqInfo,
freq_2_time_buffer,
SHORT_BLOCK1,
Q_format,
abs_max_per_window[wnd]);
/*
* If all element are zero or if the exponent is bigger than
* 16 ( it becomes an undefined shift) -> skip
*/
if (exp < 16)
{
pFreq_2_Time_data_1 = &pFreqInfo[0];
pFreq_2_Time_data_2 = &pFreqInfo[SHORT_WINDOW];
/*
* For short window 3
* ===========|====
* 3 |
* | | | |
* _--_ _--_ _-|-_ _-|-_ | _-|-_ _--_ _--_ _--_
* / \/ \/ | \/ | \|/ | \/ \/ \/ \
* / /\ /\ | /\ | /|\ | /\ /\ /\ \
* / / \ / \ | / \ | / | \ | / \ / \ / \ \
* / / \/ \|/ \|/ | \|/ \/ \ \ \
* -----|------------------[\\\\\\|///|///]--------------------------
* | | A | B | C |
*
* W_L_STOP_1
*/
pShort_Window_1 = &Short_Window_fxp[wnd_shape_this_bk][0];
pShort_Window_2 =
&Short_Window_fxp[wnd_shape_this_bk][SHORT_WINDOW_m_1];
shift = exp + 15 - SCALING;
Int16 win1;
Int16 dat1;
/* -------- segment A ---------------*/
dat1 = *(pFreq_2_Time_data_1++);
win1 = *(pShort_Window_1++);
for (i = SHORT_WINDOW; i != 0; i--)
{
*(pScrath_mem++) = fxp_mul_16_by_16(dat1, win1) >> shift;
dat1 = *(pFreq_2_Time_data_1++);
win1 = *(pShort_Window_1++);
}
dat1 = *(pFreq_2_Time_data_2++);
win1 = *(pShort_Window_2--);
/* -------- segment B ---------------*/
for (i = HALF_SHORT_WINDOW; i != 0; i--)
{
test = fxp_mul_16_by_16(dat1, win1) >> shift;
temp = *(pScrath_mem++) + test;
test = *(pOverlap_and_Add_Buffer_1x++);
limiter(*(pInterleaved_output), (temp + test));
pInterleaved_output += 2;
dat1 = *(pFreq_2_Time_data_2++);
win1 = *(pShort_Window_2--);
}
/* -------- segment C ---------------*/
for (i = HALF_SHORT_WINDOW; i != 0; i--)
{
temp = fxp_mul_16_by_16(dat1, win1) >> shift;
*(pOverlap_and_Add_Buffer_1++) += temp;
dat1 = *(pFreq_2_Time_data_2++);
win1 = *(pShort_Window_2--);
}
} /* if (exp < 16) */
else
{
pv_memset(
pScrath_mem,
0,
SHORT_WINDOW*sizeof(*pScrath_mem));
pScrath_mem += SHORT_WINDOW;
temp = *(pScrath_mem++);
for (i = HALF_SHORT_WINDOW; i != 0; i--)
{
limiter(*(pInterleaved_output), (temp));
pInterleaved_output += 2;
temp = *(pScrath_mem++);
}
}
for (wnd = NUM_SHORT_WINDOWS / 2 - 2; wnd >= 0; wnd--)
{
pInterleaved_output_2 -= (SHORT_WINDOW * 2);
pInterleaved_output = pInterleaved_output_2;
/*
* The same memory is used as scratch in every iteration
*/
pScrath_mem = pScrath_mem_entry;
pOverlap_and_Add_Buffer_2x =
&Time_data[W_L_STOP_1 + SHORT_WINDOW*(wnd+1)];
pFreqInfo = (Int16 *) & pFrequency_data[ wnd*SHORT_WINDOW];
exp = imdct_fxp(
(Int32 *)pFreqInfo,
freq_2_time_buffer,
SHORT_BLOCK1,
Q_format,
abs_max_per_window[wnd]);
/*
* If all element are zero or if the exponent is bigger than
* 16 ( it becomes an undefined shift) -> skip
*/
if (exp < 16)
{
pFreq_2_Time_data_1 = &pFreqInfo[0];
pFreq_2_Time_data_2 = &pFreqInfo[SHORT_WINDOW];
/*
* Each of the eight short blocks is windowed separately.
* Window shape decisions are made on a frame-by-frame
* basis.
*/
pShort_Window_1 = &Short_Window_fxp[wnd_shape_this_bk][0];
if (wnd == 0)
{
pShort_Window_1 =
&Short_Window_fxp[wnd_shape_prev_bk][0];
}
pShort_Window_2 =
&Short_Window_fxp[wnd_shape_this_bk][SHORT_WINDOW_m_1];
/*
* For short windows from 2 to 0
*
* =========================
* |
* 0 1 2 | |
* _--_ _--_ _--_ _-|-_ | _--_ _--_ _--_ _--_
* / \/ \/ \/ | \|/ \/ \/ \/ \
* / /\ /\ /\ | /|\ /\ /\ /\ \
* / / \ / \ / \ | / | \ / \ / \ / \ \
* / / \/ \/ \|/ | \/ \/ \ \ \
* ----[\\\\\\\\\\\\\\\\\\\\\\\\]---|-----------------------------
* |
*
* W_L_STOP_1
*/
shift = exp + 15 - SCALING;
Int16 dat1 = *(pFreq_2_Time_data_2++);
Int16 win1 = *(pShort_Window_2--);
temp = *(pScrath_mem);
for (i = SHORT_WINDOW; i != 0; i--)
{
test = fxp_mul_16_by_16(dat1, win1) >> shift;
temp += test;
dat1 = *(pFreq_2_Time_data_1++);
win1 = *(pShort_Window_1++);
limiter(*(pInterleaved_output), (temp + *(pOverlap_and_Add_Buffer_2x++)));
pInterleaved_output += 2;
*(pScrath_mem++) = fxp_mul_16_by_16(dat1, win1) >> shift;
dat1 = *(pFreq_2_Time_data_2++);
win1 = *(pShort_Window_2--);
temp = *(pScrath_mem);
}
} /* if (exp < 16) */
else
{
test = *(pScrath_mem);
temp = *(pOverlap_and_Add_Buffer_2x++);
for (i = SHORT_WINDOW; i != 0; i--)
{
limiter(*(pInterleaved_output), (temp + test));
pInterleaved_output += 2;
*(pScrath_mem++) = 0;
test = *(pScrath_mem);
temp = *(pOverlap_and_Add_Buffer_2x++);
}
}
} /* for ( wnd=NUM_SHORT_WINDOWS/2-1; wnd>=0; wnd--) */
pOverlap_and_Add_Buffer_2x = &Time_data[W_L_STOP_1];
pScrath_mem = pScrath_mem_entry;
pInterleaved_output_2 -= (SHORT_WINDOW * 2);
pInterleaved_output = pInterleaved_output_2;
test = *(pScrath_mem++);
temp = *(pOverlap_and_Add_Buffer_2x++);
for (i = SHORT_WINDOW; i != 0; i--)
{
limiter(*(pInterleaved_output), (temp + test));
pInterleaved_output += 2;
test = *(pScrath_mem++);
temp = *(pOverlap_and_Add_Buffer_2x++);
}
pOverlap_and_Add_Buffer_1x = Time_data;
pInterleaved_output = Interleaved_output;
temp = *(pOverlap_and_Add_Buffer_1x++);
for (i = W_L_STOP_1; i != 0; i--)
{
limiter(*(pInterleaved_output), temp);
pInterleaved_output += 2;
temp = *(pOverlap_and_Add_Buffer_1x++);
}
pOverlap_and_Add_Buffer_1x = &Time_data[0];
pOverlap_and_Add_Buffer_2 = &pFrequency_data[LONG_WINDOW];
/*
* update overlap and add buffer,
* so is ready for next iteration
*/
for (int i = 0; i < W_L_STOP_2; i++)
{
temp = *(pOverlap_and_Add_Buffer_2++);
*(pOverlap_and_Add_Buffer_1x++) = temp;
}
pv_memset(
pOverlap_and_Add_Buffer_1x,
0,
W_L_STOP_1*sizeof(*pOverlap_and_Add_Buffer_1x));
} /* if ( wnd_seq != EIGHT_SHORT_SEQUENCE) */
} /* trans4m_freq_2_time_fxp */