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/****************************************************************************************
19Portions of this file are derived from the following 3GPP standard:
20
21    3GPP TS 26.173
22    ANSI-C code for the Adaptive Multi-Rate - Wideband (AMR-WB) speech codec
23    Available from http://www.3gpp.org
24
25(C) 2007, 3GPP Organizational Partners (ARIB, ATIS, CCSA, ETSI, TTA, TTC)
26Permission to distribute, modify and use this file under the standard license
27terms listed above has been obtained from the copyright holder.
28****************************************************************************************/
29/*
30------------------------------------------------------------------------------
31
32
33
34 Filename: dtx_decoder_amr_wb.cpp
35
36     Date: 05/08/2007
37
38------------------------------------------------------------------------------
39 REVISION HISTORY
40
41
42 Description:
43
44------------------------------------------------------------------------------
45 INPUT AND OUTPUT DEFINITIONS
46
47
48------------------------------------------------------------------------------
49 FUNCTION DESCRIPTION
50
51    DTX functions
52
53------------------------------------------------------------------------------
54 REQUIREMENTS
55
56
57------------------------------------------------------------------------------
58 REFERENCES
59
60------------------------------------------------------------------------------
61 PSEUDO-CODE
62
63------------------------------------------------------------------------------
64*/
65
66
67/*----------------------------------------------------------------------------
68; INCLUDES
69----------------------------------------------------------------------------*/
70
71#include "pv_amr_wb_type_defs.h"
72#include "pvamrwbdecoder_basic_op.h"
73#include "pvamrwb_math_op.h"
74#include "pvamrwbdecoder_cnst.h"
75#include "pvamrwbdecoder_acelp.h"  /* prototype of functions    */
76#include "get_amr_wb_bits.h"
77#include "dtx.h"
78
79/*----------------------------------------------------------------------------
80; MACROS
81; Define module specific macros here
82----------------------------------------------------------------------------*/
83
84
85/*----------------------------------------------------------------------------
86; DEFINES
87; Include all pre-processor statements here. Include conditional
88; compile variables also.
89----------------------------------------------------------------------------*/
90
91/*----------------------------------------------------------------------------
92; LOCAL FUNCTION DEFINITIONS
93; Function Prototype declaration
94----------------------------------------------------------------------------*/
95
96/*----------------------------------------------------------------------------
97; LOCAL STORE/BUFFER/POINTER DEFINITIONS
98; Variable declaration - defined here and used outside this module
99----------------------------------------------------------------------------*/
100
101/*----------------------------------------------------------------------------
102; EXTERNAL FUNCTION REFERENCES
103; Declare functions defined elsewhere and referenced in this module
104----------------------------------------------------------------------------*/
105
106/*----------------------------------------------------------------------------
107; EXTERNAL GLOBAL STORE/BUFFER/POINTER REFERENCES
108; Declare variables used in this module but defined elsewhere
109----------------------------------------------------------------------------*/
110
111/*----------------------------------------------------------------------------
112; FUNCTION CODE
113----------------------------------------------------------------------------*/
114/*
115 * Function    : dtx_dec_amr_wb_reset
116 */
117int16 dtx_dec_amr_wb_reset(dtx_decState * st, const int16 isf_init[])
118{
119    int16 i;
120
121
122    if (st == (dtx_decState *) NULL)
123    {
124        /* dtx_dec_amr_wb_reset invalid parameter */
125        return (-1);
126    }
127    st->since_last_sid = 0;
128    st->true_sid_period_inv = (1 << 13);      /* 0.25 in Q15 */
129
130    st->log_en = 3500;
131    st->old_log_en = 3500;
132    /* low level noise for better performance in  DTX handover cases */
133
134    st->cng_seed = RANDOM_INITSEED;
135
136    st->hist_ptr = 0;
137
138    /* Init isf_hist[] and decoder log frame energy */
139    pv_memcpy((void *)st->isf, (void *)isf_init, M*sizeof(*isf_init));
140
141    pv_memcpy((void *)st->isf_old, (void *)isf_init, M*sizeof(*isf_init));
142
143    for (i = 0; i < DTX_HIST_SIZE; i++)
144    {
145        pv_memcpy((void *)&st->isf_hist[i * M], (void *)isf_init, M*sizeof(*isf_init));
146        st->log_en_hist[i] = st->log_en;
147    }
148
149    st->dtxHangoverCount = DTX_HANG_CONST;
150    st->decAnaElapsedCount = 32767;
151
152    st->sid_frame = 0;
153    st->valid_data = 0;
154    st->dtxHangoverAdded = 0;
155
156    st->dtxGlobalState = SPEECH;
157    st->data_updated = 0;
158
159    st->dither_seed = RANDOM_INITSEED;
160    st->CN_dith = 0;
161
162    return 0;
163}
164
165
166/*
167     Table of new SPD synthesis states
168
169                           |     previous SPD_synthesis_state
170     Incoming              |
171     frame_type            | SPEECH       | DTX           | DTX_MUTE
172     ---------------------------------------------------------------
173     RX_SPEECH_GOOD ,      |              |               |
174     RX_SPEECH_PR_DEGRADED | SPEECH       | SPEECH        | SPEECH
175     ----------------------------------------------------------------
176     RX_SPEECH_BAD,        | SPEECH       | DTX           | DTX_MUTE
177     ----------------------------------------------------------------
178     RX_SID_FIRST,         | DTX          | DTX/(DTX_MUTE)| DTX_MUTE
179     ----------------------------------------------------------------
180     RX_SID_UPDATE,        | DTX          | DTX           | DTX
181     ----------------------------------------------------------------
182     RX_SID_BAD,           | DTX          | DTX/(DTX_MUTE)| DTX_MUTE
183     ----------------------------------------------------------------
184     RX_NO_DATA,           | SPEECH       | DTX/(DTX_MUTE)| DTX_MUTE
185     RX_SPARE              |(class2 garb.)|               |
186     ----------------------------------------------------------------
187*/
188
189/*----------------------------------------------------------------------------
190; FUNCTION CODE
191----------------------------------------------------------------------------*/
192
193/*
194 * Function    : dtx_dec_amr_wb
195 */
196int16 dtx_dec_amr_wb(
197    dtx_decState * st,                    /* i/o : State struct         */
198    int16 * exc2,                        /* o   : CN excitation        */
199    int16 new_state,                     /* i   : New DTX state        */
200    int16 isf[],                         /* o   : CN ISF vector        */
201    int16 ** prms
202)
203{
204    int16 log_en_index;
205    int16 ind[7];
206    int16 i, j;
207    int16 int_fac;
208    int16 gain;
209
210    int32 L_isf[M], L_log_en_int, level32, ener32;
211    int16 ptr;
212    int16 tmp_int_length;
213    int16 tmp, exp, exp0, log_en_int_e, log_en_int_m, level;
214
215    /* This function is called if synthesis state is not SPEECH the globally passed  inputs to this function
216     * are st->sid_frame st->valid_data st->dtxHangoverAdded new_state  (SPEECH, DTX, DTX_MUTE) */
217
218    if ((st->dtxHangoverAdded != 0) &&
219            (st->sid_frame != 0))
220    {
221        /* sid_first after dtx hangover period */
222        /* or sid_upd after dtxhangover        */
223
224        /* consider  twice the last frame */
225        ptr = st->hist_ptr + 1;
226
227        if (ptr == DTX_HIST_SIZE)
228            ptr = 0;
229
230        pv_memcpy((void *)&st->isf_hist[ptr * M], (void *)&st->isf_hist[st->hist_ptr * M], M*sizeof(*st->isf_hist));
231
232        st->log_en_hist[ptr] = st->log_en_hist[st->hist_ptr];
233
234        /* compute mean log energy and isf from decoded signal (SID_FIRST) */
235        st->log_en = 0;
236        for (i = 0; i < M; i++)
237        {
238            L_isf[i] = 0;
239        }
240
241        /* average energy and isf */
242        for (i = 0; i < DTX_HIST_SIZE; i++)
243        {
244            /* Division by DTX_HIST_SIZE = 8 has been done in dtx_buffer log_en is in Q10 */
245            st->log_en = add_int16(st->log_en, st->log_en_hist[i]);
246
247            for (j = 0; j < M; j++)
248            {
249                L_isf[j] = add_int32(L_isf[j], (int32)(st->isf_hist[i * M + j]));
250            }
251        }
252
253        /* st->log_en in Q9 */
254        st->log_en >>=  1;
255
256        /* Add 2 in Q9, in order to have only positive values for Pow2 */
257        /* this value is subtracted back after Pow2 function */
258        st->log_en += 1024;
259
260        if (st->log_en < 0)
261            st->log_en = 0;
262
263        for (j = 0; j < M; j++)
264        {
265            st->isf[j] = (int16)(L_isf[j] >> 3);  /* divide by 8 */
266        }
267
268    }
269
270    if (st->sid_frame != 0)
271    {
272        /* Set old SID parameters, always shift */
273        /* even if there is no new valid_data   */
274
275        pv_memcpy((void *)st->isf_old, (void *)st->isf, M*sizeof(*st->isf));
276
277        st->old_log_en = st->log_en;
278
279        if (st->valid_data != 0)           /* new data available (no CRC) */
280        {
281            /* st->true_sid_period_inv = 1.0f/st->since_last_sid; */
282            /* Compute interpolation factor, since the division only works * for values of since_last_sid <
283             * 32 we have to limit the      * interpolation to 32 frames                                  */
284            tmp_int_length = st->since_last_sid;
285
286
287            if (tmp_int_length > 32)
288            {
289                tmp_int_length = 32;
290            }
291
292            if (tmp_int_length >= 2)
293            {
294                st->true_sid_period_inv = div_16by16(1 << 10, shl_int16(tmp_int_length, 10));
295            }
296            else
297            {
298                st->true_sid_period_inv = 1 << 14;      /* 0.5 it Q15 */
299            }
300
301            ind[0] = Serial_parm(6, prms);
302            ind[1] = Serial_parm(6, prms);
303            ind[2] = Serial_parm(6, prms);
304            ind[3] = Serial_parm(5, prms);
305            ind[4] = Serial_parm(5, prms);
306
307            Disf_ns(ind, st->isf);
308
309            log_en_index = Serial_parm(6, prms);
310
311            /* read background noise stationarity information */
312            st->CN_dith = Serial_parm_1bit(prms);
313
314            /* st->log_en = (float)log_en_index / 2.625 - 2.0;  */
315            /* log2(E) in Q9 (log2(E) lies in between -2:22) */
316            st->log_en = shl_int16(log_en_index, 15 - 6);
317
318            /* Divide by 2.625  */
319            st->log_en = mult_int16(st->log_en, 12483);
320            /* Subtract 2 in Q9 is done later, after Pow2 function  */
321
322            /* no interpolation at startup after coder reset        */
323            /* or when SID_UPD has been received right after SPEECH */
324
325            if ((st->data_updated == 0) || (st->dtxGlobalState == SPEECH))
326            {
327                pv_memcpy((void *)st->isf_old, (void *)st->isf, M*sizeof(*st->isf));
328
329                st->old_log_en = st->log_en;
330            }
331        }                                  /* endif valid_data */
332    }                                      /* endif sid_frame */
333
334
335    if ((st->sid_frame != 0) && (st->valid_data != 0))
336    {
337        st->since_last_sid = 0;
338    }
339    /* Interpolate SID info */
340    int_fac = shl_int16(st->since_last_sid, 10); /* Q10 */
341    int_fac = mult_int16(int_fac, st->true_sid_period_inv);   /* Q10 * Q15 -> Q10 */
342
343    /* Maximize to 1.0 in Q10 */
344
345    if (int_fac > 1024)
346    {
347        int_fac = 1024;
348    }
349    int_fac = shl_int16(int_fac, 4);             /* Q10 -> Q14 */
350
351    L_log_en_int = mul_16by16_to_int32(int_fac, st->log_en); /* Q14 * Q9 -> Q24 */
352
353    for (i = 0; i < M; i++)
354    {
355        isf[i] = mult_int16(int_fac, st->isf[i]);/* Q14 * Q15 -> Q14 */
356    }
357
358    int_fac = 16384 - int_fac;         /* 1-k in Q14 */
359
360    /* ( Q14 * Q9 -> Q24 ) + Q24 -> Q24 */
361    L_log_en_int = mac_16by16_to_int32(L_log_en_int, int_fac, st->old_log_en);
362
363    for (i = 0; i < M; i++)
364    {
365        /* Q14 + (Q14 * Q15 -> Q14) -> Q14 */
366        isf[i] = add_int16(isf[i], mult_int16(int_fac, st->isf_old[i]));
367        isf[i] = shl_int16(isf[i], 1);           /* Q14 -> Q15 */
368    }
369
370    /* If background noise is non-stationary, insert comfort noise dithering */
371    if (st->CN_dith != 0)
372    {
373        CN_dithering(isf, &L_log_en_int, &st->dither_seed);
374    }
375    /* L_log_en_int corresponds to log2(E)+2 in Q24, i.e log2(gain)+1 in Q25 */
376    /* Q25 -> Q16 */
377    L_log_en_int >>= 9;
378
379    /* Find integer part  */
380    log_en_int_e = extract_h(L_log_en_int);
381
382    /* Find fractional part */
383    log_en_int_m = (int16)(sub_int32(L_log_en_int, L_deposit_h(log_en_int_e)) >> 1);
384
385    /* Subtract 2 from L_log_en_int in Q9, i.e divide the gain by 2 (energy by 4) */
386    /* Add 16 in order to have the result of pow2 in Q16 */
387    log_en_int_e += 15;
388
389    /* level = (float)( pow( 2.0f, log_en ) );  */
390    level32 = power_of_2(log_en_int_e, log_en_int_m); /* Q16 */
391
392    exp0 = normalize_amr_wb(level32);
393    level32 <<= exp0;        /* level in Q31 */
394    exp0 = 15 - exp0;
395    level = (int16)(level32 >> 16);          /* level in Q15 */
396
397    /* generate white noise vector */
398    for (i = 0; i < L_FRAME; i++)
399    {
400        exc2[i] = noise_gen_amrwb(&(st->cng_seed)) >> 4;
401    }
402
403    /* gain = level / sqrt(ener) * sqrt(L_FRAME) */
404
405    /* energy of generated excitation */
406    ener32 = Dot_product12(exc2, exc2, L_FRAME, &exp);
407
408    one_ov_sqrt_norm(&ener32, &exp);
409
410    gain = extract_h(ener32);
411
412    gain = mult_int16(level, gain);              /* gain in Q15 */
413
414    exp += exp0;
415
416    /* Multiply by sqrt(L_FRAME)=16, i.e. shift left by 4 */
417    exp += 4;
418
419    for (i = 0; i < L_FRAME; i++)
420    {
421        tmp = mult_int16(exc2[i], gain);         /* Q0 * Q15 */
422        exc2[i] = shl_int16(tmp, exp);
423    }
424
425
426    if (new_state == DTX_MUTE)
427    {
428        /* mute comfort noise as it has been quite a long time since last SID update  was performed                            */
429
430        tmp_int_length = st->since_last_sid;
431
432        if (tmp_int_length > 32)
433        {
434            tmp_int_length = 32;
435        }
436
437        st->true_sid_period_inv = div_16by16(1 << 10, shl_int16(tmp_int_length, 10));
438
439        st->since_last_sid = 0;
440        st->old_log_en = st->log_en;
441        /* subtract 1/8 in Q9 (energy), i.e -3/8 dB */
442        st->log_en -= 64;
443    }
444    /* reset interpolation length timer if data has been updated.        */
445
446    if ((st->sid_frame != 0) &&
447            ((st->valid_data != 0) ||
448             ((st->valid_data == 0) && (st->dtxHangoverAdded) != 0)))
449    {
450        st->since_last_sid = 0;
451        st->data_updated = 1;
452    }
453    return 0;
454}
455
456
457/*----------------------------------------------------------------------------
458; FUNCTION CODE
459----------------------------------------------------------------------------*/
460
461void dtx_dec_amr_wb_activity_update(
462    dtx_decState * st,
463    int16 isf[],
464    int16 exc[])
465{
466    int16 i;
467
468    int32 L_frame_en;
469    int16 log_en_e, log_en_m, log_en;
470
471
472    st->hist_ptr++;
473
474    if (st->hist_ptr == DTX_HIST_SIZE)
475    {
476        st->hist_ptr = 0;
477    }
478    pv_memcpy((void *)&st->isf_hist[st->hist_ptr * M], (void *)isf, M*sizeof(*isf));
479
480
481    /* compute log energy based on excitation frame energy in Q0 */
482    L_frame_en = 0;
483    for (i = 0; i < L_FRAME; i++)
484    {
485        L_frame_en = mac_16by16_to_int32(L_frame_en, exc[i], exc[i]);
486    }
487    L_frame_en >>= 1;
488
489    /* log_en = (float)log10(L_frame_en/(float)L_FRAME)/(float)log10(2.0f); */
490    amrwb_log_2(L_frame_en, &log_en_e, &log_en_m);
491
492    /* convert exponent and mantissa to int16 Q7. Q7 is used to simplify averaging in dtx_enc */
493    log_en = shl_int16(log_en_e, 7);             /* Q7 */
494    log_en += log_en_m >> 8;
495
496    /* Divide by L_FRAME = 256, i.e subtract 8 in Q7 = 1024 */
497    log_en -= 1024;
498
499    /* insert into log energy buffer */
500    st->log_en_hist[st->hist_ptr] = log_en;
501
502    return;
503}
504
505
506/*
507     Table of new SPD synthesis states
508
509                           |     previous SPD_synthesis_state
510     Incoming              |
511     frame_type            | SPEECH       | DTX           | DTX_MUTE
512     ---------------------------------------------------------------
513     RX_SPEECH_GOOD ,      |              |               |
514     RX_SPEECH_PR_DEGRADED | SPEECH       | SPEECH        | SPEECH
515     ----------------------------------------------------------------
516     RX_SPEECH_BAD,        | SPEECH       | DTX           | DTX_MUTE
517     ----------------------------------------------------------------
518     RX_SID_FIRST,         | DTX          | DTX/(DTX_MUTE)| DTX_MUTE
519     ----------------------------------------------------------------
520     RX_SID_UPDATE,        | DTX          | DTX           | DTX
521     ----------------------------------------------------------------
522     RX_SID_BAD,           | DTX          | DTX/(DTX_MUTE)| DTX_MUTE
523     ----------------------------------------------------------------
524     RX_NO_DATA,           | SPEECH       | DTX/(DTX_MUTE)| DTX_MUTE
525     RX_SPARE              |(class2 garb.)|               |
526     ----------------------------------------------------------------
527*/
528
529
530/*----------------------------------------------------------------------------
531; FUNCTION CODE
532----------------------------------------------------------------------------*/
533
534int16 rx_amr_wb_dtx_handler(
535    dtx_decState * st,                    /* i/o : State struct     */
536    int16 frame_type                     /* i   : Frame type       */
537)
538{
539    int16 newState;
540    int16 encState;
541
542    /* DTX if SID frame or previously in DTX{_MUTE} and (NO_RX OR BAD_SPEECH) */
543
544
545
546    if ((frame_type == RX_SID_FIRST)  ||
547            (frame_type == RX_SID_UPDATE) ||
548            (frame_type == RX_SID_BAD)    ||
549            (((st->dtxGlobalState == DTX) ||
550              (st->dtxGlobalState == DTX_MUTE)) &&
551             ((frame_type == RX_NO_DATA)    ||
552              (frame_type == RX_SPEECH_BAD) ||
553              (frame_type == RX_SPEECH_LOST))))
554    {
555        newState = DTX;
556
557        /* stay in mute for these input types */
558
559        if ((st->dtxGlobalState == DTX_MUTE) &&
560                ((frame_type == RX_SID_BAD) ||
561                 (frame_type == RX_SID_FIRST) ||
562                 (frame_type == RX_SPEECH_LOST) ||
563                 (frame_type == RX_NO_DATA)))
564        {
565            newState = DTX_MUTE;
566        }
567        /* evaluate if noise parameters are too old                     */
568        /* since_last_sid is reset when CN parameters have been updated */
569        st->since_last_sid = add_int16(st->since_last_sid, 1);
570
571        /* no update of sid parameters in DTX for a long while */
572
573        if (st->since_last_sid > DTX_MAX_EMPTY_THRESH)
574        {
575            newState = DTX_MUTE;
576        }
577    }
578    else
579    {
580        newState = SPEECH;
581        st->since_last_sid = 0;
582    }
583
584    /* reset the decAnaElapsed Counter when receiving CNI data the first time, to robustify counter missmatch
585     * after handover this might delay the bwd CNI analysis in the new decoder slightly. */
586
587    if ((st->data_updated == 0) &&
588            (frame_type == RX_SID_UPDATE))
589    {
590        st->decAnaElapsedCount = 0;
591    }
592    /* update the SPE-SPD DTX hangover synchronization */
593    /* to know when SPE has added dtx hangover         */
594    st->decAnaElapsedCount = add_int16(st->decAnaElapsedCount, 1);
595    st->dtxHangoverAdded = 0;
596
597
598    if ((frame_type == RX_SID_FIRST) ||
599            (frame_type == RX_SID_UPDATE) ||
600            (frame_type == RX_SID_BAD) ||
601            (frame_type == RX_NO_DATA))
602    {
603        encState = DTX;
604    }
605    else
606    {
607        encState = SPEECH;
608    }
609
610
611    if (encState == SPEECH)
612    {
613        st->dtxHangoverCount = DTX_HANG_CONST;
614    }
615    else
616    {
617
618        if (st->decAnaElapsedCount > DTX_ELAPSED_FRAMES_THRESH)
619        {
620            st->dtxHangoverAdded = 1;
621            st->decAnaElapsedCount = 0;
622            st->dtxHangoverCount = 0;
623        }
624        else if (st->dtxHangoverCount == 0)
625        {
626            st->decAnaElapsedCount = 0;
627        }
628        else
629        {
630            st->dtxHangoverCount--;
631        }
632    }
633
634    if (newState != SPEECH)
635    {
636        /* DTX or DTX_MUTE CN data is not in a first SID, first SIDs are marked as SID_BAD but will do
637         * backwards analysis if a hangover period has been added according to the state machine above */
638
639        st->sid_frame = 0;
640        st->valid_data = 0;
641
642
643        if (frame_type == RX_SID_FIRST)
644        {
645            st->sid_frame = 1;
646        }
647        else if (frame_type == RX_SID_UPDATE)
648        {
649            st->sid_frame = 1;
650            st->valid_data = 1;
651        }
652        else if (frame_type == RX_SID_BAD)
653        {
654            st->sid_frame = 1;
655            st->dtxHangoverAdded = 0;      /* use old data */
656        }
657    }
658    return newState;
659    /* newState is used by both SPEECH AND DTX synthesis routines */
660}
661
662
663/*----------------------------------------------------------------------------
664; FUNCTION CODE
665----------------------------------------------------------------------------*/
666
667void aver_isf_history(
668    int16 isf_old[],
669    int16 indices[],
670    int32 isf_aver[]
671)
672{
673    int16 i, j, k;
674    int16 isf_tmp[2 * M];
675    int32 L_tmp;
676
677    /* Memorize in isf_tmp[][] the ISF vectors to be replaced by */
678    /* the median ISF vector prior to the averaging               */
679    for (k = 0; k < 2; k++)
680    {
681
682        if (indices[k] + 1 != 0)
683        {
684            for (i = 0; i < M; i++)
685            {
686                isf_tmp[k * M + i] = isf_old[indices[k] * M + i];
687                isf_old[indices[k] * M + i] = isf_old[indices[2] * M + i];
688            }
689        }
690    }
691
692    /* Perform the ISF averaging */
693    for (j = 0; j < M; j++)
694    {
695        L_tmp = 0;
696
697        for (i = 0; i < DTX_HIST_SIZE; i++)
698        {
699            L_tmp = add_int32(L_tmp, (int32)(isf_old[i * M + j]));
700        }
701        isf_aver[j] = L_tmp;
702    }
703
704    /* Retrieve from isf_tmp[][] the ISF vectors saved prior to averaging */
705    for (k = 0; k < 2; k++)
706    {
707
708        if (indices[k] + 1 != 0)
709        {
710            for (i = 0; i < M; i++)
711            {
712                isf_old[indices[k] * M + i] = isf_tmp[k * M + i];
713            }
714        }
715    }
716
717    return;
718}
719
720
721/*----------------------------------------------------------------------------
722; FUNCTION CODE
723----------------------------------------------------------------------------*/
724
725void find_frame_indices(
726    int16 isf_old_tx[],
727    int16 indices[],
728    dtx_encState * st
729)
730{
731    int32 L_tmp, summin, summax, summax2nd;
732    int16 i, j, tmp;
733    int16 ptr;
734
735    /* Remove the effect of the oldest frame from the column */
736    /* sum sumD[0..DTX_HIST_SIZE-1]. sumD[DTX_HIST_SIZE] is    */
737    /* not updated since it will be removed later.           */
738
739    tmp = DTX_HIST_SIZE_MIN_ONE;
740    j = -1;
741    for (i = 0; i < DTX_HIST_SIZE_MIN_ONE; i++)
742    {
743        j += tmp;
744        st->sumD[i] = sub_int32(st->sumD[i], st->D[j]);
745        tmp--;
746    }
747
748    /* Shift the column sum sumD. The element sumD[DTX_HIST_SIZE-1]    */
749    /* corresponding to the oldest frame is removed. The sum of     */
750    /* the distances between the latest isf and other isfs, */
751    /* i.e. the element sumD[0], will be computed during this call. */
752    /* Hence this element is initialized to zero.                   */
753
754    for (i = DTX_HIST_SIZE_MIN_ONE; i > 0; i--)
755    {
756        st->sumD[i] = st->sumD[i - 1];
757    }
758    st->sumD[0] = 0;
759
760    /* Remove the oldest frame from the distance matrix.           */
761    /* Note that the distance matrix is replaced by a one-         */
762    /* dimensional array to save static memory.                    */
763
764    tmp = 0;
765    for (i = 27; i >= 12; i -= tmp)
766    {
767        tmp++;
768        for (j = tmp; j > 0; j--)
769        {
770            st->D[i - j + 1] = st->D[i - j - tmp];
771        }
772    }
773
774    /* Compute the first column of the distance matrix D            */
775    /* (squared Euclidean distances from isf1[] to isf_old_tx[][]). */
776
777    ptr = st->hist_ptr;
778    for (i = 1; i < DTX_HIST_SIZE; i++)
779    {
780        /* Compute the distance between the latest isf and the other isfs. */
781        ptr--;
782
783        if (ptr < 0)
784        {
785            ptr = DTX_HIST_SIZE_MIN_ONE;
786        }
787        L_tmp = 0;
788        for (j = 0; j < M; j++)
789        {
790            tmp = sub_int16(isf_old_tx[st->hist_ptr * M + j], isf_old_tx[ptr * M + j]);
791            L_tmp = mac_16by16_to_int32(L_tmp, tmp, tmp);
792        }
793        st->D[i - 1] = L_tmp;
794
795        /* Update also the column sums. */
796        st->sumD[0] = add_int32(st->sumD[0], st->D[i - 1]);
797        st->sumD[i] = add_int32(st->sumD[i], st->D[i - 1]);
798    }
799
800    /* Find the minimum and maximum distances */
801    summax = st->sumD[0];
802    summin = st->sumD[0];
803    indices[0] = 0;
804    indices[2] = 0;
805    for (i = 1; i < DTX_HIST_SIZE; i++)
806    {
807
808        if (st->sumD[i] > summax)
809        {
810            indices[0] = i;
811            summax = st->sumD[i];
812        }
813
814        if (st->sumD[i] < summin)
815        {
816            indices[2] = i;
817            summin = st->sumD[i];
818        }
819    }
820
821    /* Find the second largest distance */
822    summax2nd = -2147483647L;
823    indices[1] = -1;
824    for (i = 0; i < DTX_HIST_SIZE; i++)
825    {
826
827        if ((st->sumD[i] > summax2nd) && (i != indices[0]))
828        {
829            indices[1] = i;
830            summax2nd = st->sumD[i];
831        }
832    }
833
834    for (i = 0; i < 3; i++)
835    {
836        indices[i] = sub_int16(st->hist_ptr, indices[i]);
837
838        if (indices[i] < 0)
839        {
840            indices[i] = add_int16(indices[i], DTX_HIST_SIZE);
841        }
842    }
843
844    /* If maximum distance/MED_THRESH is smaller than minimum distance */
845    /* then the median ISF vector replacement is not performed         */
846    tmp = normalize_amr_wb(summax);
847    summax <<= tmp;
848    summin <<= tmp;
849    L_tmp = mul_16by16_to_int32(amr_wb_round(summax), INV_MED_THRESH);
850
851    if (L_tmp <= summin)
852    {
853        indices[0] = -1;
854    }
855    /* If second largest distance/MED_THRESH is smaller than     */
856    /* minimum distance then the median ISF vector replacement is    */
857    /* not performed                                                 */
858    summax2nd = shl_int32(summax2nd, tmp);
859    L_tmp = mul_16by16_to_int32(amr_wb_round(summax2nd), INV_MED_THRESH);
860
861    if (L_tmp <= summin)
862    {
863        indices[1] = -1;
864    }
865    return;
866}
867
868
869/*----------------------------------------------------------------------------
870; FUNCTION CODE
871----------------------------------------------------------------------------*/
872
873int16 dithering_control(dtx_encState * st)
874{
875    int16 i, tmp, mean, CN_dith, gain_diff;
876    int32 ISF_diff;
877
878    /* determine how stationary the spectrum of background noise is */
879    ISF_diff = 0;
880    for (i = 0; i < 8; i++)
881    {
882        ISF_diff = add_int32(ISF_diff, st->sumD[i]);
883    }
884    if ((ISF_diff >> 26) > 0)
885    {
886        CN_dith = 1;
887    }
888    else
889    {
890        CN_dith = 0;
891    }
892
893    /* determine how stationary the energy of background noise is */
894    mean = 0;
895    for (i = 0; i < DTX_HIST_SIZE; i++)
896    {
897        mean = add_int16(mean, st->log_en_hist[i]);
898    }
899    mean >>= 3;
900    gain_diff = 0;
901    for (i = 0; i < DTX_HIST_SIZE; i++)
902    {
903        tmp = sub_int16(st->log_en_hist[i], mean);
904        tmp = tmp - (tmp < 0);
905
906        gain_diff += tmp ^(tmp >> 15);    /*  tmp ^sign(tmp)  */;
907    }
908    if (gain_diff > GAIN_THR)
909    {
910        CN_dith = 1;
911    }
912    return CN_dith;
913}
914
915
916/*----------------------------------------------------------------------------
917; FUNCTION CODE
918----------------------------------------------------------------------------*/
919
920void CN_dithering(
921    int16 isf[M],
922    int32 * L_log_en_int,
923    int16 * dither_seed
924)
925{
926    int16 temp, temp1, i, dither_fac, rand_dith;
927    int16 rand_dith2;
928
929    /* Insert comfort noise dithering for energy parameter */
930    rand_dith = noise_gen_amrwb(dither_seed) >> 1;
931    rand_dith2 = noise_gen_amrwb(dither_seed) >> 1;
932    rand_dith += rand_dith2;
933    *L_log_en_int = add_int32(*L_log_en_int, mul_16by16_to_int32(rand_dith, GAIN_FACTOR));
934
935    if (*L_log_en_int < 0)
936    {
937        *L_log_en_int = 0;
938    }
939    /* Insert comfort noise dithering for spectral parameters (ISF-vector) */
940    dither_fac = ISF_FACTOR_LOW;
941
942    rand_dith = noise_gen_amrwb(dither_seed) >> 1;
943    rand_dith2 = noise_gen_amrwb(dither_seed) >> 1;
944    rand_dith +=  rand_dith2;
945    temp = add_int16(isf[0], mult_int16_r(rand_dith, dither_fac));
946
947    /* Make sure that isf[0] will not get negative values */
948    if (temp < ISF_GAP)
949    {
950        isf[0] = ISF_GAP;
951    }
952    else
953    {
954        isf[0] = temp;
955    }
956
957    for (i = 1; i < M - 1; i++)
958    {
959        dither_fac = add_int16(dither_fac, ISF_FACTOR_STEP);
960
961        rand_dith = noise_gen_amrwb(dither_seed) >> 1;
962        rand_dith2 = noise_gen_amrwb(dither_seed) >> 1;
963        rand_dith +=  rand_dith2;
964        temp = add_int16(isf[i], mult_int16_r(rand_dith, dither_fac));
965        temp1 = sub_int16(temp, isf[i - 1]);
966
967        /* Make sure that isf spacing remains at least ISF_DITH_GAP Hz */
968        if (temp1 < ISF_DITH_GAP)
969        {
970            isf[i] = isf[i - 1] + ISF_DITH_GAP;
971        }
972        else
973        {
974            isf[i] = temp;
975        }
976    }
977
978    /* Make sure that isf[M-2] will not get values above 16384 */
979    if (isf[M - 2] > 16384)
980    {
981        isf[M - 2] = 16384;
982    }
983    return;
984}
985