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: long_term_prediction.c
21
22------------------------------------------------------------------------------
23 REVISION HISTORY
24
25 Description: Made changes based on comments and experiment results.
26
27 Description: Passed in buffer sizes based on review comments and prototype
28              agreements.
29
30 Description: 1. Passed in "weight_index" instead of "weight".
31              2. Added weight table.
32
33 Description: 1. Removed some passed in buffer size variables since they are
34                 not used for long window.
35              2. Modified comments format.
36
37 Description:
38    Modified casting to ensure proper operations for different platforms
39
40 Description:
41    Implemented circular buffer techniques, which save 4096 memmoves per
42    frame.
43
44 Description:
45    Implemented some optimizations found during the code review of this
46    module.  The optimizations related to the rules on the range of
47    ltp_buffer_index and num_samples, which allows for a simpler
48    code construct to be used in the processing of the predicted samples.
49
50 Description:
51    Add max calculation on the filter implementation, this to eliminate
52    function buffer_adaptation() on the time to frequency transformation.
53    Function interface changed. It now return the amount of shifting needed
54    to garb only the top 16 MSB.
55
56 Description:
57     Replace clearing memory with for-loop with pvmemset function
58
59 Description:
60
61------------------------------------------------------------------------------
62 INPUT AND OUTPUT DEFINITIONS
63
64 Inputs:
65    win_seq = type of window sequence (WINDOW_SEQUENCE).
66
67    weight_index = index (Int) of LTP coefficient table for all windows in
68                   current frame.
69
70    delay = buffer (Int) containing delays for each window.
71
72    buffer = history buffer (Int16) containing the reconstructed time domain
73             signals of previous frames.
74
75    buffer_offset = value (Int) that indicates the location of the first
76                    element in the LTP circular buffer.  (Either 0 or 1024)
77
78    time_quant    = filterbank buffer (Int32) This buffer is used by the
79                    filterbank, but it's first 1024 elements are equivalent
80                    to the last 1024 elements in the conventionally
81                    implemented LTP buffer.  Using this buffer directly avoids
82                    costly duplication of memory.
83
84    predicted_samples = buffer (Int32) with length of 2048 to hold
85                        predicted time domain signals.
86
87    buffer_index = index into buffer where the first sample of data from
88                   the frame (t-2) (two frames ago) resides.  (Int)
89
90    frame_length = length of one frame, type of Int.
91
92 Local Stores/Buffers/Pointers Needed:
93    None
94
95 Global Stores/Buffers/Pointers Needed:
96    None
97
98 Outputs:
99    Amount of shifting needed to grab the top 16 MSB from teh predicted buffer
100
101 Pointers and Buffers Modified:
102    predicted_samples contents are the newly calculated predicted time
103    domain signals
104
105 Local Stores Modified:
106    None
107
108 Global Stores Modified:
109    None
110
111------------------------------------------------------------------------------
112 FUNCTION DESCRIPTION
113
114 Long term prediction (LTP) is used to reduce the redundancy of a signal
115 between successive coding frames. This function performs prediction by
116 applying 1-tap IIR filtering to calculate the predicted time domain
117 signals of current frame from previous reconstructed frames stored in
118 time domain history buffer.
119
120 The equation used for IIR filter is as following.
121
122            y(n) = weight * x(n - delay)
123
124    where   y(n) ----- predicted time domain signals
125            x(n) ----- reconstructed time domain signals
126            weight ----- LTP coefficient
127            delay ----- optimal delay from 0 to 2047
128
129------------------------------------------------------------------------------
130 REQUIREMENTS
131
132 None
133
134------------------------------------------------------------------------------
135 REFERENCES
136
137 (1) ISO/IEC 14496-3:1999(E)
138     Part 3: Audio
139        Subpart 4.6.6   Long Term Prediction (LTP)
140
141 (2) MPEG-2 NBC Audio Decoder
142     "This software module was originally developed by Nokia in the course
143     of development of the MPEG-2 AAC/MPEG-4 Audio standard ISO/IEC13818-7,
144     14496-1, 2 and 3. This software module is an implementation of a part
145     of one or more MPEG-2 AAC/MPEG-4 Audio tools as specified by the MPEG-2
146     aac/MPEG-4 Audio standard. ISO/IEC  gives users of the MPEG-2aac/MPEG-4
147     Audio standards free license to this software module or modifications
148     thereof for use in hardware or software products claiming conformance
149     to the MPEG-2 aac/MPEG-4 Audio  standards. Those intending to use this
150     software module in hardware or software products are advised that this
151     use may infringe existing patents. The original developer of this
152     software module, the subsequent editors and their companies, and ISO/IEC
153     have no liability for use of this software module or modifications
154     thereof in an implementation. Copyright is not released for non MPEG-2
155     aac/MPEG-4 Audio conforming products. The original developer retains
156     full right to use the code for the developer's own purpose, assign or
157     donate the code to a third party and to inhibit third party from using
158     the code for non MPEG-2 aac/MPEG-4 Audio conforming products. This
159     copyright notice must be included in all copies or derivative works.
160     Copyright (c)1997.
161
162------------------------------------------------------------------------------
163 PSEUDO-CODE
164
165    pPredicted_samples = &predicted_samples[0];
166
167    weight = codebook[weight_index];
168
169    IF (win_seq != EIGHT_SHORT_SEQUENCE)
170    THEN
171
172        block_length = frame_length << 1;
173
174        lag = delay[0];
175
176        j = block_length - lag;
177
178        IF (lag < frame_length)
179        THEN
180
181            num_samples = frame_length + lag;
182
183        ELSE
184
185            num_samples = block_length;
186
187        ENDIF
188
189        pBuffer = &buffer[j];
190
191        FOR (i = num_samples; i>0; i--)
192
193            *pPredicted_samples = weight * (*pBuffer);
194            pPredicted_samples = pPredicted_samples + 1;
195            pBuffer = pBuffer + 1;
196
197        ENDFOR
198
199        FOR (i = block_length - num_samples; i>0; i--)
200
201            *pPredicted_samples = 0;
202            pPredicted_samples = pPredicted_samples + 1;
203
204        ENDFOR
205
206    ELSE
207
208        FOR (wnd = 0; wnd < short_window_num; wnd++)
209
210            IF (win_prediction_used[wnd] != FALSE)
211            THEN
212
213                delay[wnd] = delay[0] + ltp_short_lag[wnd];
214
215                lag = delay[wnd];
216
217                j = wnd*short_block_length - lag;
218
219                IF (lag < short_frame_length)
220                THEN
221
222                    num_samples = short_frame_length + lag;
223
224                ELSE
225
226                    num_samples = short_block_length;
227
228                ENDIF
229
230                pBuffer = &buffer[j];
231
232                FOR (i = num_samples; i>0; i--)
233
234                    *pPredicted_samples = weight * (*pBuffer);
235                    pPredicted_samples = pPredicted_samples + 1;
236                    pBuffer = pBuffer + 1;
237
238                ENDFOR
239
240                FOR (i = short_block_length - num_samples; i>0; i--)
241
242                    *pPredicted_samples = 0;
243                    pPredicted_samples = pPredicted_samples + 1;
244
245                ENDFOR
246
247            ELSE
248
249                CALL pv_memset(
250                        pPredicted_samples,
251                        0,
252                        sizeof(*pPredicted_samples)*short_block_length);
253                MODIFYING (predicted_samples[]);
254
255                pPredicted_samples = pPredicted_samples + short_block_length;
256
257            ENDIF [ IF (win_prediction_used[wnd] != FALSE) ]
258
259        ENDFOR [ FOR (wnd=0; wnd<short_window_num; wnd++) ]
260
261    ENDIF [ IF (win_seq != EIGHT_SHORT_SEQUENCE) ]
262
263    RETURN
264
265------------------------------------------------------------------------------
266 RESOURCES USED
267   When the code is written for a specific target processor the
268     the resources used should be documented below.
269
270 STACK USAGE: [stack count for this module] + [variable to represent
271          stack usage for each subroutine called]
272
273     where: [stack usage variable] = stack usage for [subroutine
274         name] (see [filename].ext)
275
276 DATA MEMORY USED: x words
277
278 PROGRAM MEMORY USED: x words
279
280 CLOCK CYCLES: [cycle count equation for this module] + [variable
281           used to represent cycle count for each subroutine
282           called]
283
284     where: [cycle count variable] = cycle count for [subroutine
285        name] (see [filename].ext)
286
287------------------------------------------------------------------------------
288*/
289
290
291/*----------------------------------------------------------------------------
292; INCLUDES
293----------------------------------------------------------------------------*/
294#include "pv_audio_type_defs.h"
295#include "e_window_sequence.h"
296#include "ltp_common_internal.h"
297#include "long_term_prediction.h"
298#include "aac_mem_funcs.h"
299#include "pv_normalize.h"
300#include "window_block_fxp.h"
301
302
303/*----------------------------------------------------------------------------
304; MACROS
305; Define module specific macros here
306----------------------------------------------------------------------------*/
307
308/*----------------------------------------------------------------------------
309; DEFINES
310; Include all pre-processor statements here. Include conditional
311; compile variables also.
312----------------------------------------------------------------------------*/
313
314/*----------------------------------------------------------------------------
315; LOCAL FUNCTION DEFINITIONS
316; Function Prototype declaration
317----------------------------------------------------------------------------*/
318
319/*----------------------------------------------------------------------------
320; LOCAL STORE/BUFFER/POINTER DEFINITIONS
321; Variable declaration - defined here and used outside this module
322----------------------------------------------------------------------------*/
323/* Purpose: Codebook for LTP weight coefficients. Stored in Q15 format */
324const UInt codebook[CODESIZE] =
325{
326    18705,  /* 0 */
327    22827,  /* 1 */
328    26641,  /* 2 */
329    29862,  /* 3 */
330    32273,  /* 4 */
331    34993,  /* 5 */
332    39145,  /* 6 */
333    44877   /* 7 */
334};
335
336/*----------------------------------------------------------------------------
337; EXTERNAL FUNCTION REFERENCES
338; Declare functions defined elsewhere and referenced in this module
339----------------------------------------------------------------------------*/
340
341/*----------------------------------------------------------------------------
342; EXTERNAL GLOBAL STORE/BUFFER/POINTER REFERENCES
343; Declare variables used in this module but defined elsewhere
344----------------------------------------------------------------------------*/
345
346/*----------------------------------------------------------------------------
347; FUNCTION CODE
348----------------------------------------------------------------------------*/
349Int long_term_prediction(
350    WINDOW_SEQUENCE     win_seq,
351    const Int           weight_index,
352    const Int           delay[],
353    const Int16         buffer[],
354    const Int           buffer_offset,
355    const Int32         time_quant[],
356    Int32         predicted_samples[],    /* Q15 */
357    const Int           frame_length)
358{
359    /*----------------------------------------------------------------------------
360    ; Define all local variables
361    ----------------------------------------------------------------------------*/
362    /*
363     * Window index
364     *
365     * Int wnd;
366     *
367     * will be enabled when short window information is available.
368     */
369
370    /* Pointer to time domain history buffer */
371
372    const Int16 *pBuffer;
373
374    const Int32 *pTimeQuant = time_quant;
375
376    /* Pointer to array containing predicted samples */
377    Int32 *pPredicted_samples;
378
379    Int32   test;
380    Int32   datum;
381
382    /* IIR coefficient with Q15 format */
383    UInt    weight;
384
385    /* Length of one block (two frames) */
386    Int     block_length;
387
388    Int     shift;
389    Int     k;
390    Int     ltp_buffer_index;
391    Int     jump_point;
392    Int     lag;
393    Int     num_samples;
394
395    Int32   max = 0;
396
397    /*----------------------------------------------------------------------------
398    ; Function body here
399    ----------------------------------------------------------------------------*/
400    /* Initialize pointers */
401    pPredicted_samples = &predicted_samples[0];
402
403    weight = codebook[weight_index];
404
405    /****************************************/
406    /* LTP decoding process for long window */
407    /****************************************/
408
409    if (win_seq != EIGHT_SHORT_SEQUENCE)
410    {
411        /****************************************************/
412        /* Prediction based on previous time domain signals */
413        /****************************************************/
414        block_length = frame_length << 1;
415
416        /* Calculate time lag for 1-tap IIR filter */
417        lag = delay[0];
418
419        ltp_buffer_index = block_length - lag;
420
421        /* Calculate number of samples used in IIR filter */
422        if (lag < frame_length)
423        {
424            num_samples = frame_length + lag;
425        }
426        else
427        {
428            num_samples = block_length;
429        }
430
431
432        /*
433         * Calculate the predicted time domain signals from the
434         * reconstructed time domain signals of previous frames.
435         */
436
437        /* The data is stored in TWO buffers, either as...
438         *
439         *                                       [   t ==  0  ]
440         *
441         * [   t == -1   ][   t == -2   ]
442         *
443         * OR...
444         *                                       [   t ==  0  ]
445         *
446         * [   t == -2   ][   t == -1   ]
447         *
448         *
449         *
450         * In the first case, all of the buffers are non-contiguous,
451         * and each must be handled separately.  Code for this first case
452         * will function correctly for both cases.
453         *
454         * In the second case, the buffers storing t == -2, and t == -1
455         * data are contiguous, and an optimization could take advantage
456         * of this, at the cost of an increase in code size for this function.
457         */
458
459        /* Decrement block_length by num_samples.  This is important
460         * for the loop at the end of the "ACCESS DATA IN THE LTP BUFFERS"
461         * section that sets all remaining samples in the block to zero.
462         */
463
464        block_length -= num_samples;
465
466
467
468
469
470
471        /*
472         ************************************ ACCESS DATA IN THE LTP BUFFERS
473         */
474
475        /*
476         * This section of the code handles the t == -2
477         * buffer, which corresponds to 0 <= ltp_buffer_index < 1024
478         *
479         * BUFFER t == -2
480         *
481         * [0][][][][][][][][][][][...][][][][][][][][][][][][1023]
482         *
483         */
484
485        jump_point = (frame_length - ltp_buffer_index);
486
487        if (jump_point > 0)
488        {
489            pBuffer = &(buffer[ltp_buffer_index + buffer_offset]);
490
491            for (k = jump_point; k > 0; k--)
492            {
493                /* Q15 = Q15 * Q0 */
494                test = (Int32) weight * (*(pBuffer++));
495                *(pPredicted_samples++) =  test;
496                max                   |= (test >> 31) ^ test;
497            }
498
499            num_samples -= jump_point;
500
501            ltp_buffer_index += jump_point;
502        }
503
504        /*
505         * This section of the code handles the t == -1
506         * buffer, which corresponds to 1024 <= ltp_buffer_index < 2048
507         *
508         * BUFFER t == -1
509         *
510         * [1024][][][][][][][][][][][...][][][][][][][][][][][][2047]
511         *
512         */
513
514        jump_point = 2 * frame_length - ltp_buffer_index;
515
516        pBuffer = &(buffer[ltp_buffer_index - buffer_offset]);
517
518        if (num_samples < jump_point)
519        {
520            jump_point = num_samples;
521        }
522
523        for (k = jump_point; k > 0; k--)
524        {
525            /* Q15 = Q15 * Q0 */
526            test = (Int32) weight * (*(pBuffer++));
527            *(pPredicted_samples++) =  test;
528            max                   |= (test >> 31) ^ test;
529        }
530
531        num_samples -= jump_point;
532
533        ltp_buffer_index += jump_point;
534
535        /*
536         * This section of the code handles the t == 0
537         * buffer, which corresponds to 2048 <= ltp_buffer_index < 3072
538         *
539         * BUFFER t == 0
540         *
541         * [2048][][][][][][][][][][][...][][][][][][][][][][][][3071]
542         *
543         */
544        for (k = num_samples; k > 0; k--)
545        {
546
547            datum = *(pTimeQuant++) >> SCALING;
548
549            /*
550             * Limit the values in the 32-bit filterbank's buffer to
551             * 16-bit resolution.
552             *
553             * Value's greater than 32767 or less than -32768 are saturated
554             * to 32767 and -32768, respectively.
555             */
556
557            test                    = (Int32)datum * weight;
558            *(pPredicted_samples++) =  test;
559            max                    |= (test >> 31) ^ test;
560
561        }
562
563        /* Set any remaining samples in the block to 0. */
564
565        pv_memset(
566            pPredicted_samples,
567            0,
568            block_length*sizeof(*pPredicted_samples));
569
570    } /* if (win_seq != EIGHT_SHORT_SEQUENCE) */
571
572
573    /*****************************************/
574    /* LTP decoding process for short window */
575    /*****************************************/
576
577    /*
578     * For short window LTP, since there is no "ltp_short_lag"
579     * information being passed, the following code for short
580     * window LTP will be applied in the future when those
581     * information are available.
582     */
583
584    /*
585     *----------------------------------------------------------------------------
586     *  else
587     *  {
588     *      for (wnd = 0; wnd < short_window_num; wnd++)
589     *      {
590     *          if (win_prediction_used[wnd] != FALSE)
591     *          {
592     *              delay[wnd] = delay[0] + ltp_short_lag[wnd];
593     *
594     *              lag = delay[wnd];
595     *
596     *              j = wnd*short_block_length - lag;
597     *
598     *              if (lag < short_frame_length)
599     *              {
600     *                  num_samples = short_frame_length + lag;
601     *              }
602     *              else
603     *              {
604     *                  num_samples = short_block_length;
605     *              }
606     *
607     *              pBuffer = &buffer[j];
608     *
609     *              for(i = num_samples; i>0; i--)
610     *              {
611     *                  *(pPredicted_samples++) = weight * (*(pBuffer++));
612     *              }
613     *
614     *              for(i = short_block_length - num_samples; i>0; i--)
615     *              {
616     *                  *(pPredicted_samples++) = 0;
617     *              }
618     *          }
619     *          else
620     *          {
621     *              pv_memset(
622     *                  pPredicted_samples,
623     *                  0,
624     *                  sizeof(*pPredicted_samples)*short_block_length);
625     *
626     *              pPredicted_samples += short_block_length;
627     *          }
628     *      }
629     *  }
630     *----------------------------------------------------------------------------
631     */
632
633    shift = 16 - pv_normalize(max);
634
635    if (shift < 0)
636    {
637        shift = 0;
638    }
639
640    /*----------------------------------------------------------------------------
641    ; Return nothing or data or data pointer
642    ----------------------------------------------------------------------------*/
643    return (shift);
644} /* long_term_prediction */
645
646
647
648
649