1 /* ------------------------------------------------------------------
2 * Copyright (C) 1998-2009 PacketVideo
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
13 * express or implied.
14 * See the License for the specific language governing permissions
15 * and limitations under the License.
16 * -------------------------------------------------------------------
17 */
18 /*
19
20 Pathname: trans4m_time_2_freq_fxp.c
21 Function: trans4m_time_2_freq_fxp
22
23 ------------------------------------------------------------------------------
24 REVISION HISTORY
25
26 Description:
27 Modified normalization, so it now happen per window basis, eliminated
28 shifts left or rigth to accomodate TNS inverse filtering. The output
29 is 32 bits but only the lowest 16 are being used.
30 Modified fuction interface
31
32 Description: Modified variable names with leading "p" for pointers
33
34 Description:
35 Modified call to mdct_fxp to reflect extended precision use. Added routine
36 buffer_adaptation to extract 16 MSB and keep highest precision.
37 Modify casting to ensure proper operations for different platforms
38
39 Description:
40 Added comments according to code review
41
42 Description:
43 Removed include file "buffer_normalization.h"
44
45 Description:
46 Eliminated buffer_adaptation() and embedded its functionality in other
47 functions. Commented out the short window section given that this is
48 not supported by the standards
49
50 Description:
51 Added shift down operation for case when the window was equal to one.
52 This was not needed previuosly because buffer_adaptation() was doing
53 it.
54
55 Description: Created local version of vectors Long_Window_fxp and
56 Short_Window_fxp. This solve linking problem when using the
57 /ropi option (Read-only position independent) for some
58 compilers.
59
60
61 Who: Date:
62 Description:
63
64 ------------------------------------------------------------------------------
65 INPUT AND OUTPUT DEFINITIONS
66
67 Inputs:
68 Time2Freq_data = buffer with data in the time domain, it holds 2048
69 points of input time data
70 Output holds frequency (first 1024 points )
71 type Int32
72
73 wnd_seq = window sequence
74 type WINDOW_SEQUENCE
75
76 wnd_shape_prev_bk = previous window shape type
77 type Int
78
79 wnd_shape_this_bk = current window shape type
80 type Int
81
82 pQ_format = Holds the Q format of the data in, and data out
83 type Int *
84
85 mem_4_in_place_FFT[] = scratch memory for computing FFT, 1024 point
86 type Int32
87
88
89
90 Local Stores/Buffers/Pointers Needed:
91 None
92
93 Global Stores/Buffers/Pointers Needed:
94 None
95
96 Outputs:
97 None
98
99 Pointers and Buffers Modified:
100 Frequency information (1024 pts.) is returned in Time2Freq_data
101 pQ_format content spectral coefficients Q format
102
103 Local Stores Modified:
104 None
105
106 Global Stores Modified:
107 None
108
109 ------------------------------------------------------------------------------
110 FUNCTION DESCRIPTION
111
112 The time/frequency representation of the signal is mapped onto the frequency
113 domain by feeding it into the filterbank module. This module consists of
114 a modified discrete cosine transform (MDCT), (windowing and DCT).
115 In order to adapt the time/frequency resolution of the filterbank to the
116 characteristics of the input signal, a block switching tool is also
117 adopted. N represents the window length, where N is a function of the
118 window_sequence. For each channel, the N time values are transformed into the
119 N/2 frequency domain values via the MDCT.
120
121 The adaptation of the time-frequency resolution of the filterbank to the
122 characteristics of the input signal is done by shifting between transforms
123 whose input lengths are either 2048 or 256 samples. By enabling the block
124 switching tool, the following transitions are meaningful:
125
126 from ONLY_LONG_SEQUENCE to { LONG_START_SEQUENCE
127 ONLY_LONG_SEQUENCE
128
129 from LONG_START_SEQUENCE to { LONG_STOP_SEQUENCE
130 EIGHT_SHORT_SEQUENCE
131
132 from LONG_STOP_SEQUENCE to { LONG_START_SEQUENCE
133 ONLY_LONG_SEQUENCE
134
135 from EIGHT_SHORT_SEQUENCE to { LONG_STOP_SEQUENCE
136 EIGHT_SHORT_SEQUENCE
137
138 Window shape decisions are made by the encoder on a frame-by-frame-basis.
139 The window selected is applicable to the second half of the window function
140 only, since the first half is constrained to use the appropriate window
141 shape from the preceding frame.
142 The 2048 time-domain values x'(i)(n), (i window, n sample) to be windowed are
143 the last 1024 values of the previous window_sequence concatenated with 1024
144 values of the current block. The formula below shows this fact:
145
146 | x(i-1)(n+1024) for 0 < n < 1024
147 x'(i)(n) {
148 | x(i)(n) for 1024 < n < 2048
149
150
151
152 Once the window shape is selected, the window_shape syntax element is
153 initialized. Together with the chosen window_sequence all information needed
154 for windowing exist.
155 With the window halves described below all window_sequences can be assembled.
156 For window_shape == 1, the window coefficients are given by the Kaiser -
157 Bessel derived (KBD) window.
158 Otherwise, for window_shape == 0, a sine window is employed.
159
160 The window length N can be 2048 or 256 for the KBD and the sine window.
161 All four window_sequences explained below have a total length of 2048
162 samples.
163 For all kinds of window_sequences the window_shape of the left half of
164 the first transform window is determined by the window shape of the previous
165 block.
166 ------------------------------------------------------------------------------
167 REQUIREMENTS
168
169 This module shall implement a scheme to switch between window types and
170 in turn perform time to frequency transformations
171
172
173 ------------------------------------------------------------------------------
174 REFERENCES
175
176 [1] ISO 14496-3:1999, pag 111
177
178 ------------------------------------------------------------------------------
179 PSEUDO-CODE
180
181 IF ( wnd_seq == EIGHT_SHORT_SEQUENCE)
182 THEN
183
184
185 FOR ( wnd=0; wnd<NUM_SHORT_WINDOWS; wnd++)
186
187 time_info = &Time2Freq_data[ W_L_STOP_1 + wnd*SHORT_WINDOW]
188
189 FOR( i=0; i<SHORT_BLOCK1; i++)
190 aux_temp[i] = time_info[i]
191 ENDFOR
192
193
194 IF (wnd == 0)
195 THEN
196 pShort_Window_1 = &Short_Window[wnd_shape_prev_bk][0]
197 ELSE
198 pShort_Window_1 = &Short_Window[wnd_shape_this_bk][0]
199 ENDIF
200
201
202 pShort_Window_2 =
203 &Short_Window[wnd_shape->this_bk][SHORT_WINDOW_m_1]
204
205 FOR( i=0, j=SHORT_WINDOW; i<SHORT_WINDOW; i++, j--)
206 aux_temp[ i] *= pShort_Window_1[i]
207 aux_temp[SHORT_WINDOW+i] *= pShort_Window_2[j]
208 ENDFOR
209
210
211 CALL MDCT( aux_temp, SHORT_BLOCK1)
212 MODIFYING( aux_temp)
213
214 FOR( i=0; i<SHORT_WINDOW; i++)
215 Time2Freq_data[wnd*SHORT_WINDOW + i] = aux_temp[i];
216 ENDFOR
217
218 ENDFOR
219
220 ELSE
221
222 SWITCH ( wnd_seq)
223
224 CASE ( ONLY_LONG_SEQUENCE)
225
226 pLong_Window_1 = &Long_Window[wnd_shape_prev_bk][0]
227 pLong_Window_2 =
228 &Long_Window[wnd_shape_this_bk][LONG_WINDOW_m_1]
229
230 FOR (i=0; i<LONG_WINDOW; i++)
231 Time2Freq_data[ i] *= *pLong_Window_1++
232 Time2Freq_data[LONG_WINDOW+i] *= *pLong_Window_2--
233 ENDFOR
234
235 BREAK
236
237
238 CASE ( LONG_START_SEQUENCE)
239
240 pLong_Window_1 = &Long_Window[wnd_shape_prev_bk][0];
241
242 FOR ( i=0; i<LONG_WINDOW; i++)
243 Time2Freq_data[ i] *= *pLong_Window_1++;
244 ENDFOR
245
246
247 pShort_Window_1 =
248 &Short_Window[wnd_shape->this_bk][SHORT_WINDOW_m_1];
249
250 FOR ( i=0; i<SHORT_WINDOW; i++)
251 Time2Freq_data[W_L_START_1 + i] *= *pShort_Window_1--;
252 ENDFOR
253
254
255 FOR ( i=W_L_START_2; i<LONG_BLOCK1; i++)
256 Time2Freq_data[W_L_START_2 + i] = 0;
257 ENDFOR
258
259 BREAK
260
261
262 CASE ( LONG_STOP_SEQUENCE )
263
264 FOR ( i=0; i<W_L_STOP_1; i++)
265 Time2Freq_data[ i] = 0;
266 ENDFOR
267
268
269 pShort_Window_1 = &Short_Window[wnd_shape->prev_bk][0];
270
271 FOR ( i=0; i<SHORT_WINDOW; i++)
272 Time2Freq_data[W_L_STOP_1+ i] *= *pShort_Window_1++;
273 ENDFOR
274
275
276 pLong_Window_1 =
277 &Long_Window[wnd_shape->this_bk][LONG_WINDOW_m_1];
278
279 FOR ( i=0; i<LONG_WINDOW; i++)
280 Time2Freq_data[LONG_WINDOW + i] *= *pLong_Window_1--;
281 ENDFOR
282
283 BREAK
284
285
286 }
287
288 MDCT( Time2Freq_data, LONG_BLOCK1);
289 MODIFYING( Time2Freq_data)
290
291 ENDIF
292
293 ------------------------------------------------------------------------------
294 RESOURCES USED
295 When the code is written for a specific target processor the
296 the resources used should be documented below.
297
298 STACK USAGE: [stack count for this module] + [variable to represent
299 stack usage for each subroutine called]
300
301 where: [stack usage variable] = stack usage for [subroutine
302 name] (see [filename].ext)
303
304 DATA MEMORY USED: x words
305
306 PROGRAM MEMORY USED: x words
307
308 CLOCK CYCLES: [cycle count equation for this module] + [variable
309 used to represent cycle count for each subroutine
310 called]
311
312 where: [cycle count variable] = cycle count for [subroutine
313 name] (see [filename].ext)
314
315 ------------------------------------------------------------------------------
316 */
317
318
319 /*----------------------------------------------------------------------------
320 ; INCLUDES
321 ----------------------------------------------------------------------------*/
322
323 #include "pv_audio_type_defs.h"
324 #include "aac_mem_funcs.h"
325 #include "window_block_fxp.h"
326 #include "mdct_fxp.h"
327 #include "long_term_prediction.h"
328 #include "fxp_mul32.h"
329
330
331 /*----------------------------------------------------------------------------
332 ; MACROS
333 ; Define module specific macros here
334 ----------------------------------------------------------------------------*/
335
336 /*----------------------------------------------------------------------------
337 ; DEFINES
338 ; Include all pre-processor statements here. Include conditional
339 ; compile variables also.
340 ----------------------------------------------------------------------------*/
341 /*----------------------------------------------------------------------------
342 ; LOCAL FUNCTION DEFINITIONS
343 ; Function Prototype declaration
344 ----------------------------------------------------------------------------*/
345
346 /*----------------------------------------------------------------------------
347 ; LOCAL VARIABLE DEFINITIONS
348 ; Variable declaration - defined here and used outside this module
349 ----------------------------------------------------------------------------*/
350
351 /*----------------------------------------------------------------------------
352 ; EXTERNAL FUNCTION REFERENCES
353 ; Declare functions defined elsewhere and referenced in this module
354 ----------------------------------------------------------------------------*/
355
356 /*----------------------------------------------------------------------------
357 ; EXTERNAL VARIABLES REFERENCES
358 ; Declare variables used in this module but defined elsewhere
359 ----------------------------------------------------------------------------*/
360
361 /*----------------------------------------------------------------------------
362 ; EXTERNAL GLOBAL STORE/BUFFER/POINTER REFERENCES
363 ; Declare variables used in this module but defined elsewhere
364 ----------------------------------------------------------------------------*/
365
366 /*----------------------------------------------------------------------------
367 ; FUNCTION CODE
368 ----------------------------------------------------------------------------*/
trans4m_time_2_freq_fxp(Int32 Time2Freq_data[],WINDOW_SEQUENCE wnd_seq,Int wnd_shape_prev_bk,Int wnd_shape_this_bk,Int * pQ_format,Int32 mem_4_in_place_FFT[])369 void trans4m_time_2_freq_fxp(
370 Int32 Time2Freq_data[], /* time data size 2048 */
371 WINDOW_SEQUENCE wnd_seq, /* window sequence */
372 Int wnd_shape_prev_bk, /* window shape, current and previous */
373 Int wnd_shape_this_bk,
374 Int *pQ_format,
375 Int32 mem_4_in_place_FFT[]) /* scratch memory for computing FFT */
376 {
377
378 Int i;
379
380 Int32 *pAux_temp_1;
381 Int32 *pAux_temp_2;
382 Int32 *pAux_temp;
383 // Int32 temp;
384 const Int16 *pLong_Window_1;
385 const Int16 *pLong_Window_2;
386 const Int16 *pShort_Window_1;
387 const Int16 *pShort_Window_2;
388 Int shift = *pQ_format - 1;
389
390 const Int16 * Long_Window_fxp[NUM_WINDOW_SHAPES];
391 const Int16 * Short_Window_fxp[NUM_WINDOW_SHAPES];
392
393 Long_Window_fxp[0] = Long_Window_sine_fxp;
394 Long_Window_fxp[1] = Long_Window_KBD_fxp;
395 Short_Window_fxp[0] = Short_Window_sine_fxp;
396 Short_Window_fxp[1] = Short_Window_KBD_fxp;
397
398 if (wnd_seq != EIGHT_SHORT_SEQUENCE)
399 {
400
401 pAux_temp = Time2Freq_data;
402
403 *pQ_format = LTP_Q_FORMAT - *pQ_format;
404
405 pAux_temp_1 = pAux_temp;
406
407 switch (wnd_seq)
408 {
409
410 case LONG_START_SEQUENCE:
411
412 pAux_temp_2 = &pAux_temp_1[HALF_LONG_WINDOW];
413
414 pLong_Window_1 = &Long_Window_fxp[wnd_shape_prev_bk][0];
415 pLong_Window_2 = &pLong_Window_1[ HALF_LONG_WINDOW];
416
417
418
419
420 for (i = HALF_LONG_WINDOW; i > 0; i--)
421 {
422
423 *pAux_temp_1 = fxp_mul32_by_16((*pAux_temp_1), *pLong_Window_1++) >> shift;
424 pAux_temp_1++;
425 *pAux_temp_2 = fxp_mul32_by_16((*pAux_temp_2), *pLong_Window_2++) >> shift;
426 pAux_temp_2++;
427
428 }
429
430
431 /* data unchanged from LONG_WINDOW to W_L_START_1 */
432 pAux_temp_1 = &pAux_temp[LONG_WINDOW];
433 if (shift)
434 {
435 for (i = (W_L_START_1 - LONG_WINDOW) >> 1; i != 0; i--)
436 {
437 *(pAux_temp_1++) >>= shift;
438 *(pAux_temp_1++) >>= shift;
439 }
440 }
441
442
443 pAux_temp_1 = &pAux_temp[W_L_START_1];
444 pAux_temp_2 = &pAux_temp_1[HALF_SHORT_WINDOW];
445
446 pShort_Window_1 =
447 &Short_Window_fxp[wnd_shape_this_bk][SHORT_WINDOW_m_1];
448
449 pShort_Window_2 = pShort_Window_1 - HALF_SHORT_WINDOW;
450
451 for (i = HALF_SHORT_WINDOW; i > 0; i--)
452 {
453
454 *pAux_temp_1 = fxp_mul32_by_16((*pAux_temp_1), *pShort_Window_1--) >> shift;
455 pAux_temp_1++;
456 *pAux_temp_2 = fxp_mul32_by_16((*pAux_temp_2), *pShort_Window_2--) >> shift;
457 pAux_temp_2++;
458
459 }
460
461 pAux_temp_1 = &pAux_temp[W_L_START_2];
462
463 pv_memset(
464 pAux_temp_1,
465 0,
466 (LONG_BLOCK1 - W_L_START_2)*sizeof(*pAux_temp_1));
467
468 break;
469
470
471 case LONG_STOP_SEQUENCE:
472
473 pv_memset(
474 pAux_temp_1,
475 0,
476 (W_L_STOP_1)*sizeof(*pAux_temp_1));
477
478 pShort_Window_1 = &Short_Window_fxp[wnd_shape_prev_bk][0];
479 pShort_Window_2 = &pShort_Window_1[HALF_SHORT_WINDOW];
480
481 pAux_temp_1 = &pAux_temp_1[W_L_STOP_1];
482 pAux_temp_2 = pAux_temp_1 + HALF_SHORT_WINDOW;
483
484 for (i = HALF_SHORT_WINDOW; i > 0; i--)
485 {
486
487 *pAux_temp_1 = fxp_mul32_by_16((*pAux_temp_1), *pShort_Window_1++) >> shift;
488 pAux_temp_1++;
489 *pAux_temp_2 = fxp_mul32_by_16((*pAux_temp_2), *pShort_Window_2++) >> shift;
490 pAux_temp_2++;
491
492
493 }
494
495 /* data unchanged from W_L_STOP_2 to LONG_WINDOW */
496 pAux_temp_1 = &pAux_temp[W_L_STOP_2];
497
498 if (shift)
499 {
500 for (i = ((LONG_WINDOW - W_L_STOP_2) >> 1); i != 0; i--)
501 {
502 *(pAux_temp_1++) >>= shift;
503 *(pAux_temp_1++) >>= shift;
504 }
505 }
506
507
508
509 pAux_temp_1 = &pAux_temp[LONG_WINDOW];
510 pAux_temp_2 = pAux_temp_1 + HALF_LONG_WINDOW;
511
512 pLong_Window_1 =
513 &Long_Window_fxp[wnd_shape_this_bk][LONG_WINDOW_m_1];
514
515
516 pLong_Window_2 = &pLong_Window_1[-HALF_LONG_WINDOW];
517
518 for (i = HALF_LONG_WINDOW; i > 0; i--)
519 {
520 *pAux_temp_1 = fxp_mul32_by_16((*pAux_temp_1), *pLong_Window_1--) >> shift;
521 pAux_temp_1++;
522 *pAux_temp_2 = fxp_mul32_by_16((*pAux_temp_2), *pLong_Window_2--) >> shift;
523 pAux_temp_2++;
524
525 }
526
527 break;
528
529 case ONLY_LONG_SEQUENCE:
530 default:
531
532 pAux_temp_2 = &pAux_temp[LONG_WINDOW];
533
534 pLong_Window_1 = &Long_Window_fxp[wnd_shape_prev_bk][0];
535
536
537 pLong_Window_2 =
538 &Long_Window_fxp[wnd_shape_this_bk][LONG_WINDOW_m_1];
539
540
541 for (i = LONG_WINDOW; i > 0; i--)
542 {
543
544 *pAux_temp_1 = fxp_mul32_by_16((*pAux_temp_1), *pLong_Window_1++) >> shift;
545 pAux_temp_1++;
546 *pAux_temp_2 = fxp_mul32_by_16((*pAux_temp_2), *pLong_Window_2--) >> shift;
547 pAux_temp_2++;
548 }
549
550 break;
551
552 } /* end switch ( wnd_seq) */
553
554
555
556 *pQ_format += mdct_fxp(
557 pAux_temp,
558 mem_4_in_place_FFT,
559 LONG_BLOCK1);
560
561
562 } /* end if( wnd_seq != EIGHT_SHORT_SEQUENCE) */
563
564
565
566 /*****************************************/
567 /* decoding process for short window */
568 /*****************************************/
569
570 /*
571 * For short window the following code will be applied
572 * in the future when short window is supported in the
573 * standards
574 */
575 /*-------------------------------------------------------------------------
576
577 * pAux_temp = &mem_4_in_place_FFT[(2*SHORT_BLOCK1)];
578 *
579 * for ( wnd=0; wnd<NUM_SHORT_WINDOWS; wnd++)
580 * {
581 *
582 * pShort_Window_1 = &Short_Window_fxp[wnd_shape_this_bk][0];
583 *
584 * if (wnd == 0)
585 * {
586 * pShort_Window_1 = &Short_Window_fxp[wnd_shape_prev_bk][0];
587 * }
588 *
589 * pShort_Window_2 =
590 * &Short_Window_fxp[wnd_shape_this_bk][SHORT_WINDOW_m_1];
591 *
592 * pAux_temp_1 = pAux_temp;
593 * pAux_temp_2 = pAux_temp_1 + SHORT_WINDOW;
594 *
595 * Q_aux = 0;
596 *
597 * buffer_adaptation (
598 * &Q_aux,
599 * &Time2Freq_data[ W_L_STOP_1 + wnd*SHORT_WINDOW],
600 * (void *) pAux_temp,
601 * SHORT_BLOCK1,
602 * USING_INT,
603 * 16);
604 *
605 *
606 * for ( i=SHORT_WINDOW; i>0; i--)
607 * {
608 * temp = (*pAux_temp_1) * *pShort_Window_1++;
609 * *pAux_temp_1++ = (temp + 0x08000L) >> 16;
610 *
611 * temp = (*pAux_temp_2) * *pShort_Window_2--;
612 * *pAux_temp_2++ = (temp + 0x08000L) >> 16;
613 *
614 * }
615 *
616 *
617 * exp = mdct_fxp(
618 * pAux_temp,
619 * mem_4_in_place_FFT,
620 * SHORT_BLOCK1);
621 *
622 *
623 * exp += Q_aux;
624 *
625 * pAux_temp_1 = pAux_temp;
626 * pAux_temp_2 = pAux_temp_1 + HALF_SHORT_WINDOW;
627 * pTime_data_1 = &Time2Freq_data[wnd*SHORT_WINDOW];
628 * pTime_data_2 = pTime_data_1 + HALF_SHORT_WINDOW;
629 *
630 *
631 * if (exp > 0)
632 * {
633 * for ( i=HALF_SHORT_WINDOW; i>0; i--)
634 * {
635 * *pTime_data_1++ = (*pAux_temp_1++>>exp);
636 * *pTime_data_2++ = (*pAux_temp_2++>>exp);
637 * }
638 * }
639 * else if (exp < 0)
640 * {
641 * exp = -exp;
642 * for ( i=HALF_SHORT_WINDOW; i>0; i--)
643 * {
644 * *pTime_data_1++ = (*pAux_temp_1++<<exp);
645 * *pTime_data_2++ = (*pAux_temp_2++<<exp);
646 * }
647 * }
648 * else
649 * {
650 * for ( i=HALF_SHORT_WINDOW; i>0; i--)
651 * {
652 * *pTime_data_1++ = (*pAux_temp_1++);
653 * *pTime_data_2++ = (*pAux_temp_2++);
654 * }
655 * }
656 *
657 * }
658 *
659 * }
660 *
661 *--------------------------------------------------------------------------*/
662
663 } /* trans4m_time_2_freq_fxp */
664