feat(capability): 转码能力包(vendor 纯 Go AMR-NB 解码器 + 黄金向量逐样本对照 + 8 哨兵 + 注册面)
This commit is contained in:
1 parent
89715d1813
commit
4a2d276881
100 files changed
+11319
No files matched your search
@@ -0,0 +1,77 @@
|
||||
package amrnb
|
||||
|
||||
// Adaptive gain control for the post-filter, ported from opencore-amrnb agc.cpp.
|
||||
// agc scales the post-filtered signal so its energy tracks the synthesis
|
||||
// energy, with a per-sample gain smoothed by agc_fac across the subframe. The
|
||||
// running gain is carried in agcState. Bit-exact with the reference.
|
||||
|
||||
const cAGC_FAC = 29491 // 0.9, the post-filter AGC factor
|
||||
|
||||
// agcState holds the smoothed per-sample gain across subframes.
|
||||
type agcState struct {
|
||||
pastGain int16
|
||||
}
|
||||
|
||||
// energyOld accumulates the energy of a prescaled signal (used when energyNew
|
||||
// would overflow). Mirrors energy_old.
|
||||
func energyOld(in []int16, lTrm int) int32 {
|
||||
var s int32
|
||||
for i := 0; i < lTrm; i++ {
|
||||
temp := in[i] >> 2
|
||||
s = L_mac(s, temp, temp)
|
||||
}
|
||||
return s
|
||||
}
|
||||
|
||||
// energyNew returns the energy of a signal (>>4 scaled), falling back to
|
||||
// energyOld on saturation. Mirrors energy_new.
|
||||
func energyNew(in []int16, lTrm int) int32 {
|
||||
var s int32
|
||||
for i := 0; i < lTrm; i++ {
|
||||
s = L_mac(s, in[i], in[i])
|
||||
}
|
||||
if s != maxInt32 {
|
||||
return s >> 4
|
||||
}
|
||||
return energyOld(in, lTrm)
|
||||
}
|
||||
|
||||
// agc scales sigOut in place so its energy approaches sigIn's, applying a gain
|
||||
// smoothed across the subframe by agcFac and carried in the state. Mirrors agc.
|
||||
func (st *agcState) agc(sigIn, sigOut []int16, agcFac int16, lTrm int) {
|
||||
s := energyNew(sigOut, lTrm)
|
||||
if s == 0 {
|
||||
st.pastGain = 0
|
||||
return
|
||||
}
|
||||
exp := norm_l(s) - 1
|
||||
gainOut := round_(L_shl(s, exp))
|
||||
|
||||
s = energyNew(sigIn, lTrm)
|
||||
var g0 int16
|
||||
if s == 0 {
|
||||
g0 = 0
|
||||
} else {
|
||||
i := norm_l(s)
|
||||
gainIn := round_(s << i)
|
||||
exp -= i
|
||||
|
||||
temp := div_s(gainOut, gainIn)
|
||||
ss := int32(temp) << 7
|
||||
ss = L_shr(ss, exp)
|
||||
ss = invSqrt(ss)
|
||||
lTemp := ss << 9
|
||||
ii := int16((lTemp + 0x8000) >> 16)
|
||||
temp = 32767 - agcFac
|
||||
g0 = int16((int32(ii) * int32(temp)) >> 15)
|
||||
}
|
||||
|
||||
gain := st.pastGain
|
||||
for i := 0; i < lTrm; i++ {
|
||||
gain = int16((int32(gain) * int32(agcFac)) >> 15)
|
||||
gain += g0
|
||||
lTemp := (int32(sigOut[i]) * int32(gain)) << 1
|
||||
sigOut[i] = int16(lTemp >> 13)
|
||||
}
|
||||
st.pastGain = gain
|
||||
}
|
||||
Reference in new issue
Block a user