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/trans4m_time_2_freq_fxp.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/trans4m_time_2_freq_fxp.cpp')
-rw-r--r-- | media/libstagefright/codecs/aacdec/trans4m_time_2_freq_fxp.cpp | 663 |
1 files changed, 663 insertions, 0 deletions
diff --git a/media/libstagefright/codecs/aacdec/trans4m_time_2_freq_fxp.cpp b/media/libstagefright/codecs/aacdec/trans4m_time_2_freq_fxp.cpp new file mode 100644 index 0000000..b1b44f0 --- /dev/null +++ b/media/libstagefright/codecs/aacdec/trans4m_time_2_freq_fxp.cpp @@ -0,0 +1,663 @@ +/* ------------------------------------------------------------------ + * 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_time_2_freq_fxp.c + Function: trans4m_time_2_freq_fxp + +------------------------------------------------------------------------------ + REVISION HISTORY + + Description: + Modified normalization, so it now happen per window basis, eliminated + shifts left or rigth to accomodate TNS inverse filtering. The output + is 32 bits but only the lowest 16 are being used. + Modified fuction interface + + Description: Modified variable names with leading "p" for pointers + + Description: + Modified call to mdct_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: + Added comments according to code review + + Description: + Removed include file "buffer_normalization.h" + + Description: + Eliminated buffer_adaptation() and embedded its functionality in other + functions. Commented out the short window section given that this is + not supported by the standards + + Description: + Added shift down operation for case when the window was equal to one. + This was not needed previuosly because buffer_adaptation() was doing + it. + + Description: Created local version of vectors Long_Window_fxp and + Short_Window_fxp. This solve linking problem when using the + /ropi option (Read-only position independent) for some + compilers. + + + Who: Date: + Description: + +------------------------------------------------------------------------------ + INPUT AND OUTPUT DEFINITIONS + + Inputs: + Time2Freq_data = buffer with data in the time domain, it holds 2048 + points of input time data + Output holds frequency (first 1024 points ) + type Int32 + + 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 + + pQ_format = Holds the Q format of the data in, and data out + type Int * + + mem_4_in_place_FFT[] = scratch memory for computing FFT, 1024 point + type Int32 + + + + Local Stores/Buffers/Pointers Needed: + None + + Global Stores/Buffers/Pointers Needed: + None + + Outputs: + None + + Pointers and Buffers Modified: + Frequency information (1024 pts.) is returned in Time2Freq_data + pQ_format content spectral coefficients Q format + + Local Stores Modified: + None + + Global Stores Modified: + None + +------------------------------------------------------------------------------ + FUNCTION DESCRIPTION + +The time/frequency representation of the signal is mapped onto the frequency +domain by feeding it into the filterbank module. This module consists of +a modified discrete cosine transform (MDCT), (windowing and DCT). +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 time values are transformed into the +N/2 frequency domain values via the MDCT. + +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 + + + +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. +------------------------------------------------------------------------------ + REQUIREMENTS + + This module shall implement a scheme to switch between window types and + in turn perform time to frequency transformations + + +------------------------------------------------------------------------------ + REFERENCES + + [1] ISO 14496-3:1999, pag 111 + +------------------------------------------------------------------------------ + PSEUDO-CODE + + IF ( wnd_seq == EIGHT_SHORT_SEQUENCE) + THEN + + + FOR ( wnd=0; wnd<NUM_SHORT_WINDOWS; wnd++) + + time_info = &Time2Freq_data[ W_L_STOP_1 + wnd*SHORT_WINDOW] + + FOR( i=0; i<SHORT_BLOCK1; i++) + aux_temp[i] = time_info[i] + ENDFOR + + + 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--) + aux_temp[ i] *= pShort_Window_1[i] + aux_temp[SHORT_WINDOW+i] *= pShort_Window_2[j] + ENDFOR + + + CALL MDCT( aux_temp, SHORT_BLOCK1) + MODIFYING( aux_temp) + + FOR( i=0; i<SHORT_WINDOW; i++) + Time2Freq_data[wnd*SHORT_WINDOW + i] = aux_temp[i]; + ENDFOR + + ENDFOR + + ELSE + + 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++) + Time2Freq_data[ i] *= *pLong_Window_1++ + Time2Freq_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++) + Time2Freq_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++) + Time2Freq_data[W_L_START_1 + i] *= *pShort_Window_1--; + ENDFOR + + + FOR ( i=W_L_START_2; i<LONG_BLOCK1; i++) + Time2Freq_data[W_L_START_2 + i] = 0; + ENDFOR + + BREAK + + + CASE ( LONG_STOP_SEQUENCE ) + + FOR ( i=0; i<W_L_STOP_1; i++) + Time2Freq_data[ i] = 0; + ENDFOR + + + pShort_Window_1 = &Short_Window[wnd_shape->prev_bk][0]; + + FOR ( i=0; i<SHORT_WINDOW; i++) + Time2Freq_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++) + Time2Freq_data[LONG_WINDOW + i] *= *pLong_Window_1--; + ENDFOR + + BREAK + + + } + + MDCT( Time2Freq_data, LONG_BLOCK1); + MODIFYING( Time2Freq_data) + + 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 "mdct_fxp.h" +#include "long_term_prediction.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 +----------------------------------------------------------------------------*/ + +/*---------------------------------------------------------------------------- +; EXTERNAL GLOBAL STORE/BUFFER/POINTER REFERENCES +; Declare variables used in this module but defined elsewhere +----------------------------------------------------------------------------*/ + +/*---------------------------------------------------------------------------- +; FUNCTION CODE +----------------------------------------------------------------------------*/ +void trans4m_time_2_freq_fxp( + Int32 Time2Freq_data[], /* time data size 2048 */ + WINDOW_SEQUENCE wnd_seq, /* window sequence */ + Int wnd_shape_prev_bk, /* window shape, current and previous */ + Int wnd_shape_this_bk, + Int *pQ_format, + Int32 mem_4_in_place_FFT[]) /* scratch memory for computing FFT */ +{ + + Int i; + + Int32 *pAux_temp_1; + Int32 *pAux_temp_2; + Int32 *pAux_temp; +// Int32 temp; + const Int16 *pLong_Window_1; + const Int16 *pLong_Window_2; + const Int16 *pShort_Window_1; + const Int16 *pShort_Window_2; + Int shift = *pQ_format - 1; + + 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) + { + + pAux_temp = Time2Freq_data; + + *pQ_format = LTP_Q_FORMAT - *pQ_format; + + pAux_temp_1 = pAux_temp; + + switch (wnd_seq) + { + + case LONG_START_SEQUENCE: + + pAux_temp_2 = &pAux_temp_1[HALF_LONG_WINDOW]; + + pLong_Window_1 = &Long_Window_fxp[wnd_shape_prev_bk][0]; + pLong_Window_2 = &pLong_Window_1[ HALF_LONG_WINDOW]; + + + + + for (i = HALF_LONG_WINDOW; i > 0; i--) + { + + *pAux_temp_1 = fxp_mul32_by_16((*pAux_temp_1), *pLong_Window_1++) >> shift; + pAux_temp_1++; + *pAux_temp_2 = fxp_mul32_by_16((*pAux_temp_2), *pLong_Window_2++) >> shift; + pAux_temp_2++; + + } + + + /* data unchanged from LONG_WINDOW to W_L_START_1 */ + pAux_temp_1 = &pAux_temp[LONG_WINDOW]; + if (shift) + { + for (i = (W_L_START_1 - LONG_WINDOW) >> 1; i != 0; i--) + { + *(pAux_temp_1++) >>= shift; + *(pAux_temp_1++) >>= shift; + } + } + + + pAux_temp_1 = &pAux_temp[W_L_START_1]; + pAux_temp_2 = &pAux_temp_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; + + for (i = HALF_SHORT_WINDOW; i > 0; i--) + { + + *pAux_temp_1 = fxp_mul32_by_16((*pAux_temp_1), *pShort_Window_1--) >> shift; + pAux_temp_1++; + *pAux_temp_2 = fxp_mul32_by_16((*pAux_temp_2), *pShort_Window_2--) >> shift; + pAux_temp_2++; + + } + + pAux_temp_1 = &pAux_temp[W_L_START_2]; + + pv_memset( + pAux_temp_1, + 0, + (LONG_BLOCK1 - W_L_START_2)*sizeof(*pAux_temp_1)); + + break; + + + case LONG_STOP_SEQUENCE: + + pv_memset( + pAux_temp_1, + 0, + (W_L_STOP_1)*sizeof(*pAux_temp_1)); + + pShort_Window_1 = &Short_Window_fxp[wnd_shape_prev_bk][0]; + pShort_Window_2 = &pShort_Window_1[HALF_SHORT_WINDOW]; + + pAux_temp_1 = &pAux_temp_1[W_L_STOP_1]; + pAux_temp_2 = pAux_temp_1 + HALF_SHORT_WINDOW; + + for (i = HALF_SHORT_WINDOW; i > 0; i--) + { + + *pAux_temp_1 = fxp_mul32_by_16((*pAux_temp_1), *pShort_Window_1++) >> shift; + pAux_temp_1++; + *pAux_temp_2 = fxp_mul32_by_16((*pAux_temp_2), *pShort_Window_2++) >> shift; + pAux_temp_2++; + + + } + + /* data unchanged from W_L_STOP_2 to LONG_WINDOW */ + pAux_temp_1 = &pAux_temp[W_L_STOP_2]; + + if (shift) + { + for (i = ((LONG_WINDOW - W_L_STOP_2) >> 1); i != 0; i--) + { + *(pAux_temp_1++) >>= shift; + *(pAux_temp_1++) >>= shift; + } + } + + + + pAux_temp_1 = &pAux_temp[LONG_WINDOW]; + pAux_temp_2 = pAux_temp_1 + HALF_LONG_WINDOW; + + pLong_Window_1 = + &Long_Window_fxp[wnd_shape_this_bk][LONG_WINDOW_m_1]; + + + pLong_Window_2 = &pLong_Window_1[-HALF_LONG_WINDOW]; + + for (i = HALF_LONG_WINDOW; i > 0; i--) + { + *pAux_temp_1 = fxp_mul32_by_16((*pAux_temp_1), *pLong_Window_1--) >> shift; + pAux_temp_1++; + *pAux_temp_2 = fxp_mul32_by_16((*pAux_temp_2), *pLong_Window_2--) >> shift; + pAux_temp_2++; + + } + + break; + + case ONLY_LONG_SEQUENCE: + default: + + pAux_temp_2 = &pAux_temp[LONG_WINDOW]; + + pLong_Window_1 = &Long_Window_fxp[wnd_shape_prev_bk][0]; + + + pLong_Window_2 = + &Long_Window_fxp[wnd_shape_this_bk][LONG_WINDOW_m_1]; + + + for (i = LONG_WINDOW; i > 0; i--) + { + + *pAux_temp_1 = fxp_mul32_by_16((*pAux_temp_1), *pLong_Window_1++) >> shift; + pAux_temp_1++; + *pAux_temp_2 = fxp_mul32_by_16((*pAux_temp_2), *pLong_Window_2--) >> shift; + pAux_temp_2++; + } + + break; + + } /* end switch ( wnd_seq) */ + + + + *pQ_format += mdct_fxp( + pAux_temp, + mem_4_in_place_FFT, + LONG_BLOCK1); + + + } /* end if( wnd_seq != EIGHT_SHORT_SEQUENCE) */ + + + + /*****************************************/ + /* decoding process for short window */ + /*****************************************/ + + /* + * For short window the following code will be applied + * in the future when short window is supported in the + * standards + */ + /*------------------------------------------------------------------------- + + * pAux_temp = &mem_4_in_place_FFT[(2*SHORT_BLOCK1)]; + * + * for ( wnd=0; wnd<NUM_SHORT_WINDOWS; wnd++) + * { + * + * 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]; + * + * pAux_temp_1 = pAux_temp; + * pAux_temp_2 = pAux_temp_1 + SHORT_WINDOW; + * + * Q_aux = 0; + * + * buffer_adaptation ( + * &Q_aux, + * &Time2Freq_data[ W_L_STOP_1 + wnd*SHORT_WINDOW], + * (void *) pAux_temp, + * SHORT_BLOCK1, + * USING_INT, + * 16); + * + * + * for ( i=SHORT_WINDOW; i>0; i--) + * { + * temp = (*pAux_temp_1) * *pShort_Window_1++; + * *pAux_temp_1++ = (temp + 0x08000L) >> 16; + * + * temp = (*pAux_temp_2) * *pShort_Window_2--; + * *pAux_temp_2++ = (temp + 0x08000L) >> 16; + * + * } + * + * + * exp = mdct_fxp( + * pAux_temp, + * mem_4_in_place_FFT, + * SHORT_BLOCK1); + * + * + * exp += Q_aux; + * + * pAux_temp_1 = pAux_temp; + * pAux_temp_2 = pAux_temp_1 + HALF_SHORT_WINDOW; + * pTime_data_1 = &Time2Freq_data[wnd*SHORT_WINDOW]; + * pTime_data_2 = pTime_data_1 + HALF_SHORT_WINDOW; + * + * + * if (exp > 0) + * { + * for ( i=HALF_SHORT_WINDOW; i>0; i--) + * { + * *pTime_data_1++ = (*pAux_temp_1++>>exp); + * *pTime_data_2++ = (*pAux_temp_2++>>exp); + * } + * } + * else if (exp < 0) + * { + * exp = -exp; + * for ( i=HALF_SHORT_WINDOW; i>0; i--) + * { + * *pTime_data_1++ = (*pAux_temp_1++<<exp); + * *pTime_data_2++ = (*pAux_temp_2++<<exp); + * } + * } + * else + * { + * for ( i=HALF_SHORT_WINDOW; i>0; i--) + * { + * *pTime_data_1++ = (*pAux_temp_1++); + * *pTime_data_2++ = (*pAux_temp_2++); + * } + * } + * + * } + * + * } + * + *--------------------------------------------------------------------------*/ + +} /* trans4m_time_2_freq_fxp */ |