/* The minimum probability of an energy delta (out of 32768). */ #define LAPLACE_LOG_MINP (0) #define LAPLACE_MINP (1<<LAPLACE_LOG_MINP) /* The minimum number of guaranteed representable energy deltas (in one
direction). */ #define LAPLACE_NMIN (16)
/* When called, decay is positive and at most 11456. */ staticunsigned ec_laplace_get_freq1(unsigned fs0, int decay)
{ unsigned ft;
ft = 32768 - LAPLACE_MINP*(2*LAPLACE_NMIN) - fs0; return ft*(opus_int32)(16384-decay)>>15;
}
void ec_laplace_encode(ec_enc *enc, int *value, unsigned fs, int decay)
{ unsigned fl; int val = *value;
fl = 0; if (val)
{ int s; int i;
s = -(val<0);
val = (val+s)^s;
fl = fs;
fs = ec_laplace_get_freq1(fs, decay); /* Search the decaying part of the PDF.*/ for (i=1; fs > 0 && i < val; i++)
{
fs *= 2;
fl += fs+2*LAPLACE_MINP;
fs = (fs*(opus_int32)decay)>>15;
} /* Everything beyond that has probability LAPLACE_MINP. */ if (!fs)
{ int di; int ndi_max;
ndi_max = (32768-fl+LAPLACE_MINP-1)>>LAPLACE_LOG_MINP;
ndi_max = (ndi_max-s)>>1;
di = IMIN(val - i, ndi_max - 1);
fl += (2*di+1+s)*LAPLACE_MINP;
fs = IMIN(LAPLACE_MINP, 32768-fl);
*value = (i+di+s)^s;
} else
{
fs += LAPLACE_MINP;
fl += fs&~s;
}
celt_assert(fl+fs<=32768);
celt_assert(fs>0);
}
ec_encode_bin(enc, fl, fl+fs, 15);
}
int ec_laplace_decode(ec_dec *dec, unsigned fs, int decay)
{ int val=0; unsigned fl; unsigned fm;
fm = ec_decode_bin(dec, 15);
fl = 0; if (fm >= fs)
{
val++;
fl = fs;
fs = ec_laplace_get_freq1(fs, decay)+LAPLACE_MINP; /* Search the decaying part of the PDF.*/ while(fs > LAPLACE_MINP && fm >= fl+2*fs)
{
fs *= 2;
fl += fs;
fs = ((fs-2*LAPLACE_MINP)*(opus_int32)decay)>>15;
fs += LAPLACE_MINP;
val++;
} /* Everything beyond that has probability LAPLACE_MINP. */ if (fs <= LAPLACE_MINP)
{ int di;
di = (fm-fl)>>(LAPLACE_LOG_MINP+1);
val += di;
fl += 2*di*LAPLACE_MINP;
} if (fm < fl+fs)
val = -val; else
fl += fs;
}
celt_assert(fl<32768);
celt_assert(fs>0);
celt_assert(fl<=fm);
celt_assert(fm<IMIN(fl+fs,32768));
ec_dec_update(dec, fl, IMIN(fl+fs,32768), 32768); return val;
}
void ec_laplace_encode_p0(ec_enc *enc, int value, opus_uint16 p0, opus_uint16 decay)
{ int s;
opus_uint16 sign_icdf[3];
sign_icdf[0] = 32768-p0;
sign_icdf[1] = sign_icdf[0]/2;
sign_icdf[2] = 0;
s = value == 0 ? 0 : (value > 0 ? 1 : 2);
ec_enc_icdf16(enc, s, sign_icdf, 15);
value = abs(value); if (value)
{ int i;
opus_uint16 icdf[8];
icdf[0] = IMAX(7, decay); for (i=1;i<7;i++)
{
icdf[i] = IMAX(7-i, (icdf[i-1] * (opus_int32)decay) >> 15);
}
icdf[7] = 0;
value--; do {
ec_enc_icdf16(enc, IMIN(value, 7), icdf, 15);
value -= 7;
} while (value >= 0);
}
}
int ec_laplace_decode_p0(ec_dec *dec, opus_uint16 p0, opus_uint16 decay)
{ int s; int value;
opus_uint16 sign_icdf[3];
sign_icdf[0] = 32768-p0;
sign_icdf[1] = sign_icdf[0]/2;
sign_icdf[2] = 0;
s = ec_dec_icdf16(dec, sign_icdf, 15); if (s==2) s = -1; if (s != 0)
{ int i; int v;
opus_uint16 icdf[8];
icdf[0] = IMAX(7, decay); for (i=1;i<7;i++)
{
icdf[i] = IMAX(7-i, (icdf[i-1] * (opus_int32)decay) >> 15);
}
icdf[7] = 0;
value = 1; do {
v = ec_dec_icdf16(dec, icdf, 15);
value += v;
} while (v == 7); return s*value;
} elsereturn0;
}
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.