Update opus from 1.1.4 to 1.2.1
This commit is contained in:
1 parent
c38c823a2a
commit
cb24c59567
155 files changed
+6263
-3968
No files matched your search
+380
-112
@@ -29,20 +29,27 @@
|
||||
#include "config.h"
|
||||
#endif
|
||||
|
||||
#define ANALYSIS_C
|
||||
|
||||
#include <stdio.h>
|
||||
|
||||
#include "mathops.h"
|
||||
#include "kiss_fft.h"
|
||||
#include "celt.h"
|
||||
#include "modes.h"
|
||||
#include "arch.h"
|
||||
#include "quant_bands.h"
|
||||
#include <stdio.h>
|
||||
#include "analysis.h"
|
||||
#include "mlp.h"
|
||||
#include "stack_alloc.h"
|
||||
#include "float_cast.h"
|
||||
|
||||
#ifndef M_PI
|
||||
#define M_PI 3.141592653
|
||||
#endif
|
||||
|
||||
#ifndef DISABLE_FLOAT_API
|
||||
|
||||
static const float dct_table[128] = {
|
||||
0.250000f, 0.250000f, 0.250000f, 0.250000f, 0.250000f, 0.250000f, 0.250000f, 0.250000f,
|
||||
0.250000f, 0.250000f, 0.250000f, 0.250000f, 0.250000f, 0.250000f, 0.250000f, 0.250000f,
|
||||
@@ -96,52 +103,118 @@ static const float analysis_window[240] = {
|
||||
};
|
||||
|
||||
static const int tbands[NB_TBANDS+1] = {
|
||||
2, 4, 6, 8, 10, 12, 14, 16, 20, 24, 28, 32, 40, 48, 56, 68, 80, 96, 120
|
||||
4, 8, 12, 16, 20, 24, 28, 32, 40, 48, 56, 64, 80, 96, 112, 136, 160, 192, 240
|
||||
};
|
||||
|
||||
static const int extra_bands[NB_TOT_BANDS+1] = {
|
||||
1, 2, 4, 6, 8, 10, 12, 14, 16, 20, 24, 28, 32, 40, 48, 56, 68, 80, 96, 120, 160, 200
|
||||
};
|
||||
|
||||
/*static const float tweight[NB_TBANDS+1] = {
|
||||
.3, .4, .5, .6, .7, .8, .9, 1., 1., 1., 1., 1., 1., 1., .8, .7, .6, .5
|
||||
};*/
|
||||
|
||||
#define NB_TONAL_SKIP_BANDS 9
|
||||
|
||||
#define cA 0.43157974f
|
||||
#define cB 0.67848403f
|
||||
#define cC 0.08595542f
|
||||
#define cE ((float)M_PI/2)
|
||||
static OPUS_INLINE float fast_atan2f(float y, float x) {
|
||||
float x2, y2;
|
||||
/* Should avoid underflow on the values we'll get */
|
||||
if (ABS16(x)+ABS16(y)<1e-9f)
|
||||
{
|
||||
x*=1e12f;
|
||||
y*=1e12f;
|
||||
}
|
||||
x2 = x*x;
|
||||
y2 = y*y;
|
||||
if(x2<y2){
|
||||
float den = (y2 + cB*x2) * (y2 + cC*x2);
|
||||
if (den!=0)
|
||||
return -x*y*(y2 + cA*x2) / den + (y<0 ? -cE : cE);
|
||||
else
|
||||
return (y<0 ? -cE : cE);
|
||||
}else{
|
||||
float den = (x2 + cB*y2) * (x2 + cC*y2);
|
||||
if (den!=0)
|
||||
return x*y*(x2 + cA*y2) / den + (y<0 ? -cE : cE) - (x*y<0 ? -cE : cE);
|
||||
else
|
||||
return (y<0 ? -cE : cE) - (x*y<0 ? -cE : cE);
|
||||
}
|
||||
static opus_val32 silk_resampler_down2_hp(
|
||||
opus_val32 *S, /* I/O State vector [ 2 ] */
|
||||
opus_val32 *out, /* O Output signal [ floor(len/2) ] */
|
||||
const opus_val32 *in, /* I Input signal [ len ] */
|
||||
int inLen /* I Number of input samples */
|
||||
)
|
||||
{
|
||||
int k, len2 = inLen/2;
|
||||
opus_val32 in32, out32, out32_hp, Y, X;
|
||||
opus_val64 hp_ener = 0;
|
||||
/* Internal variables and state are in Q10 format */
|
||||
for( k = 0; k < len2; k++ ) {
|
||||
/* Convert to Q10 */
|
||||
in32 = in[ 2 * k ];
|
||||
|
||||
/* All-pass section for even input sample */
|
||||
Y = SUB32( in32, S[ 0 ] );
|
||||
X = MULT16_32_Q15(QCONST16(0.6074371f, 15), Y);
|
||||
out32 = ADD32( S[ 0 ], X );
|
||||
S[ 0 ] = ADD32( in32, X );
|
||||
out32_hp = out32;
|
||||
/* Convert to Q10 */
|
||||
in32 = in[ 2 * k + 1 ];
|
||||
|
||||
/* All-pass section for odd input sample, and add to output of previous section */
|
||||
Y = SUB32( in32, S[ 1 ] );
|
||||
X = MULT16_32_Q15(QCONST16(0.15063f, 15), Y);
|
||||
out32 = ADD32( out32, S[ 1 ] );
|
||||
out32 = ADD32( out32, X );
|
||||
S[ 1 ] = ADD32( in32, X );
|
||||
|
||||
Y = SUB32( -in32, S[ 2 ] );
|
||||
X = MULT16_32_Q15(QCONST16(0.15063f, 15), Y);
|
||||
out32_hp = ADD32( out32_hp, S[ 2 ] );
|
||||
out32_hp = ADD32( out32_hp, X );
|
||||
S[ 2 ] = ADD32( -in32, X );
|
||||
|
||||
hp_ener += out32_hp*(opus_val64)out32_hp;
|
||||
/* Add, convert back to int16 and store to output */
|
||||
out[ k ] = HALF32(out32);
|
||||
}
|
||||
#ifdef FIXED_POINT
|
||||
/* len2 can be up to 480, so we shift by 8 more to make it fit. */
|
||||
hp_ener = hp_ener >> (2*SIG_SHIFT + 8);
|
||||
#endif
|
||||
return (opus_val32)hp_ener;
|
||||
}
|
||||
|
||||
void tonality_analysis_init(TonalityAnalysisState *tonal)
|
||||
static opus_val32 downmix_and_resample(downmix_func downmix, const void *_x, opus_val32 *y, opus_val32 S[3], int subframe, int offset, int c1, int c2, int C, int Fs)
|
||||
{
|
||||
VARDECL(opus_val32, tmp);
|
||||
opus_val32 scale;
|
||||
int j;
|
||||
opus_val32 ret = 0;
|
||||
SAVE_STACK;
|
||||
|
||||
if (subframe==0) return 0;
|
||||
if (Fs == 48000)
|
||||
{
|
||||
subframe *= 2;
|
||||
offset *= 2;
|
||||
} else if (Fs == 16000) {
|
||||
subframe = subframe*2/3;
|
||||
offset = offset*2/3;
|
||||
}
|
||||
ALLOC(tmp, subframe, opus_val32);
|
||||
|
||||
downmix(_x, tmp, subframe, offset, c1, c2, C);
|
||||
#ifdef FIXED_POINT
|
||||
scale = (1<<SIG_SHIFT);
|
||||
#else
|
||||
scale = 1.f/32768;
|
||||
#endif
|
||||
if (c2==-2)
|
||||
scale /= C;
|
||||
else if (c2>-1)
|
||||
scale /= 2;
|
||||
for (j=0;j<subframe;j++)
|
||||
tmp[j] *= scale;
|
||||
if (Fs == 48000)
|
||||
{
|
||||
ret = silk_resampler_down2_hp(S, y, tmp, subframe);
|
||||
} else if (Fs == 24000) {
|
||||
OPUS_COPY(y, tmp, subframe);
|
||||
} else if (Fs == 16000) {
|
||||
VARDECL(opus_val32, tmp3x);
|
||||
ALLOC(tmp3x, 3*subframe, opus_val32);
|
||||
/* Don't do this at home! This resampler is horrible and it's only (barely)
|
||||
usable for the purpose of the analysis because we don't care about all
|
||||
the aliasing between 8 kHz and 12 kHz. */
|
||||
for (j=0;j<subframe;j++)
|
||||
{
|
||||
tmp3x[3*j] = tmp[j];
|
||||
tmp3x[3*j+1] = tmp[j];
|
||||
tmp3x[3*j+2] = tmp[j];
|
||||
}
|
||||
silk_resampler_down2_hp(S, y, tmp3x, 3*subframe);
|
||||
}
|
||||
RESTORE_STACK;
|
||||
return ret;
|
||||
}
|
||||
|
||||
void tonality_analysis_init(TonalityAnalysisState *tonal, opus_int32 Fs)
|
||||
{
|
||||
/* Initialize reusable fields. */
|
||||
tonal->arch = opus_select_arch();
|
||||
tonal->Fs = Fs;
|
||||
/* Clear remaining fields. */
|
||||
tonality_analysis_reset(tonal);
|
||||
}
|
||||
@@ -151,6 +224,8 @@ void tonality_analysis_reset(TonalityAnalysisState *tonal)
|
||||
/* Clear non-reusable fields. */
|
||||
char *start = (char*)&tonal->TONALITY_ANALYSIS_RESET_START;
|
||||
OPUS_CLEAR(start, sizeof(TonalityAnalysisState) - (start - (char*)tonal));
|
||||
tonal->music_confidence = .9f;
|
||||
tonal->speech_confidence = .1f;
|
||||
}
|
||||
|
||||
void tonality_get_info(TonalityAnalysisState *tonal, AnalysisInfo *info_out, int len)
|
||||
@@ -158,6 +233,9 @@ void tonality_get_info(TonalityAnalysisState *tonal, AnalysisInfo *info_out, int
|
||||
int pos;
|
||||
int curr_lookahead;
|
||||
float psum;
|
||||
float tonality_max;
|
||||
float tonality_avg;
|
||||
int tonality_count;
|
||||
int i;
|
||||
|
||||
pos = tonal->read_pos;
|
||||
@@ -165,7 +243,8 @@ void tonality_get_info(TonalityAnalysisState *tonal, AnalysisInfo *info_out, int
|
||||
if (curr_lookahead<0)
|
||||
curr_lookahead += DETECT_SIZE;
|
||||
|
||||
if (len > 480 && pos != tonal->write_pos)
|
||||
/* On long frames, look at the second analysis window rather than the first. */
|
||||
if (len > tonal->Fs/50 && pos != tonal->write_pos)
|
||||
{
|
||||
pos++;
|
||||
if (pos==DETECT_SIZE)
|
||||
@@ -176,18 +255,32 @@ void tonality_get_info(TonalityAnalysisState *tonal, AnalysisInfo *info_out, int
|
||||
if (pos<0)
|
||||
pos = DETECT_SIZE-1;
|
||||
OPUS_COPY(info_out, &tonal->info[pos], 1);
|
||||
tonal->read_subframe += len/120;
|
||||
while (tonal->read_subframe>=4)
|
||||
tonality_max = tonality_avg = info_out->tonality;
|
||||
tonality_count = 1;
|
||||
/* If possible, look ahead for a tone to compensate for the delay in the tone detector. */
|
||||
for (i=0;i<3;i++)
|
||||
{
|
||||
tonal->read_subframe -= 4;
|
||||
pos++;
|
||||
if (pos==DETECT_SIZE)
|
||||
pos = 0;
|
||||
if (pos == tonal->write_pos)
|
||||
break;
|
||||
tonality_max = MAX32(tonality_max, tonal->info[pos].tonality);
|
||||
tonality_avg += tonal->info[pos].tonality;
|
||||
tonality_count++;
|
||||
}
|
||||
info_out->tonality = MAX32(tonality_avg/tonality_count, tonality_max-.2f);
|
||||
tonal->read_subframe += len/(tonal->Fs/400);
|
||||
while (tonal->read_subframe>=8)
|
||||
{
|
||||
tonal->read_subframe -= 8;
|
||||
tonal->read_pos++;
|
||||
}
|
||||
if (tonal->read_pos>=DETECT_SIZE)
|
||||
tonal->read_pos-=DETECT_SIZE;
|
||||
|
||||
/* Compensate for the delay in the features themselves.
|
||||
FIXME: Need a better estimate the 10 I just made up */
|
||||
curr_lookahead = IMAX(curr_lookahead-10, 0);
|
||||
/* The -1 is to compensate for the delay in the features themselves. */
|
||||
curr_lookahead = IMAX(curr_lookahead-1, 0);
|
||||
|
||||
psum=0;
|
||||
/* Summing the probability of transition patterns that involve music at
|
||||
@@ -197,11 +290,28 @@ void tonality_get_info(TonalityAnalysisState *tonal, AnalysisInfo *info_out, int
|
||||
for (;i<DETECT_SIZE;i++)
|
||||
psum += tonal->pspeech[i];
|
||||
psum = psum*tonal->music_confidence + (1-psum)*tonal->speech_confidence;
|
||||
/*printf("%f %f %f\n", psum, info_out->music_prob, info_out->tonality);*/
|
||||
/*printf("%f %f %f %f %f\n", psum, info_out->music_prob, info_out->vad_prob, info_out->activity_probability, info_out->tonality);*/
|
||||
|
||||
info_out->music_prob = psum;
|
||||
}
|
||||
|
||||
static const float std_feature_bias[9] = {
|
||||
5.684947f, 3.475288f, 1.770634f, 1.599784f, 3.773215f,
|
||||
2.163313f, 1.260756f, 1.116868f, 1.918795f
|
||||
};
|
||||
|
||||
#define LEAKAGE_OFFSET 2.5f
|
||||
#define LEAKAGE_SLOPE 2.f
|
||||
|
||||
#ifdef FIXED_POINT
|
||||
/* For fixed-point, the input is +/-2^15 shifted up by SIG_SHIFT, so we need to
|
||||
compensate for that in the energy. */
|
||||
#define SCALE_COMPENS (1.f/((opus_int32)1<<(15+SIG_SHIFT)))
|
||||
#define SCALE_ENER(e) ((SCALE_COMPENS*SCALE_COMPENS)*(e))
|
||||
#else
|
||||
#define SCALE_ENER(e) (e)
|
||||
#endif
|
||||
|
||||
static void tonality_analysis(TonalityAnalysisState *tonal, const CELTMode *celt_mode, const void *x, int len, int offset, int c1, int c2, int C, int lsb_depth, downmix_func downmix)
|
||||
{
|
||||
int i, b;
|
||||
@@ -235,19 +345,41 @@ static void tonality_analysis(TonalityAnalysisState *tonal, const CELTMode *celt
|
||||
float noise_floor;
|
||||
int remaining;
|
||||
AnalysisInfo *info;
|
||||
float hp_ener;
|
||||
float tonality2[240];
|
||||
float midE[8];
|
||||
float spec_variability=0;
|
||||
float band_log2[NB_TBANDS+1];
|
||||
float leakage_from[NB_TBANDS+1];
|
||||
float leakage_to[NB_TBANDS+1];
|
||||
SAVE_STACK;
|
||||
|
||||
tonal->last_transition++;
|
||||
alpha = 1.f/IMIN(20, 1+tonal->count);
|
||||
alphaE = 1.f/IMIN(50, 1+tonal->count);
|
||||
alphaE2 = 1.f/IMIN(1000, 1+tonal->count);
|
||||
alpha = 1.f/IMIN(10, 1+tonal->count);
|
||||
alphaE = 1.f/IMIN(25, 1+tonal->count);
|
||||
alphaE2 = 1.f/IMIN(500, 1+tonal->count);
|
||||
|
||||
if (tonal->count<4)
|
||||
tonal->music_prob = .5;
|
||||
if (tonal->Fs == 48000)
|
||||
{
|
||||
/* len and offset are now at 24 kHz. */
|
||||
len/= 2;
|
||||
offset /= 2;
|
||||
} else if (tonal->Fs == 16000) {
|
||||
len = 3*len/2;
|
||||
offset = 3*offset/2;
|
||||
}
|
||||
|
||||
if (tonal->count<4) {
|
||||
if (tonal->application == OPUS_APPLICATION_VOIP)
|
||||
tonal->music_prob = .1f;
|
||||
else
|
||||
tonal->music_prob = .625f;
|
||||
}
|
||||
kfft = celt_mode->mdct.kfft[0];
|
||||
if (tonal->count==0)
|
||||
tonal->mem_fill = 240;
|
||||
downmix(x, &tonal->inmem[tonal->mem_fill], IMIN(len, ANALYSIS_BUF_SIZE-tonal->mem_fill), offset, c1, c2, C);
|
||||
tonal->hp_ener_accum += (float)downmix_and_resample(downmix, x,
|
||||
&tonal->inmem[tonal->mem_fill], tonal->downmix_state,
|
||||
IMIN(len, ANALYSIS_BUF_SIZE-tonal->mem_fill), offset, c1, c2, C, tonal->Fs);
|
||||
if (tonal->mem_fill+len < ANALYSIS_BUF_SIZE)
|
||||
{
|
||||
tonal->mem_fill += len;
|
||||
@@ -255,6 +387,7 @@ static void tonality_analysis(TonalityAnalysisState *tonal, const CELTMode *celt
|
||||
RESTORE_STACK;
|
||||
return;
|
||||
}
|
||||
hp_ener = tonal->hp_ener_accum;
|
||||
info = &tonal->info[tonal->write_pos++];
|
||||
if (tonal->write_pos>=DETECT_SIZE)
|
||||
tonal->write_pos-=DETECT_SIZE;
|
||||
@@ -273,7 +406,9 @@ static void tonality_analysis(TonalityAnalysisState *tonal, const CELTMode *celt
|
||||
}
|
||||
OPUS_MOVE(tonal->inmem, tonal->inmem+ANALYSIS_BUF_SIZE-240, 240);
|
||||
remaining = len - (ANALYSIS_BUF_SIZE-tonal->mem_fill);
|
||||
downmix(x, &tonal->inmem[240], remaining, offset+ANALYSIS_BUF_SIZE-tonal->mem_fill, c1, c2, C);
|
||||
tonal->hp_ener_accum = (float)downmix_and_resample(downmix, x,
|
||||
&tonal->inmem[240], tonal->downmix_state, remaining,
|
||||
offset+ANALYSIS_BUF_SIZE-tonal->mem_fill, c1, c2, C, tonal->Fs);
|
||||
tonal->mem_fill = 240 + remaining;
|
||||
opus_fft(kfft, in, out, tonal->arch);
|
||||
#ifndef FIXED_POINT
|
||||
@@ -305,24 +440,31 @@ static void tonality_analysis(TonalityAnalysisState *tonal, const CELTMode *celt
|
||||
d_angle2 = angle2 - angle;
|
||||
d2_angle2 = d_angle2 - d_angle;
|
||||
|
||||
mod1 = d2_angle - (float)floor(.5+d2_angle);
|
||||
mod1 = d2_angle - (float)float2int(d2_angle);
|
||||
noisiness[i] = ABS16(mod1);
|
||||
mod1 *= mod1;
|
||||
mod1 *= mod1;
|
||||
|
||||
mod2 = d2_angle2 - (float)floor(.5+d2_angle2);
|
||||
mod2 = d2_angle2 - (float)float2int(d2_angle2);
|
||||
noisiness[i] += ABS16(mod2);
|
||||
mod2 *= mod2;
|
||||
mod2 *= mod2;
|
||||
|
||||
avg_mod = .25f*(d2A[i]+2.f*mod1+mod2);
|
||||
avg_mod = .25f*(d2A[i]+mod1+2*mod2);
|
||||
/* This introduces an extra delay of 2 frames in the detection. */
|
||||
tonality[i] = 1.f/(1.f+40.f*16.f*pi4*avg_mod)-.015f;
|
||||
/* No delay on this detection, but it's less reliable. */
|
||||
tonality2[i] = 1.f/(1.f+40.f*16.f*pi4*mod2)-.015f;
|
||||
|
||||
A[i] = angle2;
|
||||
dA[i] = d_angle2;
|
||||
d2A[i] = mod2;
|
||||
}
|
||||
|
||||
for (i=2;i<N2-1;i++)
|
||||
{
|
||||
float tt = MIN32(tonality2[i], MAX32(tonality2[i-1], tonality2[i+1]));
|
||||
tonality[i] = .9f*MAX32(tonality[i], tt-.1f);
|
||||
}
|
||||
frame_tonality = 0;
|
||||
max_frame_tonality = 0;
|
||||
/*tw_sum = 0;*/
|
||||
@@ -339,6 +481,22 @@ static void tonality_analysis(TonalityAnalysisState *tonal, const CELTMode *celt
|
||||
}
|
||||
relativeE = 0;
|
||||
frame_loudness = 0;
|
||||
/* The energy of the very first band is special because of DC. */
|
||||
{
|
||||
float E = 0;
|
||||
float X1r, X2r;
|
||||
X1r = 2*(float)out[0].r;
|
||||
X2r = 2*(float)out[0].i;
|
||||
E = X1r*X1r + X2r*X2r;
|
||||
for (i=1;i<4;i++)
|
||||
{
|
||||
float binE = out[i].r*(float)out[i].r + out[N-i].r*(float)out[N-i].r
|
||||
+ out[i].i*(float)out[i].i + out[N-i].i*(float)out[N-i].i;
|
||||
E += binE;
|
||||
}
|
||||
E = SCALE_ENER(E);
|
||||
band_log2[0] = .5f*1.442695f*(float)log(E+1e-10f);
|
||||
}
|
||||
for (b=0;b<NB_TBANDS;b++)
|
||||
{
|
||||
float E=0, tE=0, nE=0;
|
||||
@@ -348,12 +506,9 @@ static void tonality_analysis(TonalityAnalysisState *tonal, const CELTMode *celt
|
||||
{
|
||||
float binE = out[i].r*(float)out[i].r + out[N-i].r*(float)out[N-i].r
|
||||
+ out[i].i*(float)out[i].i + out[N-i].i*(float)out[N-i].i;
|
||||
#ifdef FIXED_POINT
|
||||
/* FIXME: It's probably best to change the BFCC filter initial state instead */
|
||||
binE *= 5.55e-17f;
|
||||
#endif
|
||||
binE = SCALE_ENER(binE);
|
||||
E += binE;
|
||||
tE += binE*tonality[i];
|
||||
tE += binE*MAX32(0, tonality[i]);
|
||||
nE += binE*2.f*(.5f-noisiness[i]);
|
||||
}
|
||||
#ifndef FIXED_POINT
|
||||
@@ -371,14 +526,27 @@ static void tonality_analysis(TonalityAnalysisState *tonal, const CELTMode *celt
|
||||
|
||||
frame_loudness += (float)sqrt(E+1e-10f);
|
||||
logE[b] = (float)log(E+1e-10f);
|
||||
tonal->lowE[b] = MIN32(logE[b], tonal->lowE[b]+.01f);
|
||||
tonal->highE[b] = MAX32(logE[b], tonal->highE[b]-.1f);
|
||||
if (tonal->highE[b] < tonal->lowE[b]+1.f)
|
||||
band_log2[b+1] = .5f*1.442695f*(float)log(E+1e-10f);
|
||||
tonal->logE[tonal->E_count][b] = logE[b];
|
||||
if (tonal->count==0)
|
||||
tonal->highE[b] = tonal->lowE[b] = logE[b];
|
||||
if (tonal->highE[b] > tonal->lowE[b] + 7.5)
|
||||
{
|
||||
tonal->highE[b]+=.5f;
|
||||
tonal->lowE[b]-=.5f;
|
||||
if (tonal->highE[b] - logE[b] > logE[b] - tonal->lowE[b])
|
||||
tonal->highE[b] -= .01f;
|
||||
else
|
||||
tonal->lowE[b] += .01f;
|
||||
}
|
||||
relativeE += (logE[b]-tonal->lowE[b])/(1e-15f+tonal->highE[b]-tonal->lowE[b]);
|
||||
if (logE[b] > tonal->highE[b])
|
||||
{
|
||||
tonal->highE[b] = logE[b];
|
||||
tonal->lowE[b] = MAX32(tonal->highE[b]-15, tonal->lowE[b]);
|
||||
} else if (logE[b] < tonal->lowE[b])
|
||||
{
|
||||
tonal->lowE[b] = logE[b];
|
||||
tonal->highE[b] = MIN32(tonal->lowE[b]+15, tonal->highE[b]);
|
||||
}
|
||||
relativeE += (logE[b]-tonal->lowE[b])/(1e-15f + (tonal->highE[b]-tonal->lowE[b]));
|
||||
|
||||
L1=L2=0;
|
||||
for (i=0;i<NB_FRAMES;i++)
|
||||
@@ -410,27 +578,74 @@ static void tonality_analysis(TonalityAnalysisState *tonal, const CELTMode *celt
|
||||
tonal->prev_band_tonality[b] = band_tonality[b];
|
||||
}
|
||||
|
||||
leakage_from[0] = band_log2[0];
|
||||
leakage_to[0] = band_log2[0] - LEAKAGE_OFFSET;
|
||||
for (b=1;b<NB_TBANDS+1;b++)
|
||||
{
|
||||
float leak_slope = LEAKAGE_SLOPE*(tbands[b]-tbands[b-1])/4;
|
||||
leakage_from[b] = MIN16(leakage_from[b-1]+leak_slope, band_log2[b]);
|
||||
leakage_to[b] = MAX16(leakage_to[b-1]-leak_slope, band_log2[b]-LEAKAGE_OFFSET);
|
||||
}
|
||||
for (b=NB_TBANDS-2;b>=0;b--)
|
||||
{
|
||||
float leak_slope = LEAKAGE_SLOPE*(tbands[b+1]-tbands[b])/4;
|
||||
leakage_from[b] = MIN16(leakage_from[b+1]+leak_slope, leakage_from[b]);
|
||||
leakage_to[b] = MAX16(leakage_to[b+1]-leak_slope, leakage_to[b]);
|
||||
}
|
||||
celt_assert(NB_TBANDS+1 <= LEAK_BANDS);
|
||||
for (b=0;b<NB_TBANDS+1;b++)
|
||||
{
|
||||
/* leak_boost[] is made up of two terms. The first, based on leakage_to[],
|
||||
represents the boost needed to overcome the amount of analysis leakage
|
||||
cause in a weaker band b by louder neighbouring bands.
|
||||
The second, based on leakage_from[], applies to a loud band b for
|
||||
which the quantization noise causes synthesis leakage to the weaker
|
||||
neighbouring bands. */
|
||||
float boost = MAX16(0, leakage_to[b] - band_log2[b]) +
|
||||
MAX16(0, band_log2[b] - (leakage_from[b]+LEAKAGE_OFFSET));
|
||||
info->leak_boost[b] = IMIN(255, (int)floor(.5 + 64.f*boost));
|
||||
}
|
||||
for (;b<LEAK_BANDS;b++) info->leak_boost[b] = 0;
|
||||
|
||||
for (i=0;i<NB_FRAMES;i++)
|
||||
{
|
||||
int j;
|
||||
float mindist = 1e15f;
|
||||
for (j=0;j<NB_FRAMES;j++)
|
||||
{
|
||||
int k;
|
||||
float dist=0;
|
||||
for (k=0;k<NB_TBANDS;k++)
|
||||
{
|
||||
float tmp;
|
||||
tmp = tonal->logE[i][k] - tonal->logE[j][k];
|
||||
dist += tmp*tmp;
|
||||
}
|
||||
if (j!=i)
|
||||
mindist = MIN32(mindist, dist);
|
||||
}
|
||||
spec_variability += mindist;
|
||||
}
|
||||
spec_variability = (float)sqrt(spec_variability/NB_FRAMES/NB_TBANDS);
|
||||
bandwidth_mask = 0;
|
||||
bandwidth = 0;
|
||||
maxE = 0;
|
||||
noise_floor = 5.7e-4f/(1<<(IMAX(0,lsb_depth-8)));
|
||||
#ifdef FIXED_POINT
|
||||
noise_floor *= 1<<(15+SIG_SHIFT);
|
||||
#endif
|
||||
noise_floor *= noise_floor;
|
||||
for (b=0;b<NB_TOT_BANDS;b++)
|
||||
for (b=0;b<NB_TBANDS;b++)
|
||||
{
|
||||
float E=0;
|
||||
int band_start, band_end;
|
||||
/* Keep a margin of 300 Hz for aliasing */
|
||||
band_start = extra_bands[b];
|
||||
band_end = extra_bands[b+1];
|
||||
band_start = tbands[b];
|
||||
band_end = tbands[b+1];
|
||||
for (i=band_start;i<band_end;i++)
|
||||
{
|
||||
float binE = out[i].r*(float)out[i].r + out[N-i].r*(float)out[N-i].r
|
||||
+ out[i].i*(float)out[i].i + out[N-i].i*(float)out[N-i].i;
|
||||
E += binE;
|
||||
}
|
||||
E = SCALE_ENER(E);
|
||||
maxE = MAX32(maxE, E);
|
||||
tonal->meanE[b] = MAX32((1-alphaE2)*tonal->meanE[b], E);
|
||||
E = MAX32(E, tonal->meanE[b]);
|
||||
@@ -441,14 +656,36 @@ static void tonality_analysis(TonalityAnalysisState *tonal, const CELTMode *celt
|
||||
2) less than 90 dB below the peak band (maximal masking possible considering
|
||||
both the ATH and the loudness-dependent slope of the spreading function)
|
||||
3) above the PCM quantization noise floor
|
||||
We use b+1 because the first CELT band isn't included in tbands[]
|
||||
*/
|
||||
if (E>.1*bandwidth_mask && E*1e9f > maxE && E > noise_floor*(band_end-band_start))
|
||||
bandwidth = b;
|
||||
bandwidth = b+1;
|
||||
}
|
||||
/* Special case for the last two bands, for which we don't have spectrum but only
|
||||
the energy above 12 kHz. */
|
||||
if (tonal->Fs == 48000) {
|
||||
float ratio;
|
||||
float E = hp_ener*(1.f/(240*240));
|
||||
ratio = tonal->prev_bandwidth==20 ? 0.03f : 0.07f;
|
||||
#ifdef FIXED_POINT
|
||||
/* silk_resampler_down2_hp() shifted right by an extra 8 bits. */
|
||||
E *= 256.f*(1.f/Q15ONE)*(1.f/Q15ONE);
|
||||
#endif
|
||||
maxE = MAX32(maxE, E);
|
||||
tonal->meanE[b] = MAX32((1-alphaE2)*tonal->meanE[b], E);
|
||||
E = MAX32(E, tonal->meanE[b]);
|
||||
/* Use a simple follower with 13 dB/Bark slope for spreading function */
|
||||
bandwidth_mask = MAX32(.05f*bandwidth_mask, E);
|
||||
if (E>ratio*bandwidth_mask && E*1e9f > maxE && E > noise_floor*160)
|
||||
bandwidth = 20;
|
||||
/* This detector is unreliable, so if the bandwidth is close to SWB, assume it's FB. */
|
||||
if (bandwidth >= 17)
|
||||
bandwidth = 20;
|
||||
}
|
||||
if (tonal->count<=2)
|
||||
bandwidth = 20;
|
||||
frame_loudness = 20*(float)log10(frame_loudness);
|
||||
tonal->Etracker = MAX32(tonal->Etracker-.03f, frame_loudness);
|
||||
tonal->Etracker = MAX32(tonal->Etracker-.003f, frame_loudness);
|
||||
tonal->lowECount *= (1-alphaE);
|
||||
if (frame_loudness < tonal->Etracker-30)
|
||||
tonal->lowECount += alphaE;
|
||||
@@ -460,11 +697,18 @@ static void tonality_analysis(TonalityAnalysisState *tonal, const CELTMode *celt
|
||||
sum += dct_table[i*16+b]*logE[b];
|
||||
BFCC[i] = sum;
|
||||
}
|
||||
for (i=0;i<8;i++)
|
||||
{
|
||||
float sum=0;
|
||||
for (b=0;b<16;b++)
|
||||
sum += dct_table[i*16+b]*.5f*(tonal->highE[b]+tonal->lowE[b]);
|
||||
midE[i] = sum;
|
||||
}
|
||||
|
||||
frame_stationarity /= NB_TBANDS;
|
||||
relativeE /= NB_TBANDS;
|
||||
if (tonal->count<10)
|
||||
relativeE = .5;
|
||||
relativeE = .5f;
|
||||
frame_noisiness /= NB_TBANDS;
|
||||
#if 1
|
||||
info->activity = frame_noisiness + (1-frame_noisiness)*relativeE;
|
||||
@@ -479,7 +723,7 @@ static void tonality_analysis(TonalityAnalysisState *tonal, const CELTMode *celt
|
||||
info->tonality_slope = slope;
|
||||
|
||||
tonal->E_count = (tonal->E_count+1)%NB_FRAMES;
|
||||
tonal->count++;
|
||||
tonal->count = IMIN(tonal->count+1, ANALYSIS_COUNT_MAX);
|
||||
info->tonality = frame_tonality;
|
||||
|
||||
for (i=0;i<4;i++)
|
||||
@@ -498,6 +742,8 @@ static void tonality_analysis(TonalityAnalysisState *tonal, const CELTMode *celt
|
||||
for (i=0;i<9;i++)
|
||||
tonal->std[i] = (1-alpha)*tonal->std[i] + alpha*features[i]*features[i];
|
||||
}
|
||||
for (i=0;i<4;i++)
|
||||
features[i] = BFCC[i]-midE[i];
|
||||
|
||||
for (i=0;i<8;i++)
|
||||
{
|
||||
@@ -507,24 +753,26 @@ static void tonality_analysis(TonalityAnalysisState *tonal, const CELTMode *celt
|
||||
tonal->mem[i] = BFCC[i];
|
||||
}
|
||||
for (i=0;i<9;i++)
|
||||
features[11+i] = (float)sqrt(tonal->std[i]);
|
||||
features[20] = info->tonality;
|
||||
features[21] = info->activity;
|
||||
features[22] = frame_stationarity;
|
||||
features[23] = info->tonality_slope;
|
||||
features[24] = tonal->lowECount;
|
||||
features[11+i] = (float)sqrt(tonal->std[i]) - std_feature_bias[i];
|
||||
features[18] = spec_variability - 0.78f;
|
||||
features[20] = info->tonality - 0.154723f;
|
||||
features[21] = info->activity - 0.724643f;
|
||||
features[22] = frame_stationarity - 0.743717f;
|
||||
features[23] = info->tonality_slope + 0.069216f;
|
||||
features[24] = tonal->lowECount - 0.067930f;
|
||||
|
||||
#ifndef DISABLE_FLOAT_API
|
||||
mlp_process(&net, features, frame_probs);
|
||||
frame_probs[0] = .5f*(frame_probs[0]+1);
|
||||
/* Curve fitting between the MLP probability and the actual probability */
|
||||
frame_probs[0] = .01f + 1.21f*frame_probs[0]*frame_probs[0] - .23f*(float)pow(frame_probs[0], 10);
|
||||
/*frame_probs[0] = .01f + 1.21f*frame_probs[0]*frame_probs[0] - .23f*(float)pow(frame_probs[0], 10);*/
|
||||
/* Probability of active audio (as opposed to silence) */
|
||||
frame_probs[1] = .5f*frame_probs[1]+.5f;
|
||||
/* Consider that silence has a 50-50 probability. */
|
||||
frame_probs[0] = frame_probs[1]*frame_probs[0] + (1-frame_probs[1])*.5f;
|
||||
frame_probs[1] *= frame_probs[1];
|
||||
|
||||
/*printf("%f %f ", frame_probs[0], frame_probs[1]);*/
|
||||
/* Probability of speech or music vs noise */
|
||||
info->activity_probability = frame_probs[1];
|
||||
|
||||
/*printf("%f %f\n", frame_probs[0], frame_probs[1]);*/
|
||||
{
|
||||
/* Probability of state transition */
|
||||
float tau;
|
||||
@@ -542,12 +790,32 @@ static void tonality_analysis(TonalityAnalysisState *tonal, const CELTMode *celt
|
||||
float music0;
|
||||
float p, q;
|
||||
|
||||
/* More silence transitions for speech than for music. */
|
||||
tau = .001f*tonal->music_prob + .01f*(1-tonal->music_prob);
|
||||
p = MAX16(.05f,MIN16(.95f,frame_probs[1]));
|
||||
q = MAX16(.05f,MIN16(.95f,tonal->vad_prob));
|
||||
beta = .02f+.05f*ABS16(p-q)/(p*(1-q)+q*(1-p));
|
||||
/* p0 and p1 are the probabilities of speech and music at this frame
|
||||
using only information from previous frame and applying the
|
||||
state transition model */
|
||||
p0 = (1-tonal->vad_prob)*(1-tau) + tonal->vad_prob *tau;
|
||||
p1 = tonal->vad_prob *(1-tau) + (1-tonal->vad_prob)*tau;
|
||||
/* We apply the current probability with exponent beta to work around
|
||||
the fact that the probability estimates aren't independent. */
|
||||
p0 *= (float)pow(1-frame_probs[1], beta);
|
||||
p1 *= (float)pow(frame_probs[1], beta);
|
||||
/* Normalise the probabilities to get the Marokv probability of music. */
|
||||
tonal->vad_prob = p1/(p0+p1);
|
||||
info->vad_prob = tonal->vad_prob;
|
||||
/* Consider that silence has a 50-50 probability of being speech or music. */
|
||||
frame_probs[0] = tonal->vad_prob*frame_probs[0] + (1-tonal->vad_prob)*.5f;
|
||||
|
||||
/* One transition every 3 minutes of active audio */
|
||||
tau = .00005f*frame_probs[1];
|
||||
tau = .0001f;
|
||||
/* Adapt beta based on how "unexpected" the new prob is */
|
||||
p = MAX16(.05f,MIN16(.95f,frame_probs[0]));
|
||||
q = MAX16(.05f,MIN16(.95f,tonal->music_prob));
|
||||
beta = .01f+.05f*ABS16(p-q)/(p*(1-q)+q*(1-p));
|
||||
beta = .02f+.05f*ABS16(p-q)/(p*(1-q)+q*(1-p));
|
||||
/* p0 and p1 are the probabilities of speech and music at this frame
|
||||
using only information from previous frame and applying the
|
||||
state transition model */
|
||||
@@ -561,6 +829,7 @@ static void tonality_analysis(TonalityAnalysisState *tonal, const CELTMode *celt
|
||||
tonal->music_prob = p1/(p0+p1);
|
||||
info->music_prob = tonal->music_prob;
|
||||
|
||||
/*printf("%f %f %f %f\n", frame_probs[0], frame_probs[1], tonal->music_prob, tonal->vad_prob);*/
|
||||
/* This chunk of code deals with delayed decision. */
|
||||
psum=1e-20f;
|
||||
/* Instantaneous probability of speech and music, with beta pre-applied. */
|
||||
@@ -568,8 +837,11 @@ static void tonality_analysis(TonalityAnalysisState *tonal, const CELTMode *celt
|
||||
music0 = (float)pow(frame_probs[0], beta);
|
||||
if (tonal->count==1)
|
||||
{
|
||||
tonal->pspeech[0]=.5;
|
||||
tonal->pmusic [0]=.5;
|
||||
if (tonal->application == OPUS_APPLICATION_VOIP)
|
||||
tonal->pmusic[0] = .1f;
|
||||
else
|
||||
tonal->pmusic[0] = .625f;
|
||||
tonal->pspeech[0] = 1-tonal->pmusic[0];
|
||||
}
|
||||
/* Updated probability of having only speech (s0) or only music (m0),
|
||||
before considering the new observation. */
|
||||
@@ -619,24 +891,17 @@ static void tonality_analysis(TonalityAnalysisState *tonal, const CELTMode *celt
|
||||
tonal->speech_confidence_count = IMIN(tonal->speech_confidence_count, 500);
|
||||
tonal->speech_confidence += adapt*MIN16(.2f,frame_probs[0]-tonal->speech_confidence);
|
||||
}
|
||||
} else {
|
||||
if (tonal->music_confidence_count==0)
|
||||
tonal->music_confidence = .9f;
|
||||
if (tonal->speech_confidence_count==0)
|
||||
tonal->speech_confidence = .1f;
|
||||
}
|
||||
}
|
||||
if (tonal->last_music != (tonal->music_prob>.5f))
|
||||
tonal->last_transition=0;
|
||||
tonal->last_music = tonal->music_prob>.5f;
|
||||
#else
|
||||
info->music_prob = 0;
|
||||
#endif
|
||||
/*for (i=0;i<25;i++)
|
||||
#ifdef MLP_TRAINING
|
||||
for (i=0;i<25;i++)
|
||||
printf("%f ", features[i]);
|
||||
printf("\n");*/
|
||||
printf("\n");
|
||||
#endif
|
||||
|
||||
info->bandwidth = bandwidth;
|
||||
tonal->prev_bandwidth = bandwidth;
|
||||
/*printf("%d %d\n", info->bandwidth, info->opus_bandwidth);*/
|
||||
info->noisiness = frame_noisiness;
|
||||
info->valid = 1;
|
||||
@@ -650,18 +915,19 @@ void run_analysis(TonalityAnalysisState *analysis, const CELTMode *celt_mode, co
|
||||
int offset;
|
||||
int pcm_len;
|
||||
|
||||
analysis_frame_size -= analysis_frame_size&1;
|
||||
if (analysis_pcm != NULL)
|
||||
{
|
||||
/* Avoid overflow/wrap-around of the analysis buffer */
|
||||
analysis_frame_size = IMIN((DETECT_SIZE-5)*Fs/100, analysis_frame_size);
|
||||
analysis_frame_size = IMIN((DETECT_SIZE-5)*Fs/50, analysis_frame_size);
|
||||
|
||||
pcm_len = analysis_frame_size - analysis->analysis_offset;
|
||||
offset = analysis->analysis_offset;
|
||||
do {
|
||||
tonality_analysis(analysis, celt_mode, analysis_pcm, IMIN(480, pcm_len), offset, c1, c2, C, lsb_depth, downmix);
|
||||
offset += 480;
|
||||
pcm_len -= 480;
|
||||
} while (pcm_len>0);
|
||||
while (pcm_len>0) {
|
||||
tonality_analysis(analysis, celt_mode, analysis_pcm, IMIN(Fs/50, pcm_len), offset, c1, c2, C, lsb_depth, downmix);
|
||||
offset += Fs/50;
|
||||
pcm_len -= Fs/50;
|
||||
}
|
||||
analysis->analysis_offset = analysis_frame_size;
|
||||
|
||||
analysis->analysis_offset -= frame_size;
|
||||
@@ -670,3 +936,5 @@ void run_analysis(TonalityAnalysisState *analysis, const CELTMode *celt_mode, co
|
||||
analysis_info->valid = 0;
|
||||
tonality_get_info(analysis, analysis_info, frame_size);
|
||||
}
|
||||
|
||||
#endif /* DISABLE_FLOAT_API */
|
||||
@@ -33,13 +33,20 @@
|
||||
|
||||
#define NB_FRAMES 8
|
||||
#define NB_TBANDS 18
|
||||
#define NB_TOT_BANDS 21
|
||||
#define ANALYSIS_BUF_SIZE 720 /* 15 ms at 48 kHz */
|
||||
#define ANALYSIS_BUF_SIZE 720 /* 30 ms at 24 kHz */
|
||||
|
||||
#define DETECT_SIZE 200
|
||||
/* At that point we can stop counting frames because it no longer matters. */
|
||||
#define ANALYSIS_COUNT_MAX 10000
|
||||
|
||||
#define DETECT_SIZE 100
|
||||
|
||||
/* Uncomment this to print the MLP features on stdout. */
|
||||
/*#define MLP_TRAINING*/
|
||||
|
||||
typedef struct {
|
||||
int arch;
|
||||
int application;
|
||||
opus_int32 Fs;
|
||||
#define TONALITY_ANALYSIS_RESET_START angle
|
||||
float angle[240];
|
||||
float d_angle[240];
|
||||
@@ -48,21 +55,22 @@ typedef struct {
|
||||
int mem_fill; /* number of usable samples in the buffer */
|
||||
float prev_band_tonality[NB_TBANDS];
|
||||
float prev_tonality;
|
||||
int prev_bandwidth;
|
||||
float E[NB_FRAMES][NB_TBANDS];
|
||||
float logE[NB_FRAMES][NB_TBANDS];
|
||||
float lowE[NB_TBANDS];
|
||||
float highE[NB_TBANDS];
|
||||
float meanE[NB_TOT_BANDS];
|
||||
float meanE[NB_TBANDS+1];
|
||||
float mem[32];
|
||||
float cmean[8];
|
||||
float std[9];
|
||||
float music_prob;
|
||||
float vad_prob;
|
||||
float Etracker;
|
||||
float lowECount;
|
||||
int E_count;
|
||||
int last_music;
|
||||
int last_transition;
|
||||
int count;
|
||||
float subframe_mem[3];
|
||||
int analysis_offset;
|
||||
/** Probability of having speech for time i to DETECT_SIZE-1 (and music before).
|
||||
pspeech[0] is the probability that all frames in the window are speech. */
|
||||
@@ -77,6 +85,8 @@ typedef struct {
|
||||
int write_pos;
|
||||
int read_pos;
|
||||
int read_subframe;
|
||||
float hp_ener_accum;
|
||||
opus_val32 downmix_state[3];
|
||||
AnalysisInfo info[DETECT_SIZE];
|
||||
} TonalityAnalysisState;
|
||||
|
||||
@@ -86,7 +96,7 @@ typedef struct {
|
||||
* not be repeated every analysis step. No allocated memory is retained
|
||||
* by the state struct, so no cleanup call is required.
|
||||
*/
|
||||
void tonality_analysis_init(TonalityAnalysisState *analysis);
|
||||
void tonality_analysis_init(TonalityAnalysisState *analysis, opus_int32 Fs);
|
||||
|
||||
/** Reset a TonalityAnalysisState stuct.
|
||||
*
|
||||
|
||||
@@ -1,106 +1,109 @@
|
||||
/* The contents of this file was automatically generated by mlp_train.c
|
||||
It contains multi-layer perceptron (MLP) weights. */
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
#include "config.h"
|
||||
#endif
|
||||
|
||||
#include "mlp.h"
|
||||
|
||||
/* RMS error was 0.138320, seed was 1361535663 */
|
||||
/* RMS error was 0.280492, seed was 1480478173 */
|
||||
/* 0.005976 0.031821 (0.280494 0.280492) done */
|
||||
|
||||
static const float weights[422] = {
|
||||
static const float weights[450] = {
|
||||
|
||||
/* hidden layer */
|
||||
-0.0941125f, -0.302976f, -0.603555f, -0.19393f, -0.185983f,
|
||||
-0.601617f, -0.0465317f, -0.114563f, -0.103599f, -0.618938f,
|
||||
-0.317859f, -0.169949f, -0.0702885f, 0.148065f, 0.409524f,
|
||||
0.548432f, 0.367649f, -0.494393f, 0.764306f, -1.83957f,
|
||||
0.170849f, 12.786f, -1.08848f, -1.27284f, -16.2606f,
|
||||
24.1773f, -5.57454f, -0.17276f, -0.163388f, -0.224421f,
|
||||
-0.0948944f, -0.0728695f, -0.26557f, -0.100283f, -0.0515459f,
|
||||
-0.146142f, -0.120674f, -0.180655f, 0.12857f, 0.442138f,
|
||||
-0.493735f, 0.167767f, 0.206699f, -0.197567f, 0.417999f,
|
||||
1.50364f, -0.773341f, -10.0401f, 0.401872f, 2.97966f,
|
||||
15.2165f, -1.88905f, -1.19254f, 0.0285397f, -0.00405139f,
|
||||
0.0707565f, 0.00825699f, -0.0927269f, -0.010393f, -0.00428882f,
|
||||
-0.00489743f, -0.0709731f, -0.00255992f, 0.0395619f, 0.226424f,
|
||||
0.0325231f, 0.162175f, -0.100118f, 0.485789f, 0.12697f,
|
||||
0.285937f, 0.0155637f, 0.10546f, 3.05558f, 1.15059f,
|
||||
-1.00904f, -1.83088f, 3.31766f, -3.42516f, -0.119135f,
|
||||
-0.0405654f, 0.00690068f, 0.0179877f, -0.0382487f, 0.00597941f,
|
||||
-0.0183611f, 0.00190395f, -0.144322f, -0.0435671f, 0.000990594f,
|
||||
0.221087f, 0.142405f, 0.484066f, 0.404395f, 0.511955f,
|
||||
-0.237255f, 0.241742f, 0.35045f, -0.699428f, 10.3993f,
|
||||
2.6507f, -2.43459f, -4.18838f, 1.05928f, 1.71067f,
|
||||
0.00667811f, -0.0721335f, -0.0397346f, 0.0362704f, -0.11496f,
|
||||
-0.0235776f, 0.0082161f, -0.0141741f, -0.0329699f, -0.0354253f,
|
||||
0.00277404f, -0.290654f, -1.14767f, -0.319157f, -0.686544f,
|
||||
0.36897f, 0.478899f, 0.182579f, -0.411069f, 0.881104f,
|
||||
-4.60683f, 1.4697f, 0.335845f, -1.81905f, -30.1699f,
|
||||
5.55225f, 0.0019508f, -0.123576f, -0.0727332f, -0.0641597f,
|
||||
-0.0534458f, -0.108166f, -0.0937368f, -0.0697883f, -0.0275475f,
|
||||
-0.192309f, -0.110074f, 0.285375f, -0.405597f, 0.0926724f,
|
||||
-0.287881f, -0.851193f, -0.099493f, -0.233764f, -1.2852f,
|
||||
1.13611f, 3.12168f, -0.0699f, -1.86216f, 2.65292f,
|
||||
-7.31036f, 2.44776f, -0.00111802f, -0.0632786f, -0.0376296f,
|
||||
-0.149851f, 0.142963f, 0.184368f, 0.123433f, 0.0756158f,
|
||||
0.117312f, 0.0933395f, 0.0692163f, 0.0842592f, 0.0704683f,
|
||||
0.0589963f, 0.0942205f, -0.448862f, 0.0262677f, 0.270352f,
|
||||
-0.262317f, 0.172586f, 2.00227f, -0.159216f, 0.038422f,
|
||||
10.2073f, 4.15536f, -2.3407f, -0.0550265f, 0.00964792f,
|
||||
-0.141336f, 0.0274501f, 0.0343921f, -0.0487428f, 0.0950172f,
|
||||
-0.00775017f, -0.0372492f, -0.00548121f, -0.0663695f, 0.0960506f,
|
||||
-0.200008f, -0.0412827f, 0.58728f, 0.0515787f, 0.337254f,
|
||||
0.855024f, 0.668371f, -0.114904f, -3.62962f, -0.467477f,
|
||||
-0.215472f, 2.61537f, 0.406117f, -1.36373f, 0.0425394f,
|
||||
0.12208f, 0.0934502f, 0.123055f, 0.0340935f, -0.142466f,
|
||||
0.035037f, -0.0490666f, 0.0733208f, 0.0576672f, 0.123984f,
|
||||
-0.0517194f, -0.253018f, 0.590565f, 0.145849f, 0.315185f,
|
||||
0.221534f, -0.149081f, 0.216161f, -0.349575f, 24.5664f,
|
||||
-0.994196f, 0.614289f, -18.7905f, -2.83277f, -0.716801f,
|
||||
-0.347201f, 0.479515f, -0.246027f, 0.0758683f, 0.137293f,
|
||||
-0.17781f, 0.118751f, -0.00108329f, -0.237334f, 0.355732f,
|
||||
-0.12991f, -0.0547627f, -0.318576f, -0.325524f, 0.180494f,
|
||||
-0.0625604f, 0.141219f, 0.344064f, 0.37658f, -0.591772f,
|
||||
5.8427f, -0.38075f, 0.221894f, -1.41934f, -1.87943e+06f,
|
||||
1.34114f, 0.0283355f, -0.0447856f, -0.0211466f, -0.0256927f,
|
||||
0.0139618f, 0.0207934f, -0.0107666f, 0.0110969f, 0.0586069f,
|
||||
-0.0253545f, -0.0328433f, 0.11872f, -0.216943f, 0.145748f,
|
||||
0.119808f, -0.0915211f, -0.120647f, -0.0787719f, -0.143644f,
|
||||
-0.595116f, -1.152f, -1.25335f, -1.17092f, 4.34023f,
|
||||
-975268.f, -1.37033f, -0.0401123f, 0.210602f, -0.136656f,
|
||||
0.135962f, -0.0523293f, 0.0444604f, 0.0143928f, 0.00412666f,
|
||||
-0.0193003f, 0.218452f, -0.110204f, -2.02563f, 0.918238f,
|
||||
-2.45362f, 1.19542f, -0.061362f, -1.92243f, 0.308111f,
|
||||
0.49764f, 0.912356f, 0.209272f, -2.34525f, 2.19326f,
|
||||
-6.47121f, 1.69771f, -0.725123f, 0.0118929f, 0.0377944f,
|
||||
0.0554003f, 0.0226452f, -0.0704421f, -0.0300309f, 0.0122978f,
|
||||
-0.0041782f, -0.0686612f, 0.0313115f, 0.039111f, 0.364111f,
|
||||
-0.0945548f, 0.0229876f, -0.17414f, 0.329795f, 0.114714f,
|
||||
0.30022f, 0.106997f, 0.132355f, 5.79932f, 0.908058f,
|
||||
-0.905324f, -3.3561f, 0.190647f, 0.184211f, -0.673648f,
|
||||
0.231807f, -0.0586222f, 0.230752f, -0.438277f, 0.245857f,
|
||||
-0.17215f, 0.0876383f, -0.720512f, 0.162515f, 0.0170571f,
|
||||
0.101781f, 0.388477f, 1.32931f, 1.08548f, -0.936301f,
|
||||
-2.36958f, -6.71988f, -3.44376f, 2.13818f, 14.2318f,
|
||||
4.91459f, -3.09052f, -9.69191f, -0.768234f, 1.79604f,
|
||||
0.0549653f, 0.163399f, 0.0797025f, 0.0343933f, -0.0555876f,
|
||||
-0.00505673f, 0.0187258f, 0.0326628f, 0.0231486f, 0.15573f,
|
||||
0.0476223f, -0.254824f, 1.60155f, -0.801221f, 2.55496f,
|
||||
0.737629f, -1.36249f, -0.695463f, -2.44301f, -1.73188f,
|
||||
3.95279f, 1.89068f, 0.486087f, -11.3343f, 3.9416e+06f,
|
||||
|
||||
-0.514624f, 0.0234227f, -0.14329f, -0.0878216f, -0.00187827f,
|
||||
-0.0257443f, 0.108524f, 0.00333881f, 0.00585017f, -0.0246132f,
|
||||
0.142723f, -0.00436494f, 0.0101354f, -0.11124f, -0.0809367f,
|
||||
-0.0750772f, 0.0295524f, 0.00823944f, 0.150392f, 0.0320876f,
|
||||
-0.0710564f, -1.43818f, 0.652076f, 0.0650744f, -1.54821f,
|
||||
0.168949f, -1.92724f, 0.0517976f, -0.0670737f, -0.0690121f,
|
||||
0.00247528f, -0.0522024f, 0.0631368f, 0.0532776f, 0.047751f,
|
||||
-0.011715f, 0.142374f, -0.0290885f, -0.279263f, -0.433499f,
|
||||
-0.0795174f, -0.380458f, -0.051263f, 0.218537f, -0.322478f,
|
||||
1.06667f, -0.104607f, -4.70108f, 0.312037f, 0.277397f,
|
||||
-2.71859f, 1.70037f, -0.141845f, 0.0115618f, 0.0629883f,
|
||||
0.0403871f, 0.0139428f, -0.00430733f, -0.0429038f, -0.0590318f,
|
||||
-0.0501526f, -0.0284802f, -0.0415686f, -0.0438999f, 0.0822666f,
|
||||
0.197194f, 0.0363275f, -0.0584307f, 0.0752364f, -0.0799796f,
|
||||
-0.146275f, 0.161661f, -0.184585f, 0.145568f, 0.442823f,
|
||||
1.61221f, 1.11162f, 2.62177f, -2.482f, -0.112599f,
|
||||
-0.110366f, -0.140794f, -0.181694f, 0.0648674f, 0.0842248f,
|
||||
0.0933993f, 0.150122f, 0.129171f, 0.176848f, 0.141758f,
|
||||
-0.271822f, 0.235113f, 0.0668579f, -0.433957f, 0.113633f,
|
||||
-0.169348f, -1.40091f, 0.62861f, -0.134236f, 0.402173f,
|
||||
1.86373f, 1.53998f, -4.32084f, 0.735343f, 0.800214f,
|
||||
-0.00968415f, 0.0425904f, 0.0196811f, -0.018426f, -0.000343953f,
|
||||
-0.00416389f, 0.00111558f, 0.0173069f, -0.00998596f, -0.025898f,
|
||||
0.00123764f, -0.00520373f, -0.0565033f, 0.0637394f, 0.0051213f,
|
||||
0.0221361f, 0.00819962f, -0.0467061f, -0.0548258f, -0.00314063f,
|
||||
-1.18332f, 1.88091f, -0.41148f, -2.95727f, -0.521449f,
|
||||
-0.271641f, 0.124946f, -0.0532936f, 0.101515f, 0.000208564f,
|
||||
-0.0488748f, 0.0642388f, -0.0383848f, 0.0135046f, -0.0413592f,
|
||||
-0.0326402f, -0.0137421f, -0.0225219f, -0.0917294f, -0.277759f,
|
||||
-0.185418f, 0.0471128f, -0.125879f, 0.262467f, -0.212794f,
|
||||
-0.112931f, -1.99885f, -0.404787f, 0.224402f, 0.637962f,
|
||||
-0.27808f, -0.0723953f, -0.0537655f, -0.0336359f, -0.0906601f,
|
||||
-0.0641309f, -0.0713542f, 0.0524317f, 0.00608819f, 0.0754101f,
|
||||
-0.0488401f, -0.00671865f, 0.0418239f, 0.0536284f, -0.132639f,
|
||||
0.0267648f, -0.248432f, -0.0104153f, 0.035544f, -0.212753f,
|
||||
-0.302895f, -0.0357854f, 0.376838f, 0.597025f, -0.664647f,
|
||||
0.268422f, -0.376772f, -1.05472f, 0.0144178f, 0.179122f,
|
||||
0.0360155f, 0.220262f, -0.0056381f, 0.0317197f, 0.0621066f,
|
||||
-0.00779298f, 0.00789378f, 0.00350605f, 0.0104809f, 0.0362871f,
|
||||
-0.157708f, -0.0659779f, -0.0926278f, 0.00770791f, 0.0631621f,
|
||||
0.0817343f, -0.424295f, -0.0437727f, -0.24251f, 0.711217f,
|
||||
-0.736455f, -2.194f, -0.107612f, -0.175156f, -0.0366573f,
|
||||
-0.0123156f, -0.0628516f, -0.0218977f, -0.00693699f, 0.00695185f,
|
||||
0.00507362f, 0.00359334f, 0.0052661f, 0.035561f, 0.0382701f,
|
||||
0.0342179f, -0.00790271f, -0.0170925f, 0.047029f, 0.0197362f,
|
||||
-0.0153435f, 0.0644152f, -0.36862f, -0.0674876f, -2.82672f,
|
||||
1.34122f, -0.0788029f, -3.47792f, 0.507246f, -0.816378f,
|
||||
-0.0142383f, -0.127349f, -0.106926f, -0.0359524f, 0.105045f,
|
||||
0.291554f, 0.195413f, 0.0866214f, -0.066577f, -0.102188f,
|
||||
0.0979466f, -0.12982f, 0.400181f, -0.409336f, -0.0593326f,
|
||||
-0.0656203f, -0.204474f, 0.179802f, 0.000509084f, 0.0995954f,
|
||||
-2.377f, -0.686359f, 0.934861f, 1.10261f, 1.3901f,
|
||||
-4.33616f, -0.00264017f, 0.00713045f, 0.106264f, 0.143726f,
|
||||
-0.0685305f, -0.054656f, -0.0176725f, -0.0772669f, -0.0264526f,
|
||||
-0.0103824f, -0.0269872f, -0.00687f, 0.225804f, 0.407751f,
|
||||
-0.0612611f, -0.0576863f, -0.180131f, -0.222772f, -0.461742f,
|
||||
0.335236f, 1.03399f, 4.24112f, -0.345796f, -0.594549f,
|
||||
-76.1407f, -0.265276f, 0.0507719f, 0.0643044f, 0.0384832f,
|
||||
0.0424459f, -0.0387817f, -0.0235996f, -0.0740556f, -0.0270029f,
|
||||
0.00882177f, -0.0552371f, -0.00485851f, 0.314295f, 0.360431f,
|
||||
-0.0787085f, 0.110355f, -0.415958f, -0.385088f, -0.272224f,
|
||||
-1.55108f, -0.141848f, 0.448877f, -0.563447f, -2.31403f,
|
||||
-0.120077f, -1.49918f, -0.817726f, -0.0495854f, -0.0230782f,
|
||||
-0.0224014f, 0.117076f, 0.0393216f, 0.051997f, 0.0330763f,
|
||||
-0.110796f, 0.0211117f, -0.0197258f, 0.0187461f, 0.0125183f,
|
||||
0.14876f, 0.0920565f, -0.342475f, 0.135272f, -0.168155f,
|
||||
-0.033423f, -0.0604611f, -0.128835f, 0.664947f, -0.144997f,
|
||||
2.27649f, 1.28663f, 0.841217f, -2.42807f, 0.0230471f,
|
||||
0.226709f, -0.0374803f, 0.155436f, 0.0400342f, -0.184686f,
|
||||
0.128488f, -0.0939518f, -0.0578559f, 0.0265967f, -0.0999322f,
|
||||
-0.0322768f, -0.322994f, -0.189371f, -0.738069f, -0.0754914f,
|
||||
0.214717f, -0.093728f, -0.695741f, 0.0899298f, -2.06188f,
|
||||
-0.273719f, -0.896977f, 0.130553f, 0.134638f, 1.29355f,
|
||||
0.00520749f, -0.0324224f, 0.00530451f, 0.0192385f, 0.00328708f,
|
||||
0.0250838f, 0.0053365f, -0.0177321f, 0.00618789f, 0.00525364f,
|
||||
0.00104596f, -0.0360459f, 0.0402403f, -0.0406351f, 0.0136883f,
|
||||
0.0880722f, -0.0197449f, 0.089938f, 0.0100456f, -0.0475638f,
|
||||
-0.73267f, 0.037433f, -0.146551f, -0.230221f, -3.06489f,
|
||||
-1.40194f, 0.0198483f, 0.0397953f, -0.0190239f, 0.0470715f,
|
||||
-0.131363f, -0.191721f, -0.0176224f, -0.0480352f, -0.221799f,
|
||||
-0.26794f, -0.0292615f, 0.0612127f, -0.129877f, 0.00628332f,
|
||||
-0.085918f, 0.0175379f, 0.0541011f, -0.0810874f, -0.380809f,
|
||||
-0.222056f, -0.508859f, -0.473369f, 0.484958f, -2.28411f,
|
||||
0.0139516f,
|
||||
/* output layer */
|
||||
-0.381439f, 0.12115f, -0.906927f, 2.93878f, 1.6388f,
|
||||
0.882811f, 0.874344f, 1.21726f, -0.874545f, 0.321706f,
|
||||
0.785055f, 0.946558f, -0.575066f, -3.46553f, 0.884905f,
|
||||
0.0924047f, -9.90712f, 0.391338f, 0.160103f, -2.04954f,
|
||||
4.1455f, 0.0684029f, -0.144761f, -0.285282f, 0.379244f,
|
||||
-1.1584f, -0.0277241f, -9.85f, -4.82386f, 3.71333f,
|
||||
3.87308f, 3.52558f};
|
||||
3.90017f, 1.71789f, -1.43372f, -2.70839f, 1.77107f,
|
||||
5.48006f, 1.44661f, 2.01134f, -1.88383f, -3.64958f,
|
||||
-1.26351f, 0.779421f, 2.11357f, 3.10409f, 1.68846f,
|
||||
-4.46197f, -1.61455f, 3.59832f, 2.43531f, -1.26458f,
|
||||
0.417941f, 1.47437f, 2.16635f, -1.909f, -0.828869f,
|
||||
1.38805f, -2.67975f, -0.110044f, 1.95596f, 0.697931f,
|
||||
-0.313226f, -0.889315f, 0.283236f, 0.946102f, };
|
||||
|
||||
static const int topo[3] = {25, 15, 2};
|
||||
static const int topo[3] = {25, 16, 2};
|
||||
|
||||
const MLP net = {
|
||||
3,
|
||||
|
||||
@@ -107,7 +107,7 @@ OPUS_EXPORT void opus_pcm_soft_clip(float *_x, int N, int C, float *declip_mem)
|
||||
/* Slightly boost "a" by 2^-22. This is just enough to ensure -ffast-math
|
||||
does not cause output values larger than +/-1, but small enough not
|
||||
to matter even for 24-bit output. */
|
||||
a += a*2.4e-7;
|
||||
a += a*2.4e-7f;
|
||||
if (x[i*C]>0)
|
||||
a = -a;
|
||||
/* Apply soft clipping */
|
||||
|
||||
@@ -891,7 +891,7 @@ int opus_decoder_ctl(OpusDecoder *st, int request, ...)
|
||||
break;
|
||||
case OPUS_GET_LAST_PACKET_DURATION_REQUEST:
|
||||
{
|
||||
opus_uint32 *value = va_arg(ap, opus_uint32*);
|
||||
opus_int32 *value = va_arg(ap, opus_int32*);
|
||||
if (!value)
|
||||
{
|
||||
goto bad_arg;
|
||||
@@ -899,6 +899,26 @@ int opus_decoder_ctl(OpusDecoder *st, int request, ...)
|
||||
*value = st->last_packet_duration;
|
||||
}
|
||||
break;
|
||||
case OPUS_SET_PHASE_INVERSION_DISABLED_REQUEST:
|
||||
{
|
||||
opus_int32 value = va_arg(ap, opus_int32);
|
||||
if(value<0 || value>1)
|
||||
{
|
||||
goto bad_arg;
|
||||
}
|
||||
celt_decoder_ctl(celt_dec, OPUS_SET_PHASE_INVERSION_DISABLED(value));
|
||||
}
|
||||
break;
|
||||
case OPUS_GET_PHASE_INVERSION_DISABLED_REQUEST:
|
||||
{
|
||||
opus_int32 *value = va_arg(ap, opus_int32*);
|
||||
if (!value)
|
||||
{
|
||||
goto bad_arg;
|
||||
}
|
||||
celt_decoder_ctl(celt_dec, OPUS_GET_PHASE_INVERSION_DISABLED(value));
|
||||
}
|
||||
break;
|
||||
default:
|
||||
/*fprintf(stderr, "unknown opus_decoder_ctl() request: %d", request);*/
|
||||
ret = OPUS_UNIMPLEMENTED;
|
||||
|
||||
+761
-566
File diff suppressed because it is too large.
Load diff
@@ -237,7 +237,8 @@ static int opus_multistream_decode_native(
|
||||
for (s=0;s<st->layout.nb_streams;s++)
|
||||
{
|
||||
OpusDecoder *dec;
|
||||
int packet_offset, ret;
|
||||
opus_int32 packet_offset;
|
||||
int ret;
|
||||
|
||||
dec = (OpusDecoder*)ptr;
|
||||
ptr += (s < st->layout.nb_coupled_streams) ? align(coupled_size) : align(mono_size);
|
||||
@@ -425,6 +426,7 @@ int opus_multistream_decoder_ctl(OpusMSDecoder *st, int request, ...)
|
||||
case OPUS_GET_SAMPLE_RATE_REQUEST:
|
||||
case OPUS_GET_GAIN_REQUEST:
|
||||
case OPUS_GET_LAST_PACKET_DURATION_REQUEST:
|
||||
case OPUS_GET_PHASE_INVERSION_DISABLED_REQUEST:
|
||||
{
|
||||
OpusDecoder *dec;
|
||||
/* For int32* GET params, just query the first stream */
|
||||
@@ -499,6 +501,7 @@ int opus_multistream_decoder_ctl(OpusMSDecoder *st, int request, ...)
|
||||
}
|
||||
break;
|
||||
case OPUS_SET_GAIN_REQUEST:
|
||||
case OPUS_SET_PHASE_INVERSION_DISABLED_REQUEST:
|
||||
{
|
||||
int s;
|
||||
/* This works for int32 params */
|
||||
|
||||
@@ -87,7 +87,6 @@ struct OpusMSEncoder {
|
||||
int variable_duration;
|
||||
MappingType mapping_type;
|
||||
opus_int32 bitrate_bps;
|
||||
float subframe_mem[3];
|
||||
/* Encoder states go here */
|
||||
/* then opus_val32 window_mem[channels*120]; */
|
||||
/* then opus_val32 preemph_mem[channels]; */
|
||||
@@ -133,6 +132,29 @@ static opus_val32 *ms_get_window_mem(OpusMSEncoder *st)
|
||||
return (opus_val32*)(void*)ptr;
|
||||
}
|
||||
|
||||
#ifdef ENABLE_EXPERIMENTAL_AMBISONICS
|
||||
static int validate_ambisonics(int nb_channels, int *nb_streams, int *nb_coupled_streams)
|
||||
{
|
||||
int order_plus_one;
|
||||
int acn_channels;
|
||||
int nondiegetic_channels;
|
||||
|
||||
order_plus_one = isqrt32(nb_channels);
|
||||
acn_channels = order_plus_one * order_plus_one;
|
||||
nondiegetic_channels = nb_channels - acn_channels;
|
||||
|
||||
if (order_plus_one < 1 || order_plus_one > 15 ||
|
||||
(nondiegetic_channels != 0 && nondiegetic_channels != 2))
|
||||
return 0;
|
||||
|
||||
if (nb_streams)
|
||||
*nb_streams = acn_channels + (nondiegetic_channels != 0);
|
||||
if (nb_coupled_streams)
|
||||
*nb_coupled_streams = nondiegetic_channels != 0;
|
||||
return 1;
|
||||
}
|
||||
#endif
|
||||
|
||||
static int validate_encoder_layout(const ChannelLayout *layout)
|
||||
{
|
||||
int s;
|
||||
@@ -240,6 +262,7 @@ void surround_analysis(const CELTMode *celt_mode, const void *pcm, opus_val16 *b
|
||||
int pos[8] = {0};
|
||||
int upsample;
|
||||
int frame_size;
|
||||
int freq_size;
|
||||
opus_val16 channel_offset;
|
||||
opus_val32 bandE[21];
|
||||
opus_val16 maskLogE[3][21];
|
||||
@@ -250,6 +273,7 @@ void surround_analysis(const CELTMode *celt_mode, const void *pcm, opus_val16 *b
|
||||
|
||||
upsample = resampling_factor(rate);
|
||||
frame_size = len*upsample;
|
||||
freq_size = IMIN(960, frame_size);
|
||||
|
||||
/* LM = log2(frame_size / 120) */
|
||||
for (LM=0;LM<celt_mode->maxLM;LM++)
|
||||
@@ -258,7 +282,7 @@ void surround_analysis(const CELTMode *celt_mode, const void *pcm, opus_val16 *b
|
||||
|
||||
ALLOC(in, frame_size+overlap, opus_val32);
|
||||
ALLOC(x, len, opus_val16);
|
||||
ALLOC(freq, frame_size, opus_val32);
|
||||
ALLOC(freq, freq_size, opus_val32);
|
||||
|
||||
channel_pos(channels, pos);
|
||||
|
||||
@@ -268,6 +292,9 @@ void surround_analysis(const CELTMode *celt_mode, const void *pcm, opus_val16 *b
|
||||
|
||||
for (c=0;c<channels;c++)
|
||||
{
|
||||
int frame;
|
||||
int nb_frames = frame_size/freq_size;
|
||||
celt_assert(nb_frames*freq_size == frame_size);
|
||||
OPUS_COPY(in, mem+c*overlap, overlap);
|
||||
(*copy_channel_in)(x, 1, pcm, channels, c, len);
|
||||
celt_preemphasis(x, in+overlap, frame_size, 1, upsample, celt_mode->preemph, preemph_mem+c, 0);
|
||||
@@ -277,25 +304,33 @@ void surround_analysis(const CELTMode *celt_mode, const void *pcm, opus_val16 *b
|
||||
sum = celt_inner_prod(in, in, frame_size+overlap, 0);
|
||||
/* This should filter out both NaNs and ridiculous signals that could
|
||||
cause NaNs further down. */
|
||||
if (!(sum < 1e9f) || celt_isnan(sum))
|
||||
if (!(sum < 1e18f) || celt_isnan(sum))
|
||||
{
|
||||
OPUS_CLEAR(in, frame_size+overlap);
|
||||
preemph_mem[c] = 0;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
clt_mdct_forward(&celt_mode->mdct, in, freq, celt_mode->window,
|
||||
overlap, celt_mode->maxLM-LM, 1, arch);
|
||||
if (upsample != 1)
|
||||
OPUS_CLEAR(bandE, 21);
|
||||
for (frame=0;frame<nb_frames;frame++)
|
||||
{
|
||||
int bound = len;
|
||||
for (i=0;i<bound;i++)
|
||||
freq[i] *= upsample;
|
||||
for (;i<frame_size;i++)
|
||||
freq[i] = 0;
|
||||
}
|
||||
opus_val32 tmpE[21];
|
||||
clt_mdct_forward(&celt_mode->mdct, in+960*frame, freq, celt_mode->window,
|
||||
overlap, celt_mode->maxLM-LM, 1, arch);
|
||||
if (upsample != 1)
|
||||
{
|
||||
int bound = freq_size/upsample;
|
||||
for (i=0;i<bound;i++)
|
||||
freq[i] *= upsample;
|
||||
for (;i<freq_size;i++)
|
||||
freq[i] = 0;
|
||||
}
|
||||
|
||||
compute_band_energies(celt_mode, freq, bandE, 21, 1, LM);
|
||||
compute_band_energies(celt_mode, freq, tmpE, 21, 1, LM, arch);
|
||||
/* If we have multiple frames, take the max energy. */
|
||||
for (i=0;i<21;i++)
|
||||
bandE[i] = MAX32(bandE[i], tmpE[i]);
|
||||
}
|
||||
amp2Log2(celt_mode, 21, 21, bandE, bandLogE+21*c, 1);
|
||||
/* Apply spreading function with -6 dB/band going up and -12 dB/band going down. */
|
||||
for (i=1;i<21;i++)
|
||||
@@ -411,8 +446,8 @@ opus_int32 opus_multistream_surround_encoder_get_size(int channels, int mapping_
|
||||
#ifdef ENABLE_EXPERIMENTAL_AMBISONICS
|
||||
} else if (mapping_family==254)
|
||||
{
|
||||
nb_streams=channels;
|
||||
nb_coupled_streams=0;
|
||||
if (!validate_ambisonics(channels, &nb_streams, &nb_coupled_streams))
|
||||
return 0;
|
||||
#endif
|
||||
} else
|
||||
return 0;
|
||||
@@ -448,7 +483,6 @@ static int opus_multistream_encoder_init_impl(
|
||||
st->layout.nb_channels = channels;
|
||||
st->layout.nb_streams = streams;
|
||||
st->layout.nb_coupled_streams = coupled_streams;
|
||||
st->subframe_mem[0]=st->subframe_mem[1]=st->subframe_mem[2]=0;
|
||||
if (mapping_type != MAPPING_TYPE_SURROUND)
|
||||
st->lfe_stream = -1;
|
||||
st->bitrate_bps = OPUS_AUTO;
|
||||
@@ -456,8 +490,16 @@ static int opus_multistream_encoder_init_impl(
|
||||
st->variable_duration = OPUS_FRAMESIZE_ARG;
|
||||
for (i=0;i<st->layout.nb_channels;i++)
|
||||
st->layout.mapping[i] = mapping[i];
|
||||
if (!validate_layout(&st->layout) || !validate_encoder_layout(&st->layout))
|
||||
if (!validate_layout(&st->layout))
|
||||
return OPUS_BAD_ARG;
|
||||
if (mapping_type == MAPPING_TYPE_SURROUND &&
|
||||
!validate_encoder_layout(&st->layout))
|
||||
return OPUS_BAD_ARG;
|
||||
#ifdef ENABLE_EXPERIMENTAL_AMBISONICS
|
||||
if (mapping_type == MAPPING_TYPE_AMBISONICS &&
|
||||
!validate_ambisonics(st->layout.nb_channels, NULL, NULL))
|
||||
return OPUS_BAD_ARG;
|
||||
#endif
|
||||
ptr = (char*)st + align(sizeof(OpusMSEncoder));
|
||||
coupled_size = opus_encoder_get_size(2);
|
||||
mono_size = opus_encoder_get_size(1);
|
||||
@@ -553,10 +595,12 @@ int opus_multistream_surround_encoder_init(
|
||||
} else if (mapping_family==254)
|
||||
{
|
||||
int i;
|
||||
*streams=channels;
|
||||
*coupled_streams=0;
|
||||
for(i=0;i<channels;i++)
|
||||
mapping[i] = i;
|
||||
if (!validate_ambisonics(channels, streams, coupled_streams))
|
||||
return OPUS_BAD_ARG;
|
||||
for(i = 0; i < (*streams - *coupled_streams); i++)
|
||||
mapping[i] = i + (*coupled_streams * 2);
|
||||
for(i = 0; i < *coupled_streams * 2; i++)
|
||||
mapping[i + (*streams - *coupled_streams)] = i;
|
||||
#endif
|
||||
} else
|
||||
return OPUS_UNIMPLEMENTED;
|
||||
@@ -672,58 +716,59 @@ static void surround_rate_allocation(
|
||||
int lfe_offset;
|
||||
int coupled_ratio; /* Q8 */
|
||||
int lfe_ratio; /* Q8 */
|
||||
int nb_lfe;
|
||||
int nb_uncoupled;
|
||||
int nb_coupled;
|
||||
int nb_normal;
|
||||
opus_int32 channel_offset;
|
||||
opus_int32 bitrate;
|
||||
int total;
|
||||
|
||||
if (st->bitrate_bps > st->layout.nb_channels*40000)
|
||||
stream_offset = 20000;
|
||||
else
|
||||
stream_offset = st->bitrate_bps/st->layout.nb_channels/2;
|
||||
stream_offset += 60*(Fs/frame_size-50);
|
||||
/* We start by giving each stream (coupled or uncoupled) the same bitrate.
|
||||
nb_lfe = (st->lfe_stream!=-1);
|
||||
nb_coupled = st->layout.nb_coupled_streams;
|
||||
nb_uncoupled = st->layout.nb_streams-nb_coupled-nb_lfe;
|
||||
nb_normal = 2*nb_coupled + nb_uncoupled;
|
||||
|
||||
/* Give each non-LFE channel enough bits per channel for coding band energy. */
|
||||
channel_offset = 40*IMAX(50, Fs/frame_size);
|
||||
|
||||
if (st->bitrate_bps==OPUS_AUTO)
|
||||
{
|
||||
bitrate = nb_normal*(channel_offset + Fs + 10000) + 8000*nb_lfe;
|
||||
} else if (st->bitrate_bps==OPUS_BITRATE_MAX)
|
||||
{
|
||||
bitrate = nb_normal*300000 + nb_lfe*128000;
|
||||
} else {
|
||||
bitrate = st->bitrate_bps;
|
||||
}
|
||||
|
||||
/* Give LFE some basic stream_channel allocation but never exceed 1/20 of the
|
||||
total rate for the non-energy part to avoid problems at really low rate. */
|
||||
lfe_offset = IMIN(bitrate/20, 3000) + 15*IMAX(50, Fs/frame_size);
|
||||
|
||||
/* We give each stream (coupled or uncoupled) a starting bitrate.
|
||||
This models the main saving of coupled channels over uncoupled. */
|
||||
/* The LFE stream is an exception to the above and gets fewer bits. */
|
||||
lfe_offset = 3500 + 60*(Fs/frame_size-50);
|
||||
/* Coupled streams get twice the mono rate after the first 20 kb/s. */
|
||||
stream_offset = (bitrate - channel_offset*nb_normal - lfe_offset*nb_lfe)/nb_normal/2;
|
||||
stream_offset = IMAX(0, IMIN(20000, stream_offset));
|
||||
|
||||
/* Coupled streams get twice the mono rate after the offset is allocated. */
|
||||
coupled_ratio = 512;
|
||||
/* Should depend on the bitrate, for now we assume LFE gets 1/8 the bits of mono */
|
||||
lfe_ratio = 32;
|
||||
|
||||
/* Compute bitrate allocation between streams */
|
||||
if (st->bitrate_bps==OPUS_AUTO)
|
||||
{
|
||||
channel_rate = Fs+60*Fs/frame_size;
|
||||
} else if (st->bitrate_bps==OPUS_BITRATE_MAX)
|
||||
{
|
||||
channel_rate = 300000;
|
||||
} else {
|
||||
int nb_lfe;
|
||||
int nb_uncoupled;
|
||||
int nb_coupled;
|
||||
int total;
|
||||
nb_lfe = (st->lfe_stream!=-1);
|
||||
nb_coupled = st->layout.nb_coupled_streams;
|
||||
nb_uncoupled = st->layout.nb_streams-nb_coupled-nb_lfe;
|
||||
total = (nb_uncoupled<<8) /* mono */
|
||||
+ coupled_ratio*nb_coupled /* stereo */
|
||||
+ nb_lfe*lfe_ratio;
|
||||
channel_rate = 256*(st->bitrate_bps-lfe_offset*nb_lfe-stream_offset*(nb_coupled+nb_uncoupled))/total;
|
||||
}
|
||||
#ifndef FIXED_POINT
|
||||
if (st->variable_duration==OPUS_FRAMESIZE_VARIABLE && frame_size != Fs/50)
|
||||
{
|
||||
opus_int32 bonus;
|
||||
bonus = 60*(Fs/frame_size-50);
|
||||
channel_rate += bonus;
|
||||
}
|
||||
#endif
|
||||
total = (nb_uncoupled<<8) /* mono */
|
||||
+ coupled_ratio*nb_coupled /* stereo */
|
||||
+ nb_lfe*lfe_ratio;
|
||||
channel_rate = 256*(opus_int64)(bitrate - lfe_offset*nb_lfe - stream_offset*(nb_coupled+nb_uncoupled) - channel_offset*nb_normal)/total;
|
||||
|
||||
for (i=0;i<st->layout.nb_streams;i++)
|
||||
{
|
||||
if (i<st->layout.nb_coupled_streams)
|
||||
rate[i] = stream_offset+(channel_rate*coupled_ratio>>8);
|
||||
rate[i] = 2*channel_offset + IMAX(0, stream_offset+(channel_rate*coupled_ratio>>8));
|
||||
else if (i!=st->lfe_stream)
|
||||
rate[i] = stream_offset+channel_rate;
|
||||
rate[i] = channel_offset + IMAX(0, stream_offset + channel_rate);
|
||||
else
|
||||
rate[i] = lfe_offset+(channel_rate*lfe_ratio>>8);
|
||||
rate[i] = IMAX(0, lfe_offset+(channel_rate*lfe_ratio>>8));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -736,47 +781,72 @@ static void ambisonics_rate_allocation(
|
||||
)
|
||||
{
|
||||
int i;
|
||||
int non_mono_rate;
|
||||
int total_rate;
|
||||
int directional_rate;
|
||||
int nondirectional_rate;
|
||||
int leftover_bits;
|
||||
|
||||
/* The mono channel gets (rate_ratio_num / rate_ratio_den) times as many bits
|
||||
* as all other channels */
|
||||
/* Each nondirectional channel gets (rate_ratio_num / rate_ratio_den) times
|
||||
* as many bits as all other ambisonics channels.
|
||||
*/
|
||||
const int rate_ratio_num = 4;
|
||||
const int rate_ratio_den = 3;
|
||||
const int num_channels = st->layout.nb_streams;
|
||||
const int nb_channels = st->layout.nb_streams + st->layout.nb_coupled_streams;
|
||||
const int nb_nondirectional_channels = st->layout.nb_coupled_streams * 2 + 1;
|
||||
const int nb_directional_channels = st->layout.nb_streams - 1;
|
||||
|
||||
if (st->bitrate_bps==OPUS_AUTO)
|
||||
{
|
||||
total_rate = num_channels * (20000 + st->layout.nb_streams*(Fs+60*Fs/frame_size));
|
||||
total_rate = (st->layout.nb_coupled_streams + st->layout.nb_streams) *
|
||||
(Fs+60*Fs/frame_size) + st->layout.nb_streams * 15000;
|
||||
} else if (st->bitrate_bps==OPUS_BITRATE_MAX)
|
||||
{
|
||||
total_rate = num_channels * 320000;
|
||||
} else {
|
||||
total_rate = nb_channels * 320000;
|
||||
} else
|
||||
{
|
||||
total_rate = st->bitrate_bps;
|
||||
}
|
||||
|
||||
/* Let y be the non-mono rate and let p, q be integers such that the mono
|
||||
* channel rate is (p/q) * y.
|
||||
/* Let y be the directional rate, m be the num of nondirectional channels
|
||||
* m = (s + 1)
|
||||
* and let p, q be integers such that the nondirectional rate is
|
||||
* m_rate = (p / q) * y
|
||||
* Also let T be the total bitrate to allocate. Then
|
||||
* (n - 1) y + (p/q) y = T
|
||||
* y = (T q) / (qn - q + p)
|
||||
* T = (n - m) * y + m * m_rate
|
||||
* Solving for y,
|
||||
* y = (q * T) / (m * (p - q) + n * q)
|
||||
*/
|
||||
non_mono_rate =
|
||||
total_rate * rate_ratio_den
|
||||
/ (rate_ratio_den*num_channels + rate_ratio_num - rate_ratio_den);
|
||||
directional_rate =
|
||||
total_rate * rate_ratio_den
|
||||
/ (nb_nondirectional_channels * (rate_ratio_num - rate_ratio_den)
|
||||
+ nb_channels * rate_ratio_den);
|
||||
|
||||
#ifndef FIXED_POINT
|
||||
if (st->variable_duration==OPUS_FRAMESIZE_VARIABLE && frame_size != Fs/50)
|
||||
{
|
||||
opus_int32 bonus = 60*(Fs/frame_size-50);
|
||||
non_mono_rate += bonus;
|
||||
}
|
||||
#endif
|
||||
/* Calculate the nondirectional rate.
|
||||
* m_rate = y * (p / q)
|
||||
*/
|
||||
nondirectional_rate = directional_rate * rate_ratio_num / rate_ratio_den;
|
||||
|
||||
rate[0] = total_rate - (num_channels - 1) * non_mono_rate;
|
||||
for (i=1;i<st->layout.nb_streams;i++)
|
||||
/* Calculate the leftover from truncation error.
|
||||
* leftover = T - y * (n - m) - m_rate * m
|
||||
* Place leftover bits in omnidirectional channel.
|
||||
*/
|
||||
leftover_bits = total_rate
|
||||
- directional_rate * nb_directional_channels
|
||||
- nondirectional_rate * nb_nondirectional_channels;
|
||||
|
||||
/* Calculate rates for each channel */
|
||||
for (i = 0; i < st->layout.nb_streams; i++)
|
||||
{
|
||||
rate[i] = non_mono_rate;
|
||||
if (i < st->layout.nb_coupled_streams)
|
||||
{
|
||||
rate[i] = nondirectional_rate * 2;
|
||||
} else if (i == st->layout.nb_coupled_streams)
|
||||
{
|
||||
rate[i] = nondirectional_rate + leftover_bits;
|
||||
} else
|
||||
{
|
||||
rate[i] = directional_rate;
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif /* ENABLE_EXPERIMENTAL_AMBISONICS */
|
||||
@@ -812,8 +882,8 @@ static opus_int32 rate_allocation(
|
||||
return rate_sum;
|
||||
}
|
||||
|
||||
/* Max size in case the encoder decides to return three frames */
|
||||
#define MS_FRAME_TMP (3*1275+7)
|
||||
/* Max size in case the encoder decides to return six frames (6 x 20 ms = 120 ms) */
|
||||
#define MS_FRAME_TMP (6*1275+12)
|
||||
static int opus_multistream_encode_native
|
||||
(
|
||||
OpusMSEncoder *st,
|
||||
@@ -859,32 +929,8 @@ static int opus_multistream_encode_native
|
||||
opus_encoder_ctl((OpusEncoder*)ptr, OPUS_GET_VBR(&vbr));
|
||||
opus_encoder_ctl((OpusEncoder*)ptr, CELT_GET_MODE(&celt_mode));
|
||||
|
||||
{
|
||||
opus_int32 delay_compensation;
|
||||
int channels;
|
||||
|
||||
channels = st->layout.nb_streams + st->layout.nb_coupled_streams;
|
||||
opus_encoder_ctl((OpusEncoder*)ptr, OPUS_GET_LOOKAHEAD(&delay_compensation));
|
||||
delay_compensation -= Fs/400;
|
||||
frame_size = compute_frame_size(pcm, analysis_frame_size,
|
||||
st->variable_duration, channels, Fs, st->bitrate_bps,
|
||||
delay_compensation, downmix
|
||||
#ifndef DISABLE_FLOAT_API
|
||||
, st->subframe_mem
|
||||
#endif
|
||||
);
|
||||
}
|
||||
|
||||
if (400*frame_size < Fs)
|
||||
{
|
||||
RESTORE_STACK;
|
||||
return OPUS_BAD_ARG;
|
||||
}
|
||||
/* Validate frame_size before using it to allocate stack space.
|
||||
This mirrors the checks in opus_encode[_float](). */
|
||||
if (400*frame_size != Fs && 200*frame_size != Fs &&
|
||||
100*frame_size != Fs && 50*frame_size != Fs &&
|
||||
25*frame_size != Fs && 50*frame_size != 3*Fs)
|
||||
frame_size = frame_size_select(analysis_frame_size, st->variable_duration, Fs);
|
||||
if (frame_size <= 0)
|
||||
{
|
||||
RESTORE_STACK;
|
||||
return OPUS_BAD_ARG;
|
||||
@@ -892,6 +938,9 @@ static int opus_multistream_encode_native
|
||||
|
||||
/* Smallest packet the encoder can produce. */
|
||||
smallest_packet = st->layout.nb_streams*2-1;
|
||||
/* 100 ms needs an extra byte per stream for the ToC. */
|
||||
if (Fs/frame_size == 10)
|
||||
smallest_packet += st->layout.nb_streams;
|
||||
if (max_data_bytes < smallest_packet)
|
||||
{
|
||||
RESTORE_STACK;
|
||||
@@ -1013,6 +1062,9 @@ static int opus_multistream_encode_native
|
||||
curr_max = max_data_bytes - tot_size;
|
||||
/* Reserve one byte for the last stream and two for the others */
|
||||
curr_max -= IMAX(0,2*(st->layout.nb_streams-s-1)-1);
|
||||
/* For 100 ms, reserve an extra byte per stream for the ToC */
|
||||
if (Fs/frame_size == 10)
|
||||
curr_max -= st->layout.nb_streams-s-1;
|
||||
curr_max = IMIN(curr_max,MS_FRAME_TMP);
|
||||
/* Repacketizer will add one or two bytes for self-delimited frames */
|
||||
if (s != st->layout.nb_streams-1) curr_max -= curr_max>253 ? 2 : 1;
|
||||
@@ -1161,9 +1213,11 @@ int opus_multistream_encoder_ctl(OpusMSEncoder *st, int request, ...)
|
||||
case OPUS_SET_BITRATE_REQUEST:
|
||||
{
|
||||
opus_int32 value = va_arg(ap, opus_int32);
|
||||
if (value<0 && value!=OPUS_AUTO && value!=OPUS_BITRATE_MAX)
|
||||
if (value != OPUS_AUTO && value != OPUS_BITRATE_MAX)
|
||||
{
|
||||
goto bad_arg;
|
||||
if (value <= 0)
|
||||
goto bad_arg;
|
||||
value = IMIN(300000*st->layout.nb_channels, IMAX(500*st->layout.nb_channels, value));
|
||||
}
|
||||
st->bitrate_bps = value;
|
||||
}
|
||||
@@ -1206,6 +1260,7 @@ int opus_multistream_encoder_ctl(OpusMSEncoder *st, int request, ...)
|
||||
case OPUS_GET_INBAND_FEC_REQUEST:
|
||||
case OPUS_GET_FORCE_CHANNELS_REQUEST:
|
||||
case OPUS_GET_PREDICTION_DISABLED_REQUEST:
|
||||
case OPUS_GET_PHASE_INVERSION_DISABLED_REQUEST:
|
||||
{
|
||||
OpusEncoder *enc;
|
||||
/* For int32* GET params, just query the first stream */
|
||||
@@ -1252,6 +1307,7 @@ int opus_multistream_encoder_ctl(OpusMSEncoder *st, int request, ...)
|
||||
case OPUS_SET_FORCE_MODE_REQUEST:
|
||||
case OPUS_SET_FORCE_CHANNELS_REQUEST:
|
||||
case OPUS_SET_PREDICTION_DISABLED_REQUEST:
|
||||
case OPUS_SET_PHASE_INVERSION_DISABLED_REQUEST:
|
||||
{
|
||||
int s;
|
||||
/* This works for int32 params */
|
||||
@@ -1313,7 +1369,6 @@ int opus_multistream_encoder_ctl(OpusMSEncoder *st, int request, ...)
|
||||
case OPUS_RESET_STATE:
|
||||
{
|
||||
int s;
|
||||
st->subframe_mem[0] = st->subframe_mem[1] = st->subframe_mem[2] = 0;
|
||||
if (st->mapping_type == MAPPING_TYPE_SURROUND)
|
||||
{
|
||||
OPUS_CLEAR(ms_get_preemph_mem(st), st->layout.nb_channels);
|
||||
|
||||
@@ -92,14 +92,6 @@ int encode_size(int size, unsigned char *data);
|
||||
|
||||
opus_int32 frame_size_select(opus_int32 frame_size, int variable_duration, opus_int32 Fs);
|
||||
|
||||
opus_int32 compute_frame_size(const void *analysis_pcm, int frame_size,
|
||||
int variable_duration, int C, opus_int32 Fs, int bitrate_bps,
|
||||
int delay_compensation, downmix_func downmix
|
||||
#ifndef DISABLE_FLOAT_API
|
||||
, float *subframe_mem
|
||||
#endif
|
||||
);
|
||||
|
||||
opus_int32 opus_encode_native(OpusEncoder *st, const opus_val16 *pcm, int frame_size,
|
||||
unsigned char *data, opus_int32 out_data_bytes, int lsb_depth,
|
||||
const void *analysis_pcm, opus_int32 analysis_size, int c1, int c2,
|
||||
|
||||
Reference in new issue
Block a user