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,88 @@
|
||||
package amrnb
|
||||
|
||||
// Per-subframe codebook dispatch and post-processing, ported from opencore-amrnb
|
||||
// cbsearch.cpp (cbsearch) and spstproc.cpp (subframePostProc). cbsearch routes
|
||||
// to the mode's algebraic codebook search (and applies the MR102/MR122 pitch
|
||||
// sharpening around it); subframePostProc forms the total excitation, runs the
|
||||
// local synthesis, and updates the synthesis/error/weighting filter memories
|
||||
// for the next subframe. Bit-exact with the reference.
|
||||
|
||||
// cbsearch runs the fixed-codebook search for the mode, writing the innovation
|
||||
// code and filtered code y and the analysis indices into anap (returning the
|
||||
// count). Mirrors cbsearch.
|
||||
func cbsearch(x, h []int16, T0, pitchSharp, gainPit int16, res2, code, y []int16, mode, subNr int, anap []int16) int {
|
||||
switch {
|
||||
case mode == dMR475 || mode == dMR515:
|
||||
idx, sgn := code2i40_9bits(int16(subNr), x, h, T0, pitchSharp, code, y)
|
||||
anap[0], anap[1] = idx, sgn
|
||||
return 2
|
||||
case mode == dMR59:
|
||||
idx, sgn := code2i40_11bits(x, h, T0, pitchSharp, code, y)
|
||||
anap[0], anap[1] = idx, sgn
|
||||
return 2
|
||||
case mode == dMR67:
|
||||
idx, sgn := code3i40_14bits(x, h, T0, pitchSharp, code, y)
|
||||
anap[0], anap[1] = idx, sgn
|
||||
return 2
|
||||
case mode == dMR74 || mode == dMR795:
|
||||
idx, sgn := code4i40_17bits(x, h, T0, pitchSharp, code, y)
|
||||
anap[0], anap[1] = idx, sgn
|
||||
return 2
|
||||
case mode == dMR102:
|
||||
ps := shl(pitchSharp, 1)
|
||||
for i := T0; i < cL_SUBFR; i++ {
|
||||
h[i] = add(h[i], mult(h[i-T0], ps))
|
||||
}
|
||||
code8i40_31bits(x, res2, h, code, y, anap[0:7])
|
||||
for i := T0; i < cL_SUBFR; i++ {
|
||||
code[i] = add(code[i], mult(code[i-T0], ps))
|
||||
}
|
||||
return 7
|
||||
default: // MR122
|
||||
ps := shl(gainPit, 1)
|
||||
for i := T0; i < cL_SUBFR; i++ {
|
||||
h[i] = add(h[i], int16((int32(h[i-T0])*int32(ps))>>15))
|
||||
}
|
||||
code10i40_35bits(x, res2, h, code, y, anap[0:10])
|
||||
for i := T0; i < cL_SUBFR; i++ {
|
||||
code[i] = add(code[i], mult(code[i-T0], ps))
|
||||
}
|
||||
return 10
|
||||
}
|
||||
}
|
||||
|
||||
// subframePostProc builds the total excitation (gain_pit·adaptive +
|
||||
// gain_code·code), runs the local synthesis (updating mem_syn), and refreshes
|
||||
// the error and weighting-filter memories. sharp is updated with the clamped
|
||||
// pitch gain. Mirrors subframePostProc.
|
||||
func subframePostProc(speech []int16, speechOff, mode, iSubfr int, gainPit, gainCode int16, aq, synth, xn, code, y1, y2, memSyn, memErr, memW0, exc []int16, excOff int, sharp *int16) {
|
||||
var tempShift, kShift, pitchFac int16
|
||||
if mode != dMR122 {
|
||||
tempShift, kShift, pitchFac = 1, 16-2-1, gainPit
|
||||
} else {
|
||||
tempShift, kShift, pitchFac = 2, 16-4-1, gainPit>>1
|
||||
}
|
||||
|
||||
if gainPit < cSHARPMAX {
|
||||
*sharp = gainPit
|
||||
} else {
|
||||
*sharp = cSHARPMAX
|
||||
}
|
||||
|
||||
base := excOff + iSubfr
|
||||
for i := 0; i < cL_SUBFR; i++ {
|
||||
L := (int32(exc[base+i]) * int32(pitchFac)) << 1
|
||||
L += (int32(code[i]) * int32(gainCode)) << 1
|
||||
L <<= uint(tempShift)
|
||||
exc[base+i] = int16((L + 0x8000) >> 16)
|
||||
}
|
||||
|
||||
synFilt(aq, exc[base:base+cL_SUBFR], synth[iSubfr:iSubfr+cL_SUBFR], cL_SUBFR, memSyn, true)
|
||||
|
||||
for i, j := cL_SUBFR-cM, 0; i < cL_SUBFR; i, j = i+1, j+1 {
|
||||
memErr[j] = speech[speechOff+iSubfr+i] - synth[iSubfr+i]
|
||||
temp := int16((int32(y1[i]) * int32(gainPit)) >> 14)
|
||||
temp += int16((int32(y2[i]) * int32(gainCode)) >> uint(kShift))
|
||||
memW0[j] = xn[i] - temp
|
||||
}
|
||||
}
|
||||
Reference in new issue
Block a user