Makes analysis usable for all frame sizes
[opus.git] / src / analysis.c
1 /* Copyright (c) 2011 Xiph.Org Foundation
2    Written by Jean-Marc Valin */
3 /*
4    Redistribution and use in source and binary forms, with or without
5    modification, are permitted provided that the following conditions
6    are met:
7
8    - Redistributions of source code must retain the above copyright
9    notice, this list of conditions and the following disclaimer.
10
11    - Redistributions in binary form must reproduce the above copyright
12    notice, this list of conditions and the following disclaimer in the
13    documentation and/or other materials provided with the distribution.
14
15    THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
16    ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
17    LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
18    A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR
19    CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
20    EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
21    PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
22    PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
23    LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
24    NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
25    SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26 */
27
28 #ifdef HAVE_CONFIG_H
29 #include "config.h"
30 #endif
31
32 #include "kiss_fft.h"
33 #include "celt.h"
34 #include "modes.h"
35 #include "arch.h"
36 #include "quant_bands.h"
37 #include <stdio.h>
38 #include "analysis.h"
39 #include "mlp.h"
40
41 extern const MLP net;
42
43 #ifndef M_PI
44 #define M_PI 3.141592653
45 #endif
46
47 static const float dct_table[128] = {
48         0.250000f, 0.250000f, 0.250000f, 0.250000f, 0.250000f, 0.250000f, 0.250000f, 0.250000f,
49         0.250000f, 0.250000f, 0.250000f, 0.250000f, 0.250000f, 0.250000f, 0.250000f, 0.250000f,
50         0.351851f, 0.338330f, 0.311806f, 0.273300f, 0.224292f, 0.166664f, 0.102631f, 0.034654f,
51        -0.034654f,-0.102631f,-0.166664f,-0.224292f,-0.273300f,-0.311806f,-0.338330f,-0.351851f,
52         0.346760f, 0.293969f, 0.196424f, 0.068975f,-0.068975f,-0.196424f,-0.293969f,-0.346760f,
53        -0.346760f,-0.293969f,-0.196424f,-0.068975f, 0.068975f, 0.196424f, 0.293969f, 0.346760f,
54         0.338330f, 0.224292f, 0.034654f,-0.166664f,-0.311806f,-0.351851f,-0.273300f,-0.102631f,
55         0.102631f, 0.273300f, 0.351851f, 0.311806f, 0.166664f,-0.034654f,-0.224292f,-0.338330f,
56         0.326641f, 0.135299f,-0.135299f,-0.326641f,-0.326641f,-0.135299f, 0.135299f, 0.326641f,
57         0.326641f, 0.135299f,-0.135299f,-0.326641f,-0.326641f,-0.135299f, 0.135299f, 0.326641f,
58         0.311806f, 0.034654f,-0.273300f,-0.338330f,-0.102631f, 0.224292f, 0.351851f, 0.166664f,
59        -0.166664f,-0.351851f,-0.224292f, 0.102631f, 0.338330f, 0.273300f,-0.034654f,-0.311806f,
60         0.293969f,-0.068975f,-0.346760f,-0.196424f, 0.196424f, 0.346760f, 0.068975f,-0.293969f,
61        -0.293969f, 0.068975f, 0.346760f, 0.196424f,-0.196424f,-0.346760f,-0.068975f, 0.293969f,
62         0.273300f,-0.166664f,-0.338330f, 0.034654f, 0.351851f, 0.102631f,-0.311806f,-0.224292f,
63         0.224292f, 0.311806f,-0.102631f,-0.351851f,-0.034654f, 0.338330f, 0.166664f,-0.273300f,
64 };
65
66 static const float analysis_window[240] = {
67       0.000043f, 0.000171f, 0.000385f, 0.000685f, 0.001071f, 0.001541f, 0.002098f, 0.002739f,
68       0.003466f, 0.004278f, 0.005174f, 0.006156f, 0.007222f, 0.008373f, 0.009607f, 0.010926f,
69       0.012329f, 0.013815f, 0.015385f, 0.017037f, 0.018772f, 0.020590f, 0.022490f, 0.024472f,
70       0.026535f, 0.028679f, 0.030904f, 0.033210f, 0.035595f, 0.038060f, 0.040604f, 0.043227f,
71       0.045928f, 0.048707f, 0.051564f, 0.054497f, 0.057506f, 0.060591f, 0.063752f, 0.066987f,
72       0.070297f, 0.073680f, 0.077136f, 0.080665f, 0.084265f, 0.087937f, 0.091679f, 0.095492f,
73       0.099373f, 0.103323f, 0.107342f, 0.111427f, 0.115579f, 0.119797f, 0.124080f, 0.128428f,
74       0.132839f, 0.137313f, 0.141849f, 0.146447f, 0.151105f, 0.155823f, 0.160600f, 0.165435f,
75       0.170327f, 0.175276f, 0.180280f, 0.185340f, 0.190453f, 0.195619f, 0.200838f, 0.206107f,
76       0.211427f, 0.216797f, 0.222215f, 0.227680f, 0.233193f, 0.238751f, 0.244353f, 0.250000f,
77       0.255689f, 0.261421f, 0.267193f, 0.273005f, 0.278856f, 0.284744f, 0.290670f, 0.296632f,
78       0.302628f, 0.308658f, 0.314721f, 0.320816f, 0.326941f, 0.333097f, 0.339280f, 0.345492f,
79       0.351729f, 0.357992f, 0.364280f, 0.370590f, 0.376923f, 0.383277f, 0.389651f, 0.396044f,
80       0.402455f, 0.408882f, 0.415325f, 0.421783f, 0.428254f, 0.434737f, 0.441231f, 0.447736f,
81       0.454249f, 0.460770f, 0.467298f, 0.473832f, 0.480370f, 0.486912f, 0.493455f, 0.500000f,
82       0.506545f, 0.513088f, 0.519630f, 0.526168f, 0.532702f, 0.539230f, 0.545751f, 0.552264f,
83       0.558769f, 0.565263f, 0.571746f, 0.578217f, 0.584675f, 0.591118f, 0.597545f, 0.603956f,
84       0.610349f, 0.616723f, 0.623077f, 0.629410f, 0.635720f, 0.642008f, 0.648271f, 0.654508f,
85       0.660720f, 0.666903f, 0.673059f, 0.679184f, 0.685279f, 0.691342f, 0.697372f, 0.703368f,
86       0.709330f, 0.715256f, 0.721144f, 0.726995f, 0.732807f, 0.738579f, 0.744311f, 0.750000f,
87       0.755647f, 0.761249f, 0.766807f, 0.772320f, 0.777785f, 0.783203f, 0.788573f, 0.793893f,
88       0.799162f, 0.804381f, 0.809547f, 0.814660f, 0.819720f, 0.824724f, 0.829673f, 0.834565f,
89       0.839400f, 0.844177f, 0.848895f, 0.853553f, 0.858151f, 0.862687f, 0.867161f, 0.871572f,
90       0.875920f, 0.880203f, 0.884421f, 0.888573f, 0.892658f, 0.896677f, 0.900627f, 0.904508f,
91       0.908321f, 0.912063f, 0.915735f, 0.919335f, 0.922864f, 0.926320f, 0.929703f, 0.933013f,
92       0.936248f, 0.939409f, 0.942494f, 0.945503f, 0.948436f, 0.951293f, 0.954072f, 0.956773f,
93       0.959396f, 0.961940f, 0.964405f, 0.966790f, 0.969096f, 0.971321f, 0.973465f, 0.975528f,
94       0.977510f, 0.979410f, 0.981228f, 0.982963f, 0.984615f, 0.986185f, 0.987671f, 0.989074f,
95       0.990393f, 0.991627f, 0.992778f, 0.993844f, 0.994826f, 0.995722f, 0.996534f, 0.997261f,
96       0.997902f, 0.998459f, 0.998929f, 0.999315f, 0.999615f, 0.999829f, 0.999957f, 1.000000f,
97 };
98
99 static const int tbands[NB_TBANDS+1] = {
100        2,  4,  6,  8, 10, 12, 14, 16, 20, 24, 28, 32, 40, 48, 56, 68, 80, 96, 120
101 };
102
103 static const int extra_bands[NB_TOT_BANDS+1] = {
104       0, 2,  4,  6,  8, 10, 12, 14, 16, 20, 24, 28, 32, 40, 48, 56, 68, 80, 96, 120, 160, 200
105 };
106
107 /*static const float tweight[NB_TBANDS+1] = {
108       .3, .4, .5, .6, .7, .8, .9, 1., 1., 1., 1., 1., 1., 1., .8, .7, .6, .5
109 };*/
110
111 #define NB_TONAL_SKIP_BANDS 9
112
113 #define cA 0.43157974f
114 #define cB 0.67848403f
115 #define cC 0.08595542f
116 #define cE ((float)M_PI/2)
117 static inline float fast_atan2f(float y, float x) {
118    float x2, y2;
119    /* Should avoid underflow on the values we'll get */
120    if (ABS16(x)+ABS16(y)<1e-9f)
121    {
122       x*=1e12f;
123       y*=1e12f;
124    }
125    x2 = x*x;
126    y2 = y*y;
127    if(x2<y2){
128       float den = (y2 + cB*x2) * (y2 + cC*x2);
129       if (den!=0)
130          return -x*y*(y2 + cA*x2) / den + (y<0 ? -cE : cE);
131       else
132          return (y<0 ? -cE : cE);
133    }else{
134       float den = (x2 + cB*y2) * (x2 + cC*y2);
135       if (den!=0)
136          return  x*y*(x2 + cA*y2) / den + (y<0 ? -cE : cE) - (x*y<0 ? -cE : cE);
137       else
138          return (y<0 ? -cE : cE) - (x*y<0 ? -cE : cE);
139    }
140 }
141
142 void tonality_analysis(TonalityAnalysisState *tonal, AnalysisInfo *info, CELTEncoder *celt_enc, const opus_val16 *x, int len, int C, int lsb_depth)
143 {
144     int i, b;
145     const CELTMode *mode;
146     const kiss_fft_state *kfft;
147     kiss_fft_cpx in[480], out[480];
148     int N = 480, N2=240;
149     float * OPUS_RESTRICT A = tonal->angle;
150     float * OPUS_RESTRICT dA = tonal->d_angle;
151     float * OPUS_RESTRICT d2A = tonal->d2_angle;
152     float tonality[240];
153     float noisiness[240];
154     float band_tonality[NB_TBANDS];
155     float logE[NB_TBANDS];
156     float BFCC[8];
157     float features[100];
158     float frame_tonality;
159     float max_frame_tonality;
160     /*float tw_sum=0;*/
161     float frame_noisiness;
162     const float pi4 = (float)(M_PI*M_PI*M_PI*M_PI);
163     float slope=0;
164     float frame_stationarity;
165     float relativeE;
166     float frame_prob;
167     float alpha, alphaE, alphaE2;
168     float frame_loudness;
169     float bandwidth_mask;
170     int bandwidth=0;
171     float maxE = 0;
172     float noise_floor;
173     int remaining;
174
175     celt_encoder_ctl(celt_enc, CELT_GET_MODE(&mode));
176
177     tonal->last_transition++;
178     alpha = 1.f/IMIN(20, 1+tonal->count);
179     alphaE = 1.f/IMIN(50, 1+tonal->count);
180     alphaE2 = 1.f/IMIN(6000, 1+tonal->count);
181
182     if (tonal->count<4)
183        tonal->music_prob = .5;
184     kfft = mode->mdct.kfft[0];
185     if (tonal->count==0)
186        tonal->mem_fill = 240;
187     if (C==1)
188     {
189        for (i=0;i<IMIN(len, ANALYSIS_BUF_SIZE-tonal->mem_fill);i++)
190           tonal->inmem[i+tonal->mem_fill] = x[i];
191     } else {
192        for (i=0;i<IMIN(len, ANALYSIS_BUF_SIZE-tonal->mem_fill);i++)
193           tonal->inmem[i+tonal->mem_fill] = x[2*i]+x[2*i+1];
194     }
195     if (tonal->mem_fill+len < ANALYSIS_BUF_SIZE)
196     {
197        tonal->mem_fill += len;
198        /* Don't have enough to update the analysis */
199        return;
200     }
201
202     for (i=0;i<N2;i++)
203     {
204        float w = analysis_window[i];
205        in[i].r = MULT16_16(w, tonal->inmem[i]);
206        in[i].i = MULT16_16(w, tonal->inmem[N2+i]);
207        in[N-i-1].r = MULT16_16(w, tonal->inmem[N-i-1]);
208        in[N-i-1].i = MULT16_16(w, tonal->inmem[N+N2-i-1]);
209     }
210     OPUS_MOVE(tonal->inmem, tonal->inmem+ANALYSIS_BUF_SIZE-240, 240);
211     remaining = len - (ANALYSIS_BUF_SIZE-tonal->mem_fill);
212     if (C==1)
213     {
214        for (i=0;i<remaining;i++)
215           tonal->inmem[240+i] = x[ANALYSIS_BUF_SIZE-tonal->mem_fill+i];
216     } else {
217        for (i=0;i<remaining;i++)
218           tonal->inmem[240+i] = x[2*(ANALYSIS_BUF_SIZE-tonal->mem_fill+i)]
219                               + x[2*(ANALYSIS_BUF_SIZE-tonal->mem_fill+i)+1];
220     }
221     tonal->mem_fill = 240 + remaining;
222     opus_fft(kfft, in, out);
223
224     for (i=1;i<N2;i++)
225     {
226        float X1r, X2r, X1i, X2i;
227        float angle, d_angle, d2_angle;
228        float angle2, d_angle2, d2_angle2;
229        float mod1, mod2, avg_mod;
230        X1r = out[i].r+out[N-i].r;
231        X1i = out[i].i-out[N-i].i;
232        X2r = out[i].i+out[N-i].i;
233        X2i = out[N-i].r-out[i].r;
234
235        angle = (float)(.5f/M_PI)*fast_atan2f(X1i, X1r);
236        d_angle = angle - A[i];
237        d2_angle = d_angle - dA[i];
238
239        angle2 = (float)(.5f/M_PI)*fast_atan2f(X2i, X2r);
240        d_angle2 = angle2 - angle;
241        d2_angle2 = d_angle2 - d_angle;
242
243        mod1 = d2_angle - (float)floor(.5+d2_angle);
244        noisiness[i] = ABS16(mod1);
245        mod1 *= mod1;
246        mod1 *= mod1;
247
248        mod2 = d2_angle2 - (float)floor(.5+d2_angle2);
249        noisiness[i] += ABS16(mod2);
250        mod2 *= mod2;
251        mod2 *= mod2;
252
253        avg_mod = .25f*(d2A[i]+2.f*mod1+mod2);
254        tonality[i] = 1.f/(1.f+40.f*16.f*pi4*avg_mod)-.015f;
255
256        A[i] = angle2;
257        dA[i] = d_angle2;
258        d2A[i] = mod2;
259     }
260
261     frame_tonality = 0;
262     max_frame_tonality = 0;
263     /*tw_sum = 0;*/
264     info->activity = 0;
265     frame_noisiness = 0;
266     frame_stationarity = 0;
267     if (!tonal->count)
268     {
269        for (b=0;b<NB_TBANDS;b++)
270        {
271           tonal->lowE[b] = 1e10;
272           tonal->highE[b] = -1e10;
273        }
274     }
275     relativeE = 0;
276     frame_loudness = 0;
277     bandwidth_mask = 0;
278     for (b=0;b<NB_TBANDS;b++)
279     {
280        float E=0, tE=0, nE=0;
281        float L1, L2;
282        float stationarity;
283        for (i=tbands[b];i<tbands[b+1];i++)
284        {
285           float binE = out[i].r*out[i].r + out[N-i].r*out[N-i].r
286                      + out[i].i*out[i].i + out[N-i].i*out[N-i].i;
287           E += binE;
288           tE += binE*tonality[i];
289           nE += binE*2.f*(.5f-noisiness[i]);
290        }
291        tonal->E[tonal->E_count][b] = E;
292        frame_noisiness += nE/(1e-15f+E);
293
294        frame_loudness += celt_sqrt(E+1e-10f);
295        logE[b] = (float)log(E+1e-10f);
296        tonal->lowE[b] = MIN32(logE[b], tonal->lowE[b]+.01f);
297        tonal->highE[b] = MAX32(logE[b], tonal->highE[b]-.1f);
298        if (tonal->highE[b] < tonal->lowE[b]+1.f)
299        {
300           tonal->highE[b]+=.5f;
301           tonal->lowE[b]-=.5f;
302        }
303        relativeE += (logE[b]-tonal->lowE[b])/(EPSILON+tonal->highE[b]-tonal->lowE[b]);
304
305        L1=L2=0;
306        for (i=0;i<NB_FRAMES;i++)
307        {
308           L1 += celt_sqrt(tonal->E[i][b]);
309           L2 += tonal->E[i][b];
310        }
311
312        stationarity = MIN16(0.99f,L1/celt_sqrt(EPSILON+NB_FRAMES*L2));
313        stationarity *= stationarity;
314        stationarity *= stationarity;
315        frame_stationarity += stationarity;
316        /*band_tonality[b] = tE/(1e-15+E)*/;
317        band_tonality[b] = MAX16(tE/(EPSILON+E), stationarity*tonal->prev_band_tonality[b]);
318 #if 0
319        if (b>=NB_TONAL_SKIP_BANDS)
320        {
321           frame_tonality += tweight[b]*band_tonality[b];
322           tw_sum += tweight[b];
323        }
324 #else
325        frame_tonality += band_tonality[b];
326        if (b>=NB_TBANDS-NB_TONAL_SKIP_BANDS)
327           frame_tonality -= band_tonality[b-NB_TBANDS+NB_TONAL_SKIP_BANDS];
328 #endif
329        max_frame_tonality = MAX16(max_frame_tonality, (1.f+.03f*(b-NB_TBANDS))*frame_tonality);
330        slope += band_tonality[b]*(b-8);
331        /*printf("%f %f ", band_tonality[b], stationarity);*/
332        tonal->prev_band_tonality[b] = band_tonality[b];
333     }
334
335     bandwidth_mask = 0;
336     bandwidth = 0;
337     for (b=0;b<NB_TOT_BANDS;b++)
338        maxE = MAX32(maxE, tonal->meanE[b]);
339     noise_floor = 5.7e-4f/(1<<(IMAX(0,lsb_depth-8)));
340     noise_floor *= noise_floor;
341     for (b=0;b<NB_TOT_BANDS;b++)
342     {
343        float E=0;
344        int band_start, band_end;
345        /* Keep a margin of 300 Hz for aliasing */
346        band_start = extra_bands[b]+3;
347        band_end = extra_bands[b+1]+3;
348        for (i=band_start;i<band_end;i++)
349        {
350           float binE = out[i].r*out[i].r + out[N-i].r*out[N-i].r
351                      + out[i].i*out[i].i + out[N-i].i*out[N-i].i;
352           E += binE;
353        }
354        E /= (band_end-band_start);
355        maxE = MAX32(maxE, E);
356        if (tonal->count>2)
357        {
358           tonal->meanE[b] = (1-alphaE2)*tonal->meanE[b] + alphaE2*E;
359        } else {
360           tonal->meanE[b] = E;
361        }
362        E = MAX32(E, tonal->meanE[b]);
363        /* 13 dB slope for spreading function */
364        bandwidth_mask = MAX32(.05f*bandwidth_mask, E);
365        /* Checks if band looks like stationary noise or if it's below a (trivial) masking curve */
366        if (E>.1*bandwidth_mask && E*1e10f > maxE && E > noise_floor)
367           bandwidth = b;
368     }
369     if (tonal->count<=2)
370        bandwidth = 20;
371     frame_loudness = 20*(float)log10(frame_loudness);
372     tonal->Etracker = MAX32(tonal->Etracker-.03f, frame_loudness);
373     tonal->lowECount *= (1-alphaE);
374     if (frame_loudness < tonal->Etracker-30)
375        tonal->lowECount += alphaE;
376
377     for (i=0;i<8;i++)
378     {
379        float sum=0;
380        for (b=0;b<16;b++)
381           sum += dct_table[i*16+b]*logE[b];
382        BFCC[i] = sum;
383     }
384
385     frame_stationarity /= NB_TBANDS;
386     relativeE /= NB_TBANDS;
387     if (tonal->count<10)
388        relativeE = .5;
389     frame_noisiness /= NB_TBANDS;
390 #if 1
391     info->activity = frame_noisiness + (1-frame_noisiness)*relativeE;
392 #else
393     info->activity = .5*(1+frame_noisiness-frame_stationarity);
394 #endif
395     frame_tonality = (max_frame_tonality/(NB_TBANDS-NB_TONAL_SKIP_BANDS));
396     frame_tonality = MAX16(frame_tonality, tonal->prev_tonality*.8f);
397     tonal->prev_tonality = frame_tonality;
398
399     slope /= 8*8;
400     info->tonality_slope = slope;
401
402     tonal->E_count = (tonal->E_count+1)%NB_FRAMES;
403     tonal->count++;
404     info->tonality = frame_tonality;
405
406     for (i=0;i<4;i++)
407        features[i] = -0.12299f*(BFCC[i]+tonal->mem[i+24]) + 0.49195f*(tonal->mem[i]+tonal->mem[i+16]) + 0.69693f*tonal->mem[i+8] - 1.4349f*tonal->cmean[i];
408
409     for (i=0;i<4;i++)
410        tonal->cmean[i] = (1-alpha)*tonal->cmean[i] + alpha*BFCC[i];
411
412     for (i=0;i<4;i++)
413         features[4+i] = 0.63246f*(BFCC[i]-tonal->mem[i+24]) + 0.31623f*(tonal->mem[i]-tonal->mem[i+16]);
414     for (i=0;i<3;i++)
415         features[8+i] = 0.53452f*(BFCC[i]+tonal->mem[i+24]) - 0.26726f*(tonal->mem[i]+tonal->mem[i+16]) -0.53452f*tonal->mem[i+8];
416
417     if (tonal->count > 5)
418     {
419        for (i=0;i<9;i++)
420           tonal->std[i] = (1-alpha)*tonal->std[i] + alpha*features[i]*features[i];
421     }
422
423     for (i=0;i<8;i++)
424     {
425        tonal->mem[i+24] = tonal->mem[i+16];
426        tonal->mem[i+16] = tonal->mem[i+8];
427        tonal->mem[i+8] = tonal->mem[i];
428        tonal->mem[i] = BFCC[i];
429     }
430     for (i=0;i<9;i++)
431        features[11+i] = celt_sqrt(tonal->std[i]);
432     features[20] = info->tonality;
433     features[21] = info->activity;
434     features[22] = frame_stationarity;
435     features[23] = info->tonality_slope;
436     features[24] = tonal->lowECount;
437
438 #ifndef FIXED_POINT
439     mlp_process(&net, features, &frame_prob);
440     frame_prob = .5f*(frame_prob+1);
441     /* Curve fitting between the MLP probability and the actual probability */
442     frame_prob = .01f + 1.21f*frame_prob*frame_prob - .23f*(float)pow(frame_prob, 10);
443
444     /*printf("%f\n", frame_prob);*/
445     {
446        float tau, beta;
447        float p0, p1;
448        float max_certainty;
449        /* One transition every 3 minutes */
450        tau = .00005f;
451        beta = .1f;
452        max_certainty = .01f+1.f/(20.f+.5f*tonal->last_transition);
453        p0 = (1-tonal->music_prob)*(1-tau) +    tonal->music_prob *tau;
454        p1 =    tonal->music_prob *(1-tau) + (1-tonal->music_prob)*tau;
455        p0 *= (float)pow(1-frame_prob, beta);
456        p1 *= (float)pow(frame_prob, beta);
457        tonal->music_prob = MAX16(max_certainty, MIN16(1-max_certainty, p1/(p0+p1)));
458        info->music_prob = tonal->music_prob;
459        /*printf("%f %f\n", frame_prob, info->music_prob);*/
460     }
461     if (tonal->last_music != (tonal->music_prob>.5f))
462        tonal->last_transition=0;
463     tonal->last_music = tonal->music_prob>.5f;
464 #else
465     info->music_prob = 0;
466 #endif
467     /*for (i=0;i<25;i++)
468        printf("%f ", features[i]);
469     printf("\n");*/
470
471     if (bandwidth<=12 || (bandwidth==13 && tonal->opus_bandwidth == OPUS_BANDWIDTH_NARROWBAND))
472        tonal->opus_bandwidth = OPUS_BANDWIDTH_NARROWBAND;
473     else if (bandwidth<=14 || (bandwidth==15 && tonal->opus_bandwidth == OPUS_BANDWIDTH_MEDIUMBAND))
474        tonal->opus_bandwidth = OPUS_BANDWIDTH_MEDIUMBAND;
475     else if (bandwidth<=16 || (bandwidth==17 && tonal->opus_bandwidth == OPUS_BANDWIDTH_WIDEBAND))
476        tonal->opus_bandwidth = OPUS_BANDWIDTH_WIDEBAND;
477     else if (bandwidth<=18)
478        tonal->opus_bandwidth = OPUS_BANDWIDTH_SUPERWIDEBAND;
479     else
480        tonal->opus_bandwidth = OPUS_BANDWIDTH_FULLBAND;
481
482     info->bandwidth = bandwidth;
483     info->opus_bandwidth = tonal->opus_bandwidth;
484     /*printf("%d %d\n", info->bandwidth, info->opus_bandwidth);*/
485     info->noisiness = frame_noisiness;
486     info->valid = 1;
487 }