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 Filename: sbr_generate_high_freq.c
21
22------------------------------------------------------------------------------
23 REVISION HISTORY
24
25
26 Who:                                   Date: MM/DD/YYYY
27 Description:
28
29------------------------------------------------------------------------------
30 INPUT AND OUTPUT DEFINITIONS
31
32
33
34------------------------------------------------------------------------------
35 FUNCTION DESCRIPTION
36
37    HF generator with built-in QMF bank inverse filtering function
38
39------------------------------------------------------------------------------
40 REQUIREMENTS
41
42
43------------------------------------------------------------------------------
44 REFERENCES
45
46SC 29 Software Copyright Licencing Disclaimer:
47
48This software module was originally developed by
49  Coding Technologies
50
51and edited by
52  -
53
54in the course of development of the ISO/IEC 13818-7 and ISO/IEC 14496-3
55standards for reference purposes and its performance may not have been
56optimized. This software module is an implementation of one or more tools as
57specified by the ISO/IEC 13818-7 and ISO/IEC 14496-3 standards.
58ISO/IEC gives users free license to this software module or modifications
59thereof for use in products claiming conformance to audiovisual and
60image-coding related ITU Recommendations and/or ISO/IEC International
61Standards. ISO/IEC gives users the same free license to this software module or
62modifications thereof for research purposes and further ISO/IEC standardisation.
63Those intending to use this software module in products are advised that its
64use may infringe existing patents. ISO/IEC have no liability for use of this
65software module or modifications thereof. Copyright is not released for
66products that do not conform to audiovisual and image-coding related ITU
67Recommendations and/or ISO/IEC International Standards.
68The original developer retains full right to modify and use the code for its
69own purpose, assign or donate the code to a third party and to inhibit third
70parties from using the code for products that do not conform to audiovisual and
71image-coding related ITU Recommendations and/or ISO/IEC International Standards.
72This copyright notice must be included in all copies or derivative works.
73Copyright (c) ISO/IEC 2002.
74
75------------------------------------------------------------------------------
76 PSEUDO-CODE
77
78------------------------------------------------------------------------------
79*/
80
81
82/*----------------------------------------------------------------------------
83; INCLUDES
84----------------------------------------------------------------------------*/
85#ifdef AAC_PLUS
86
87
88
89#include    "sbr_generate_high_freq.h"
90#include    "calc_auto_corr.h"
91#include    "sbr_inv_filt_levelemphasis.h"
92#include    "pv_div.h"
93#include    "fxp_mul32.h"
94#include    "aac_mem_funcs.h"
95#include    "sbr_constants.h"
96
97/*----------------------------------------------------------------------------
98; MACROS
99; Define module specific macros here
100----------------------------------------------------------------------------*/
101
102
103/*----------------------------------------------------------------------------
104; DEFINES
105; Include all pre-processor statements here. Include conditional
106; compile variables also.
107----------------------------------------------------------------------------*/
108
109/*----------------------------------------------------------------------------
110; LOCAL FUNCTION DEFINITIONS
111; Function Prototype declaration
112----------------------------------------------------------------------------*/
113
114#ifdef __cplusplus
115extern "C"
116{
117#endif
118
119    void high_freq_coeff_LC(Int32 sourceBufferReal[][32],
120    Int32 *alphar[2],
121    Int32 *degreeAlias,
122    Int32 *v_k_master,
123    Int32 *scratch_mem);
124
125
126    void high_freq_generation_LC(Int32 sourceBufferReal[][32],
127                                 Int32 *targetBufferReal,
128                                 Int32 *alphar[2],
129                                 Int32 *degreeAlias,
130                                 Int32 *invFiltBandTable,
131                                 Int32 targetStopBand,
132                                 Int32 patchDistance,
133                                 Int32 numBandsInPatch,
134                                 Int32 startSample,
135                                 Int32 slopeLength,
136                                 Int32 stopSample,
137                                 Int32 *BwVector,
138                                 Int32 sbrStartFreqOffset);
139
140
141#ifdef HQ_SBR
142
143    void high_freq_coeff(Int32 sourceBufferReal[][32],
144                         Int32 sourceBufferImag[][32],
145                         Int32 *alphar[2],
146                         Int32 *alphai[2],
147                         Int32 *v_k_master);
148
149    void high_freq_generation(Int32 sourceBufferReal[][32],
150                              Int32 sourceBufferImag[][32],
151                              Int32 *targetBufferReal,
152                              Int32 *targetBufferImag,
153                              Int32 *alphar[2],
154                              Int32 *alphai[2],
155                              Int32 *invFiltBandTable,
156                              Int32 targetStopBand,
157                              Int32 patchDistance,
158                              Int32 numBandsInPatch,
159                              Int32 startSample,
160                              Int32 slopeLength,
161                              Int32 stopSample,
162                              Int32 *BwVector,
163                              Int32 sbrStartFreqOffset);
164
165
166#endif
167
168#ifdef __cplusplus
169}
170#endif
171
172/*----------------------------------------------------------------------------
173; LOCAL STORE/BUFFER/POINTER DEFINITIONS
174; Variable declaration - defined here and used outside this module
175----------------------------------------------------------------------------*/
176
177/*----------------------------------------------------------------------------
178; EXTERNAL FUNCTION REFERENCES
179; Declare functions defined elsewhere and referenced in this module
180----------------------------------------------------------------------------*/
181
182/*----------------------------------------------------------------------------
183; EXTERNAL GLOBAL STORE/BUFFER/POINTER REFERENCES
184; Declare variables used in this module but defined elsewhere
185----------------------------------------------------------------------------*/
186
187/*----------------------------------------------------------------------------
188; FUNCTION CODE
189----------------------------------------------------------------------------*/
190
191void sbr_generate_high_freq(Int32 sourceBufferReal[][32],
192                            Int32 sourceBufferImag[][32],
193                            Int32 *targetBufferReal,
194                            Int32 *targetBufferImag,
195                            INVF_MODE *invFiltMode,
196                            INVF_MODE *prevInvFiltMode,
197                            Int32 *invFiltBandTable,
198                            Int32 noInvFiltBands,
199                            Int32 highBandStartSb,
200                            Int32  *v_k_master,
201                            Int32 numMaster,
202                            Int32 fs,
203                            Int32   *frameInfo,
204                            Int32 *degreeAlias,
205                            Int32  scratch_mem[][64],
206                            Int32  BwVector[MAX_NUM_PATCHES],
207                            Int32  BwVectorOld[MAX_NUM_PATCHES],
208                            struct PATCH *Patch,
209                            Int32 LC_flag,
210                            Int32 *highBandStopSb)
211{
212    Int32    i;
213    Int32    patch;
214    Int32    startSample;
215    Int32    stopSample;
216    Int32    goalSb;
217    Int32    targetStopBand;
218    Int32    sourceStartBand;
219    Int32    patchDistance;
220    Int32    numBandsInPatch;
221    Int32    sbrStartFreqOffset;
222
223    Int32  *alphar[2];
224    Int32  *alphai[2];
225
226    Int32    lsb = v_k_master[0];                           /* Lowest subband related to the synthesis filterbank */
227    Int32    usb = v_k_master[numMaster];                   /* Stop subband related to the synthesis filterbank */
228    Int32  xoverOffset = highBandStartSb - v_k_master[0]; /* Calculate distance in subbands between k0 and kx */
229
230
231
232    Int    slopeLength = 0;
233
234    Int32 firstSlotOffs = frameInfo[1];
235    Int32 lastSlotOffs  = frameInfo[frameInfo[0] + 1] - 16;
236
237
238    alphar[0] = scratch_mem[0];
239    alphar[1] = scratch_mem[1];
240    alphai[0] = scratch_mem[2];
241    alphai[1] = scratch_mem[3];
242
243
244    startSample = (firstSlotOffs << 1);
245    stopSample  = (lastSlotOffs << 1) + 32;
246
247
248    sbr_inv_filt_levelemphasis(invFiltMode,
249                               prevInvFiltMode,
250                               noInvFiltBands,
251                               BwVector,
252                               BwVectorOld);
253
254
255    if (LC_flag == ON)
256    {
257        /* Set subbands to zero  */
258
259        pv_memset((void *)&targetBufferReal[startSample*SBR_NUM_BANDS],
260                  0,
261                  (stopSample - startSample)*SBR_NUM_BANDS*sizeof(targetBufferReal[0]));
262
263        high_freq_coeff_LC(sourceBufferReal,
264                           alphar,
265                           degreeAlias,
266                           v_k_master,
267                           scratch_mem[4]);
268    }
269#ifdef HQ_SBR
270    else
271    {
272        /* Set subbands to zero  */
273
274        pv_memset((void *)&targetBufferReal[startSample*SBR_NUM_BANDS],
275                  0,
276                  (stopSample - startSample)*SBR_NUM_BANDS*sizeof(targetBufferReal[0]));
277        pv_memset((void *)&targetBufferImag[startSample*SBR_NUM_BANDS],
278                  0,
279                  (stopSample - startSample)*SBR_NUM_BANDS*sizeof(targetBufferImag[0]));
280
281        high_freq_coeff(sourceBufferReal,
282                        sourceBufferImag,
283                        alphar,
284                        alphai,
285                        v_k_master);
286
287    }
288#endif     /*  #ifdef HQ_SBR */
289
290
291
292
293    /*
294     * Initialize the patching parameter
295     */
296    switch (fs)
297
298    {
299            /*
300             *  goalSb = (int)( 2.048e6f / fs + 0.5f );
301             */
302        case 48000:
303            goalSb = 43;  /* 16 kHz band */
304            break;
305        case 32000:
306            goalSb = 64;  /* 16 kHz band */
307            break;
308        case 24000:
309            goalSb = 85;  /* 16 kHz band */
310            break;
311        case 22050:
312            goalSb = 93;  /* 16 kHz band */
313            break;
314        case 16000:
315            goalSb = 128;  /* 16 kHz band */
316            break;
317        case 44100:
318        default:
319            goalSb = 46;  /* 16 kHz band */
320            break;
321    }
322
323    i = 0;
324
325    if (goalSb > v_k_master[0])
326    {
327        if (goalSb < v_k_master[numMaster])
328        {
329            while (v_k_master[i] < goalSb)
330            {
331                i++;
332            }
333        }
334        else
335        {
336            i = numMaster;
337        }
338    }
339
340    goalSb =  v_k_master[i];
341
342    /* First patch */
343    sourceStartBand = xoverOffset + 1;
344    targetStopBand = lsb + xoverOffset;
345
346    /* even (odd) numbered channel must be patched to even (odd) numbered channel */
347    patch = 0;
348
349
350    sbrStartFreqOffset = targetStopBand;
351
352    while (targetStopBand < usb)
353    {
354        Patch->targetStartBand[patch] = targetStopBand;
355
356        numBandsInPatch = goalSb - targetStopBand;                   /* get the desired range of the patch */
357
358        if (numBandsInPatch >= lsb - sourceStartBand)
359        {
360            /* desired number bands are not available -> patch whole source range */
361            patchDistance   = targetStopBand - sourceStartBand;        /* get the targetOffset */
362            patchDistance   = patchDistance & ~1;                      /* rounding off odd numbers and make all even */
363            numBandsInPatch = lsb - (targetStopBand - patchDistance);
364
365            if (targetStopBand + numBandsInPatch > v_k_master[0])
366            {
367                i = numMaster;
368                if (targetStopBand + numBandsInPatch < v_k_master[numMaster])
369                {
370                    while (v_k_master[i] > targetStopBand + numBandsInPatch)
371                    {
372                        i--;
373                    }
374                }
375            }
376            else
377            {
378                i = 0;
379            }
380            numBandsInPatch =  v_k_master[i] - targetStopBand;
381        }
382
383        /* desired number bands are available -> get the minimal even patching distance */
384        patchDistance   = numBandsInPatch + targetStopBand - lsb;  /* get minimal distance */
385        patchDistance   = (patchDistance + 1) & ~1;                /* rounding up odd numbers and make all even */
386
387        /* All patches but first */
388        sourceStartBand = 1;
389
390        /* Check if we are close to goalSb */
391        if (goalSb - (targetStopBand + numBandsInPatch) < 3)
392        { /* MPEG doc */
393            goalSb = usb;
394        }
395
396
397        if ((numBandsInPatch < 3) && (patch > 0))
398        {
399            if (LC_flag == ON)
400            {
401
402                pv_memset((void *) &degreeAlias[targetStopBand], 0, numBandsInPatch*sizeof(*degreeAlias));
403            }
404            break;
405        }
406
407        if (numBandsInPatch <= 0)
408        {
409            continue;
410        }
411
412
413        /*
414         *  High Frequency generation
415         */
416
417        if (LC_flag == ON)
418        {
419
420            high_freq_generation_LC(sourceBufferReal,
421                                    (Int32 *)targetBufferReal,
422                                    alphar,
423                                    degreeAlias,
424                                    invFiltBandTable,
425                                    targetStopBand,
426                                    patchDistance,
427                                    numBandsInPatch,
428                                    startSample,
429                                    slopeLength,
430                                    stopSample,
431                                    BwVector,
432                                    sbrStartFreqOffset);
433
434        }
435#ifdef HQ_SBR
436        else
437        {
438
439            high_freq_generation(sourceBufferReal,
440                                 sourceBufferImag,
441                                 (Int32 *)targetBufferReal,
442                                 (Int32 *)targetBufferImag,
443                                 alphar,
444                                 alphai,
445                                 invFiltBandTable,
446                                 targetStopBand,
447                                 patchDistance,
448                                 numBandsInPatch,
449                                 startSample,
450                                 slopeLength,
451                                 stopSample,
452                                 BwVector,
453                                 sbrStartFreqOffset);
454
455        }
456#endif
457
458        targetStopBand += numBandsInPatch;
459
460        patch++;
461
462    }  /* targetStopBand */
463
464    Patch->noOfPatches = patch;
465
466    pv_memmove(BwVectorOld, BwVector, noInvFiltBands*sizeof(BwVector[0]));
467
468    *highBandStopSb = goalSb;
469
470
471}
472
473
474/*----------------------------------------------------------------------------
475; FUNCTION CODE
476----------------------------------------------------------------------------*/
477
478
479void high_freq_coeff_LC(Int32 sourceBufferReal[][32],
480                        Int32 *alphar[2],
481                        Int32 *degreeAlias,
482                        Int32 *v_k_master,
483                        Int32 *scratch_mem)
484{
485
486    Int32  fac;
487    Int32 *k1;
488    struct ACORR_COEFS ac;
489    struct intg_div  quotient;
490
491    Int32 temp1;
492    Int32 temp2;
493    Int32 temp3;
494    Int32 autoCorrLength;
495    Int32 loBand;
496
497    k1 = scratch_mem;
498
499
500    autoCorrLength = 38;
501
502    for (loBand = 1; loBand < v_k_master[0]; loBand++)
503    {
504
505        calc_auto_corr_LC(&ac,
506                          sourceBufferReal,
507                          loBand,
508                          autoCorrLength);
509
510        if (ac.r11r && ac.det)
511        {
512
513            pv_div(ac.r01r, ac.r11r, &quotient);
514
515            fac = -(quotient.quotient >> 2);   /*  Q28 */
516
517            if (quotient.shift_factor > 0)
518            {
519                fac >>= quotient.shift_factor;    /* Q28 */
520            }
521            else if (quotient.shift_factor < 0)
522            {
523                if (quotient.shift_factor > -4)     /* |fac| < 8 */
524                {
525                    fac <<= (-quotient.shift_factor); /* Q28 */
526                }
527                else
528                {
529                    fac = 0x80000000;     /* overshoot possible fac = -8 */
530                }
531            }
532
533            /*
534             *  prevent for overflow of reflection coefficients
535             */
536            if (quotient.shift_factor > 0)
537            {
538                k1[loBand] = - quotient.quotient >> quotient.shift_factor;
539            }
540            else if (quotient.shift_factor == 0)
541            {
542                if (quotient.quotient >= 0x40000000)
543                {
544                    k1[loBand] = (Int32)0xC0000000;   /* -1.0 in Q30  */
545                }
546                else if (quotient.quotient <= (Int32)0xC0000000)
547                {
548                    k1[loBand] = 0x40000000;   /*  1.0 in Q30  */
549                }
550                else
551                {
552                    k1[loBand] = -quotient.quotient;
553                }
554            }
555            else
556            {
557                if (quotient.quotient > 0)
558                {
559                    k1[loBand] = (Int32)0xC0000000;   /* -1.0 in Q30  */
560                }
561                else
562                {
563                    k1[loBand] = 0x40000000;   /*  1.0 in Q30  */
564                }
565            }
566            /*
567             *   alphar[1][loBand] = ( ac.r01r * ac.r12r - ac.r02r * ac.r11r ) / ac.det;
568             */
569
570            temp1  = -fxp_mul32_Q30(ac.r02r, ac.r11r);
571            temp1  =  fxp_mac32_Q30(ac.r01r, ac.r12r, temp1);
572
573            temp2 = ac.det;
574            temp3 = temp1 > 0 ? temp1 : -temp1;
575            temp2 = temp2 > 0 ? temp2 : -temp2;
576
577            /* prevent for shootovers */
578            if ((temp3 >> 2) >= temp2 || fac == (Int32)0x80000000)
579            {
580                alphar[0][loBand] = 0;
581                alphar[1][loBand] = 0;
582            }
583            else
584            {
585                pv_div(temp1, ac.det, &quotient);
586                /*
587                 *  alphar[1][loBand] is lesser than 4.0
588                 */
589                alphar[1][loBand] = quotient.quotient;
590                quotient.shift_factor += 2;             /* Q28 */
591
592                if (quotient.shift_factor > 0)
593                {
594                    alphar[1][loBand] >>= quotient.shift_factor;    /* Q28 */
595                }
596                else if (quotient.shift_factor < 0)     /* at this point can only be -1 */
597                {
598                    alphar[1][loBand] <<= (-quotient.shift_factor); /* Q28 */
599                }
600
601                /*
602                 *  alphar[0][loBand] = - ( ac.r01r + alphar[1][loBand] * ac.r12r ) / ac.r11r;
603                 */
604
605                pv_div(ac.r12r, ac.r11r, &quotient);
606
607                temp3 = (quotient.quotient >> 2);       /*  Q28 */
608
609                if (quotient.shift_factor > 0)
610                {
611                    temp3 >>= quotient.shift_factor;    /* Q28 */
612                }
613                else if (quotient.shift_factor < 0)
614                {
615                    temp3 <<= (-quotient.shift_factor); /* Q28 */
616                }
617
618                alphar[0][loBand] = fac - fxp_mul32_Q28(alphar[1][loBand], temp3) ;    /* Q28 */
619
620                if ((alphar[0][loBand] >= 0x40000000) || (alphar[0][loBand] <= (Int32)0xC0000000))
621                {
622                    alphar[0][loBand] = 0;
623                    alphar[1][loBand] = 0;
624                }
625
626            }
627
628        }
629        else
630        {
631            alphar[0][loBand] = 0;
632            alphar[1][loBand] = 0;
633
634            k1[loBand] = 0;
635        }
636
637    }
638
639    k1[0] = 0;
640    degreeAlias[1] = 0;
641    for (loBand = 2; loBand < v_k_master[0]; loBand++)
642    {
643        degreeAlias[loBand] = 0;
644        if ((!(loBand & 1)) && (k1[loBand] < 0))
645        {
646            if (k1[loBand-1] < 0)
647            { // 2-CH Aliasing Detection
648                degreeAlias[loBand]   = 0x40000000;
649                if (k1[loBand-2] > 0)
650                { // 3-CH Aliasing Detection
651                    degreeAlias[loBand-1] = 0x40000000 - fxp_mul32_Q30(k1[loBand-1], k1[loBand-1]);
652
653                }
654            }
655            else if (k1[loBand-2] > 0)
656            { // 3-CH Aliasing Detection
657                degreeAlias[loBand] = 0x40000000 - fxp_mul32_Q30(k1[loBand-1], k1[loBand-1]);
658            }
659        }
660        if ((loBand & 1) && (k1[loBand] > 0))
661        {
662            if (k1[loBand-1] > 0)
663            { // 2-CH Aliasing Detection
664                degreeAlias[loBand]   = 0x40000000;
665                if (k1[loBand-2] < 0)
666                { // 3-CH Aliasing Detection
667                    degreeAlias[loBand-1] = 0x40000000 - fxp_mul32_Q30(k1[loBand-1], k1[loBand-1]);
668                }
669            }
670            else if (k1[loBand-2] < 0)
671            { // 3-CH Aliasing Detection
672                degreeAlias[loBand] = 0x40000000 - fxp_mul32_Q30(k1[loBand-1], k1[loBand-1]);
673            }
674        }
675    }
676
677}
678
679
680/*----------------------------------------------------------------------------
681; FUNCTION CODE
682----------------------------------------------------------------------------*/
683
684void high_freq_generation_LC(Int32 sourceBufferReal[][32],
685                             Int32 *targetBufferReal,
686                             Int32 *alphar[2],
687                             Int32 *degreeAlias,
688                             Int32 *invFiltBandTable,
689                             Int32 targetStopBand,
690                             Int32 patchDistance,
691                             Int32 numBandsInPatch,
692                             Int32 startSample,
693                             Int32 slopeLength,
694                             Int32 stopSample,
695                             Int32 *BwVector,
696                             Int32 sbrStartFreqOffset)
697{
698
699    Int32  temp1;
700    Int32  temp2;
701    Int32  temp3;
702
703
704    Int32  a0r;
705    Int32  a1r;
706    Int32  i;
707    Int32  bw;
708    Int32  hiBand;
709    Int32  bwIndex;
710    Int32  loBand;
711    Int32  j;
712
713    bwIndex = 0;
714
715    for (hiBand = targetStopBand; hiBand < targetStopBand + numBandsInPatch; hiBand++)
716    {
717        loBand = hiBand - patchDistance;
718
719        if (hiBand != targetStopBand)
720        {
721            degreeAlias[hiBand] = degreeAlias[loBand];
722        }
723        else
724        {
725            degreeAlias[hiBand] = 0;
726        }
727
728        while (hiBand >= invFiltBandTable[bwIndex])
729        {
730            bwIndex++;
731        }
732
733        bw = BwVector[bwIndex];
734
735        /*
736         *  Inverse Filtering
737         */
738
739
740        j = hiBand - sbrStartFreqOffset;
741
742        if (bw > 0 && (alphar[0][loBand] | alphar[1][loBand]))
743        {
744            /* Apply current bandwidth expansion factor */
745            a0r = fxp_mul32_Q29(bw, alphar[0][loBand]);
746
747            bw  = fxp_mul32_Q31(bw, bw) << 2;
748
749            a1r = fxp_mul32_Q28(bw, alphar[1][loBand]);
750
751            i = startSample + slopeLength;
752
753            temp1 = sourceBufferReal[i    ][loBand];
754            temp2 = sourceBufferReal[i - 1][loBand];
755            temp3 = sourceBufferReal[i - 2][loBand];
756
757            for (; i < stopSample + slopeLength - 1; i++)
758            {
759
760
761                targetBufferReal[i*SBR_NUM_BANDS + j] = temp1 + fxp_mul32_Q28(a0r, temp2)  +
762                                                        fxp_mul32_Q28(a1r, temp3);
763
764
765                temp3 = temp2;
766                temp2 = temp1;
767                temp1 = sourceBufferReal[i + 1][loBand];
768            }
769            targetBufferReal[i*SBR_NUM_BANDS + j] = temp1 + fxp_mul32_Q28(a0r, temp2)  +
770                                                    fxp_mul32_Q28(a1r, temp3);
771
772        }
773        else
774        {
775
776            for (i = startSample + slopeLength; i < stopSample + slopeLength; i++)
777            {
778                targetBufferReal[i*SBR_NUM_BANDS + j] = sourceBufferReal[i][loBand];
779            }
780        }
781
782
783    }  /* hiBand */
784
785}
786
787
788#ifdef HQ_SBR
789
790/*----------------------------------------------------------------------------
791; FUNCTION CODE
792----------------------------------------------------------------------------*/
793
794void high_freq_coeff(Int32 sourceBufferReal[][32],
795                     Int32 sourceBufferImag[][32],
796                     Int32 *alphar[2],
797                     Int32 *alphai[2],
798                     Int32 *v_k_master)
799{
800
801    Int32  overflow_flag;
802
803    Int32  temp1r;
804    Int32  temp1i;
805    Int32  temp0r;
806    Int32  temp0i;
807    Int32  loBand;
808
809    struct ACORR_COEFS ac;
810    struct intg_div  quotient;
811
812    Int32 autoCorrLength;
813
814    autoCorrLength = 38;
815
816    for (loBand = 1; loBand < v_k_master[0]; loBand++)
817    {
818
819        calc_auto_corr(&ac,
820                       sourceBufferReal,
821                       sourceBufferImag,
822                       loBand,
823                       autoCorrLength);
824
825
826        overflow_flag = 0;
827
828        if (ac.det < 1)
829        {
830            /* ---  */
831            temp1r = 0;
832            temp1i = 0;
833            alphar[1][loBand] = 0;
834            alphai[1][loBand] = 0;
835
836        }
837        else
838        {
839
840            temp1r =  fxp_mul32_Q29(ac.r01r, ac.r12r);
841            temp1r =  fxp_msu32_Q29(ac.r01i, ac.r12i, temp1r);
842            temp1r =  fxp_msu32_Q29(ac.r02r, ac.r11r, temp1r);
843
844            temp1i =  fxp_mul32_Q29(ac.r01r, ac.r12i);
845            temp1i =  fxp_msu32_Q29(ac.r02i, ac.r11r, temp1i);
846            temp1i =  fxp_mac32_Q29(ac.r01i, ac.r12r, temp1i);
847
848            pv_div(temp1r, ac.det, &quotient);
849            overflow_flag = (quotient.shift_factor < -2) ? 1 : 0;
850            temp1r = quotient.quotient >> (2 + quotient.shift_factor);   /*  Q28 */
851            pv_div(temp1i, ac.det, &quotient);
852            overflow_flag = (quotient.shift_factor < -2) ? 1 : 0;
853            temp1i = quotient.quotient >> (2 + quotient.shift_factor);   /*  Q28 */
854
855            alphar[1][loBand] = temp1r;
856            alphai[1][loBand] = temp1i;
857
858        }
859
860        if (ac.r11r == 0)
861        {
862            temp0r = 0;
863            temp0i = 0;
864            alphar[0][loBand] = 0;
865            alphai[0][loBand] = 0;
866
867        }
868        else
869        {
870            temp0r = - (ac.r01r + fxp_mul32_Q28(temp1r, ac.r12r) + fxp_mul32_Q28(temp1i, ac.r12i));
871            temp0i = - (ac.r01i + fxp_mul32_Q28(temp1i, ac.r12r) - fxp_mul32_Q28(temp1r, ac.r12i));
872
873            pv_div(temp0r, ac.r11r, &quotient);
874            overflow_flag = (quotient.shift_factor < -2) ? 1 : 0;
875            temp0r = quotient.quotient >> (2 + quotient.shift_factor);   /*  Q28 */
876            pv_div(temp0i, ac.r11r, &quotient);
877            overflow_flag = (quotient.shift_factor < -2) ? 1 : 0;
878            temp0i = quotient.quotient >> (2 + quotient.shift_factor);   /*  Q28 */
879
880            alphar[0][loBand] = temp0r;
881            alphai[0][loBand] = temp0i;
882
883        }
884
885        /* prevent for shootovers */
886
887        if (fxp_mul32_Q28((temp0r >> 2), (temp0r >> 2)) + fxp_mul32_Q28((temp0i >> 2), (temp0i >> 2)) >= 0x10000000 ||
888                fxp_mul32_Q28((temp1r >> 2), (temp1r >> 2)) + fxp_mul32_Q28((temp1i >> 2), (temp1i >> 2)) >= 0x10000000 ||
889                overflow_flag)     /*  0x10000000 == 1 in Q28 */
890
891        {
892            alphar[0][loBand] = 0;
893            alphar[1][loBand] = 0;
894            alphai[0][loBand] = 0;
895            alphai[1][loBand] = 0;
896
897        }
898    }
899}
900
901/*----------------------------------------------------------------------------
902; FUNCTION CODE
903----------------------------------------------------------------------------*/
904
905
906
907void high_freq_generation(Int32 sourceBufferReal[][32],
908                          Int32 sourceBufferImag[][32],
909                          Int32 *targetBufferReal,
910                          Int32 *targetBufferImag,
911                          Int32 *alphar[2],
912                          Int32 *alphai[2],
913                          Int32 *invFiltBandTable,
914                          Int32 targetStopBand,
915                          Int32 patchDistance,
916                          Int32 numBandsInPatch,
917                          Int32 startSample,
918                          Int32 slopeLength,
919                          Int32 stopSample,
920                          Int32 *BwVector,
921                          Int32 sbrStartFreqOffset)
922{
923    Int32  temp1_r;
924    Int32  temp2_r;
925    Int32  temp3_r;
926    Int32  temp1_i;
927    Int32  temp2_i;
928    Int32  temp3_i;
929
930
931    Int32  a0i;
932    Int32  a1i;
933    Int32  a0r;
934    Int32  a1r;
935    Int32  i;
936    Int32  bw;
937    Int32  hiBand;
938    Int32  bwIndex;
939    Int32  loBand;
940    Int32  j;
941
942
943
944    int64_t tmp;
945
946    bwIndex = 0;
947
948    for (hiBand = targetStopBand; hiBand < targetStopBand + numBandsInPatch; hiBand++)
949    {
950
951        loBand = hiBand - patchDistance;
952
953        while (hiBand >= invFiltBandTable[bwIndex])
954        {
955            bwIndex++;
956        }
957
958        bw = BwVector[bwIndex];
959
960        /*
961         *  Inverse Filtering
962         */
963
964
965        j = hiBand - sbrStartFreqOffset;
966
967        if (bw >= 0 && (alphar[0][loBand] | alphar[1][loBand] |
968                        alphai[0][loBand] | alphai[1][loBand]))
969        {
970            /* Apply current bandwidth expansion factor */
971            a0r = fxp_mul32_Q29(bw, alphar[0][loBand]);
972            a0i = fxp_mul32_Q29(bw, alphai[0][loBand]);
973
974
975            bw  = fxp_mul32_Q30(bw, bw);
976
977
978            a1r = fxp_mul32_Q28(bw, alphar[1][loBand]);
979            a1i = fxp_mul32_Q28(bw, alphai[1][loBand]);
980
981
982            i  = startSample + slopeLength;
983            j += i * SBR_NUM_BANDS;
984
985            temp1_r = sourceBufferReal[i    ][loBand];
986            temp2_r = sourceBufferReal[i - 1][loBand];
987            temp3_r = sourceBufferReal[i - 2][loBand];
988
989            temp1_i = sourceBufferImag[i    ][loBand];
990            temp2_i = sourceBufferImag[i - 1][loBand];
991            temp3_i = sourceBufferImag[i - 2][loBand];
992
993            while (i < stopSample + slopeLength)
994            {
995                tmp =  fxp_mac64_Q31(((int64_t)temp1_r << 28),  a0r, temp2_r);
996                tmp =  fxp_mac64_Q31(tmp, -a0i, temp2_i);
997                tmp =  fxp_mac64_Q31(tmp,  a1r, temp3_r);
998                targetBufferReal[j] = (Int32)(fxp_mac64_Q31(tmp, -a1i, temp3_i) >> 28);
999
1000                tmp =  fxp_mac64_Q31(((int64_t)temp1_i << 28),  a0i, temp2_r);
1001                tmp =  fxp_mac64_Q31(tmp,  a0r, temp2_i);
1002                tmp =  fxp_mac64_Q31(tmp,  a1i, temp3_r);
1003                targetBufferImag[j] = (Int32)(fxp_mac64_Q31(tmp,  a1r, temp3_i) >> 28);
1004
1005                i++;
1006                j += SBR_NUM_BANDS;
1007
1008                temp3_r  = temp2_r;
1009                temp2_r  = temp1_r;
1010                temp1_r  = sourceBufferReal[i ][loBand];
1011
1012                temp3_i  = temp2_i;
1013                temp2_i  = temp1_i;
1014                temp1_i  = sourceBufferImag[i ][loBand];
1015
1016            }
1017
1018        }
1019
1020
1021
1022        else
1023        {
1024            i = startSample + slopeLength;
1025            j += i * SBR_NUM_BANDS;
1026
1027            for (; i < stopSample + slopeLength; i++)
1028            {
1029                targetBufferReal[j] = sourceBufferReal[i][loBand];
1030                targetBufferImag[j] = sourceBufferImag[i][loBand];
1031                j += SBR_NUM_BANDS;
1032            }
1033        }
1034    }
1035}
1036
1037#endif
1038
1039
1040#endif
1041