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,99 @@
|
||||
package amrnb
|
||||
|
||||
// Separate pitch/code gain quantizers (MR122; pitch also used by MR795), ported
|
||||
// from opencore-amrnb q_gain_p.cpp (q_gain_pitch) and q_gain_c.cpp
|
||||
// (q_gain_code). qGainPitch picks the nearest quantized pitch gain; qGainCode
|
||||
// picks the code-gain index minimizing the error to the predicted gain. The
|
||||
// exact encoder counterparts of dGainPitch / dGainCode. Bit-exact with the
|
||||
// reference.
|
||||
|
||||
const (
|
||||
cNB_QUA_PITCH = 16
|
||||
cNB_QUA_CODE = 32
|
||||
)
|
||||
|
||||
// qGainPitch quantizes the pitch gain (in place) to the nearest table entry
|
||||
// within gpLimit, returning the index. For MR795 it also fills three candidate
|
||||
// gains/indices. Mirrors q_gain_pitch.
|
||||
func qGainPitch(mode int, gpLimit int16, gain *int16, gainCand, gainCind []int16) int16 {
|
||||
errMin := abs_s(sub(*gain, qua_gain_pitch[0]))
|
||||
index := int16(0)
|
||||
for i := int16(1); i < cNB_QUA_PITCH; i++ {
|
||||
if qua_gain_pitch[i] <= gpLimit {
|
||||
err := abs_s(sub(*gain, qua_gain_pitch[i]))
|
||||
if err < errMin {
|
||||
errMin = err
|
||||
index = i
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if mode == dMR795 {
|
||||
var ii int16
|
||||
switch {
|
||||
case index == 0:
|
||||
ii = index
|
||||
case index == cNB_QUA_PITCH-1 || qua_gain_pitch[index+1] > gpLimit:
|
||||
ii = index - 2
|
||||
default:
|
||||
ii = index - 1
|
||||
}
|
||||
for i := 0; i < 3; i++ {
|
||||
gainCind[i] = ii
|
||||
gainCand[i] = qua_gain_pitch[ii]
|
||||
ii++
|
||||
}
|
||||
*gain = qua_gain_pitch[index]
|
||||
} else if mode == dMR122 {
|
||||
*gain = qua_gain_pitch[index] &^ 3
|
||||
} else {
|
||||
*gain = qua_gain_pitch[index]
|
||||
}
|
||||
return index
|
||||
}
|
||||
|
||||
// qGainCode quantizes the fixed-codebook gain (in place) against the predicted
|
||||
// gain, returning the index and the predictor-update energies. Mirrors
|
||||
// q_gain_code.
|
||||
func qGainCode(mode int, expGcode0, fracGcode0 int16, gain *int16) (index, quaEnerMR122, quaEner int16) {
|
||||
var gQ0 int16
|
||||
if mode == dMR122 {
|
||||
gQ0 = *gain >> 1 // Q1 -> Q0
|
||||
} else {
|
||||
gQ0 = *gain
|
||||
}
|
||||
|
||||
gcode0 := int16(pow2(expGcode0, fracGcode0))
|
||||
if mode == dMR122 {
|
||||
gcode0 = shl(gcode0, 4)
|
||||
} else {
|
||||
gcode0 = shl(gcode0, 5)
|
||||
}
|
||||
|
||||
errMin := gQ0 - int16((int32(gcode0)*int32(qua_gain_code[0]))>>15)
|
||||
if errMin < 0 {
|
||||
errMin = -errMin
|
||||
}
|
||||
index = 0
|
||||
for i := int16(1); i < cNB_QUA_CODE; i++ {
|
||||
err := gQ0 - int16((int32(gcode0)*int32(qua_gain_code[i*3]))>>15)
|
||||
if err < 0 {
|
||||
err = -err
|
||||
}
|
||||
if err < errMin {
|
||||
errMin = err
|
||||
index = i
|
||||
}
|
||||
}
|
||||
|
||||
p := int(index) * 3
|
||||
temp := int16((int32(gcode0) * int32(qua_gain_code[p])) >> 15)
|
||||
if mode == dMR122 {
|
||||
*gain = temp << 1
|
||||
} else {
|
||||
*gain = temp
|
||||
}
|
||||
quaEnerMR122 = qua_gain_code[p+1]
|
||||
quaEner = qua_gain_code[p+2]
|
||||
return
|
||||
}
|
||||
Reference in new issue
Block a user