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,101 @@
|
||||
package amrnb
|
||||
|
||||
// Gain dequantization, ported from opencore-amrnb d_gain_p.cpp, d_gain_c.cpp and
|
||||
// dec_gain.cpp. These turn the received gain indices into the per-subframe pitch
|
||||
// gain and fixed-codebook gain, driving the gc_pred energy predictor. dGainPitch
|
||||
// and dGainCode handle MR795/MR122; decGain handles the joint/scalar-VQ modes
|
||||
// (MR475 joint, MR515/MR59 low-rate, MR67/MR74/MR102 high-rate). Bit-exact with
|
||||
// the reference.
|
||||
|
||||
const cMR475_VQ_SIZE = 256
|
||||
|
||||
// dGainPitch returns the quantized pitch gain (Q14) for the given index.
|
||||
// Mirrors d_gain_pitch.
|
||||
func dGainPitch(mode int, index int16) int16 {
|
||||
gain := qua_gain_pitch[index]
|
||||
if mode == dMR122 {
|
||||
gain &^= 3 // clear 2 LSBits
|
||||
}
|
||||
return gain
|
||||
}
|
||||
|
||||
// dGainCode decodes the fixed-codebook gain for MR795/MR122 from the predicted
|
||||
// gain (gc_pred) and the quantized correction factor, then updates the
|
||||
// predictor. Mirrors d_gain_code.
|
||||
func (pred *gcPredState) dGainCode(mode int, index int16, code []int16) (gainCode int16) {
|
||||
r := pred.gcPred(mode, code)
|
||||
exp, frac := r.expGcode0, r.fracGcode0
|
||||
|
||||
index &= 31 // index < 32, avoid buffer overflow
|
||||
tblTmp := index + (index << 1)
|
||||
p := qua_gain_code[tblTmp:]
|
||||
|
||||
if mode == dMR122 {
|
||||
gcode0 := int16(pow2(exp, frac))
|
||||
gcode0 = shl(gcode0, 4)
|
||||
gainCode = shl(mult(gcode0, p[0]), 1)
|
||||
} else {
|
||||
gcode0 := int16(pow2(14, frac))
|
||||
lTmp := L_mult(p[0], gcode0)
|
||||
lTmp = L_shr(lTmp, sub(9, exp))
|
||||
gainCode = int16(lTmp >> 16) // Q1
|
||||
}
|
||||
|
||||
quaEnerMR122 := p[1]
|
||||
quaEner := p[2]
|
||||
pred.update(quaEnerMR122, quaEner)
|
||||
return gainCode
|
||||
}
|
||||
|
||||
// decGain decodes both the pitch gain and fixed-codebook gain for the
|
||||
// scalar/joint-VQ modes (all except MR795/MR122), updating the predictor.
|
||||
// evenSubfr selects the MR475 joint-gain half. Mirrors Dec_gain.
|
||||
func (pred *gcPredState) decGain(mode int, index int16, code []int16, evenSubfr int16) (gainPit, gainCod int16) {
|
||||
index = shl(index, 2)
|
||||
|
||||
var gCode, quaEnerMR122, quaEner int16
|
||||
|
||||
switch {
|
||||
case mode == dMR102 || mode == dMR74 || mode == dMR67:
|
||||
p := table_gain_highrates[index:]
|
||||
gainPit = p[0]
|
||||
gCode = p[1]
|
||||
quaEnerMR122 = p[2]
|
||||
quaEner = p[3]
|
||||
case mode == dMR475:
|
||||
index += (1 ^ evenSubfr) << 1 // evenSubfr is 0 or 1
|
||||
if index > int16(cMR475_VQ_SIZE*4-2) {
|
||||
index = int16(cMR475_VQ_SIZE*4 - 2)
|
||||
}
|
||||
p := table_gain_MR475[index:]
|
||||
gainPit = p[0]
|
||||
gCode = p[1]
|
||||
// Predictor update values are recomputed (not stored in the 4.75 table):
|
||||
// qua_ener_MR122 = log2(g), qua_ener = 20*log10(g)
|
||||
e, f := log2(int32(gCode)) // Log2(x Q12) = log2(x) + 12
|
||||
e -= 12
|
||||
t1 := shr_r(f, 5)
|
||||
t2 := shl(e, 10)
|
||||
quaEnerMR122 = add(t1, t2)
|
||||
lTmp := mpy32_16(e, f, 24660) // 24660 Q12 ~= 20*log10(2)
|
||||
lTmp = L_shl(lTmp, 13)
|
||||
quaEner = round_(lTmp)
|
||||
default: // MR515, MR59
|
||||
p := table_gain_lowrates[index:]
|
||||
gainPit = p[0]
|
||||
gCode = p[1]
|
||||
quaEnerMR122 = p[2]
|
||||
quaEner = p[3]
|
||||
}
|
||||
|
||||
r := pred.gcPred(mode, code)
|
||||
exp, frac := r.expGcode0, r.fracGcode0
|
||||
gcode0 := int16(pow2(14, frac))
|
||||
|
||||
lTmp := L_mult(gCode, gcode0)
|
||||
lTmp = L_shr(lTmp, 10-exp)
|
||||
gainCod = int16(lTmp >> 16)
|
||||
|
||||
pred.update(quaEnerMR122, quaEner)
|
||||
return gainPit, gainCod
|
||||
}
|
||||
Reference in new issue
Block a user