Coverage Report

Created: 2024-03-26 07:25

/src/opus/silk/float/burg_modified_FLP.c
Line
Count
Source
1
/***********************************************************************
2
Copyright (c) 2006-2011, Skype Limited. All rights reserved.
3
Redistribution and use in source and binary forms, with or without
4
modification, are permitted provided that the following conditions
5
are met:
6
- Redistributions of source code must retain the above copyright notice,
7
this list of conditions and the following disclaimer.
8
- Redistributions in binary form must reproduce the above copyright
9
notice, this list of conditions and the following disclaimer in the
10
documentation and/or other materials provided with the distribution.
11
- Neither the name of Internet Society, IETF or IETF Trust, nor the
12
names of specific contributors, may be used to endorse or promote
13
products derived from this software without specific prior written
14
permission.
15
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
16
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
17
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
18
ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
19
LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
20
CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
21
SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
22
INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
23
CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
24
ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
25
POSSIBILITY OF SUCH DAMAGE.
26
***********************************************************************/
27
28
#ifdef HAVE_CONFIG_H
29
#include "config.h"
30
#endif
31
32
#include "SigProc_FLP.h"
33
#include "tuning_parameters.h"
34
#include "define.h"
35
36
#define MAX_FRAME_SIZE              384 /* subfr_length * nb_subfr = ( 0.005 * 16000 + 16 ) * 4 = 384*/
37
38
/* Compute reflection coefficients from input signal */
39
silk_float silk_burg_modified_FLP(          /* O    returns residual energy                                     */
40
    silk_float          A[],                /* O    prediction coefficients (length order)                      */
41
    const silk_float    x[],                /* I    input signal, length: nb_subfr*(D+L_sub)                    */
42
    const silk_float    minInvGain,         /* I    minimum inverse prediction gain                             */
43
    const opus_int      subfr_length,       /* I    input signal subframe length (incl. D preceding samples)    */
44
    const opus_int      nb_subfr,           /* I    number of subframes stacked in x                            */
45
    const opus_int      D,                  /* I    order                                                       */
46
    int                 arch
47
)
48
150k
{
49
150k
    opus_int         k, n, s, reached_max_gain;
50
150k
    double           C0, invGain, num, nrg_f, nrg_b, rc, Atmp, tmp1, tmp2;
51
150k
    const silk_float *x_ptr;
52
150k
    double           C_first_row[ SILK_MAX_ORDER_LPC ], C_last_row[ SILK_MAX_ORDER_LPC ];
53
150k
    double           CAf[ SILK_MAX_ORDER_LPC + 1 ], CAb[ SILK_MAX_ORDER_LPC + 1 ];
54
150k
    double           Af[ SILK_MAX_ORDER_LPC ];
55
56
150k
    celt_assert( subfr_length * nb_subfr <= MAX_FRAME_SIZE );
57
58
    /* Compute autocorrelations, added over subframes */
59
150k
    C0 = silk_energy_FLP( x, nb_subfr * subfr_length );
60
150k
    silk_memset( C_first_row, 0, SILK_MAX_ORDER_LPC * sizeof( double ) );
61
623k
    for( s = 0; s < nb_subfr; s++ ) {
62
473k
        x_ptr = x + s * subfr_length;
63
5.79M
        for( n = 1; n < D + 1; n++ ) {
64
5.31M
            C_first_row[ n - 1 ] += silk_inner_product_FLP( x_ptr, x_ptr + n, subfr_length - n, arch );
65
5.31M
        }
66
473k
    }
67
150k
    silk_memcpy( C_last_row, C_first_row, SILK_MAX_ORDER_LPC * sizeof( double ) );
68
69
    /* Initialize */
70
150k
    CAb[ 0 ] = CAf[ 0 ] = C0 + FIND_LPC_COND_FAC * C0 + 1e-9f;
71
150k
    invGain = 1.0f;
72
150k
    reached_max_gain = 0;
73
1.77M
    for( n = 0; n < D; n++ ) {
74
        /* Update first row of correlation matrix (without first element) */
75
        /* Update last row of correlation matrix (without last element, stored in reversed order) */
76
        /* Update C * Af */
77
        /* Update C * flipud(Af) (stored in reversed order) */
78
6.76M
        for( s = 0; s < nb_subfr; s++ ) {
79
5.13M
            x_ptr = x + s * subfr_length;
80
5.13M
            tmp1 = x_ptr[ n ];
81
5.13M
            tmp2 = x_ptr[ subfr_length - n - 1 ];
82
32.6M
            for( k = 0; k < n; k++ ) {
83
27.4M
                C_first_row[ k ] -= x_ptr[ n ] * x_ptr[ n - k - 1 ];
84
27.4M
                C_last_row[ k ]  -= x_ptr[ subfr_length - n - 1 ] * x_ptr[ subfr_length - n + k ];
85
27.4M
                Atmp = Af[ k ];
86
27.4M
                tmp1 += x_ptr[ n - k - 1 ] * Atmp;
87
27.4M
                tmp2 += x_ptr[ subfr_length - n + k ] * Atmp;
88
27.4M
            }
89
37.7M
            for( k = 0; k <= n; k++ ) {
90
32.6M
                CAf[ k ] -= tmp1 * x_ptr[ n - k ];
91
32.6M
                CAb[ k ] -= tmp2 * x_ptr[ subfr_length - n + k - 1 ];
92
32.6M
            }
93
5.13M
        }
94
1.62M
        tmp1 = C_first_row[ n ];
95
1.62M
        tmp2 = C_last_row[ n ];
96
10.3M
        for( k = 0; k < n; k++ ) {
97
8.70M
            Atmp = Af[ k ];
98
8.70M
            tmp1 += C_last_row[  n - k - 1 ] * Atmp;
99
8.70M
            tmp2 += C_first_row[ n - k - 1 ] * Atmp;
100
8.70M
        }
101
1.62M
        CAf[ n + 1 ] = tmp1;
102
1.62M
        CAb[ n + 1 ] = tmp2;
103
104
        /* Calculate nominator and denominator for the next order reflection (parcor) coefficient */
105
1.62M
        num = CAb[ n + 1 ];
106
1.62M
        nrg_b = CAb[ 0 ];
107
1.62M
        nrg_f = CAf[ 0 ];
108
10.3M
        for( k = 0; k < n; k++ ) {
109
8.70M
            Atmp = Af[ k ];
110
8.70M
            num   += CAb[ n - k ] * Atmp;
111
8.70M
            nrg_b += CAb[ k + 1 ] * Atmp;
112
8.70M
            nrg_f += CAf[ k + 1 ] * Atmp;
113
8.70M
        }
114
1.62M
        silk_assert( nrg_f > 0.0 );
115
1.62M
        silk_assert( nrg_b > 0.0 );
116
117
        /* Calculate the next order reflection (parcor) coefficient */
118
1.62M
        rc = -2.0 * num / ( nrg_f + nrg_b );
119
1.62M
        silk_assert( rc > -1.0 && rc < 1.0 );
120
121
        /* Update inverse prediction gain */
122
1.62M
        tmp1 = invGain * ( 1.0 - rc * rc );
123
1.62M
        if( tmp1 <= minInvGain ) {
124
            /* Max prediction gain exceeded; set reflection coefficient such that max prediction gain is exactly hit */
125
7.55k
            rc = sqrt( 1.0 - minInvGain / invGain );
126
7.55k
            if( num > 0 ) {
127
                /* Ensure adjusted reflection coefficients has the original sign */
128
5.85k
                rc = -rc;
129
5.85k
            }
130
7.55k
            invGain = minInvGain;
131
7.55k
            reached_max_gain = 1;
132
1.62M
        } else {
133
1.62M
            invGain = tmp1;
134
1.62M
        }
135
136
        /* Update the AR coefficients */
137
6.38M
        for( k = 0; k < (n + 1) >> 1; k++ ) {
138
4.75M
            tmp1 = Af[ k ];
139
4.75M
            tmp2 = Af[ n - k - 1 ];
140
4.75M
            Af[ k ]         = tmp1 + rc * tmp2;
141
4.75M
            Af[ n - k - 1 ] = tmp2 + rc * tmp1;
142
4.75M
        }
143
1.62M
        Af[ n ] = rc;
144
145
1.62M
        if( reached_max_gain ) {
146
            /* Reached max prediction gain; set remaining coefficients to zero and exit loop */
147
67.9k
            for( k = n + 1; k < D; k++ ) {
148
60.3k
                Af[ k ] = 0.0;
149
60.3k
            }
150
7.55k
            break;
151
7.55k
        }
152
153
        /* Update C * Af and C * Ab */
154
13.5M
        for( k = 0; k <= n + 1; k++ ) {
155
11.9M
            tmp1 = CAf[ k ];
156
11.9M
            CAf[ k ]          += rc * CAb[ n - k + 1 ];
157
11.9M
            CAb[ n - k + 1  ] += rc * tmp1;
158
11.9M
        }
159
1.62M
    }
160
161
150k
    if( reached_max_gain ) {
162
        /* Convert to silk_float */
163
91.8k
        for( k = 0; k < D; k++ ) {
164
84.3k
            A[ k ] = (silk_float)( -Af[ k ] );
165
84.3k
        }
166
        /* Subtract energy of preceding samples from C0 */
167
30.2k
        for( s = 0; s < nb_subfr; s++ ) {
168
22.7k
            C0 -= silk_energy_FLP( x + s * subfr_length, D );
169
22.7k
        }
170
        /* Approximate residual energy */
171
7.55k
        nrg_f = C0 * invGain;
172
142k
    } else {
173
        /* Compute residual energy and store coefficients as silk_float */
174
142k
        nrg_f = CAf[ 0 ];
175
142k
        tmp1 = 1.0;
176
1.74M
        for( k = 0; k < D; k++ ) {
177
1.60M
            Atmp = Af[ k ];
178
1.60M
            nrg_f += CAf[ k + 1 ] * Atmp;
179
1.60M
            tmp1  += Atmp * Atmp;
180
1.60M
            A[ k ] = (silk_float)(-Atmp);
181
1.60M
        }
182
142k
        nrg_f -= FIND_LPC_COND_FAC * C0 * tmp1;
183
142k
    }
184
185
    /* Return residual energy */
186
150k
    return (silk_float)nrg_f;
187
150k
}