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,67 @@
|
||||
package amrnb
|
||||
|
||||
// Output post-processing building blocks, ported from opencore-amrnb
|
||||
// weight_a.cpp (Weight_Ai), preemph.cpp (preemphasis) and post_pro.cpp
|
||||
// (Post_Process). weightAi applies gamma bandwidth expansion to an LP filter;
|
||||
// preemphasis is the 1st-order y[n]=x[n]-g·x[n-1]; postProcess is the decoder's
|
||||
// output high-pass biquad with the ×2 output scaling. Bit-exact with the
|
||||
// reference.
|
||||
|
||||
// weightAi computes the bandwidth-expanded coefficients a_exp[i] = a[i]·fac[i-1]
|
||||
// (with a_exp[0]=a[0]). Mirrors Weight_Ai.
|
||||
func weightAi(a []int16, fac []int16, aExp []int16) {
|
||||
aExp[0] = a[0]
|
||||
for i := 1; i <= cM; i++ {
|
||||
aExp[i] = int16((int32(a[i])*int32(fac[i-1]) + 0x4000) >> 15)
|
||||
}
|
||||
}
|
||||
|
||||
// preemphasis applies y[n] = x[n] - g·x[n-1] in place over L samples, carrying
|
||||
// one sample of memory. Mirrors preemphasis (preemph.cpp).
|
||||
func preemphasis(memPre *int16, signal []int16, g int16, L int) {
|
||||
temp := signal[L-1]
|
||||
for i := L - 1; i >= 1; i-- {
|
||||
signal[i] = sub(signal[i], mult(g, signal[i-1]))
|
||||
}
|
||||
signal[0] = sub(signal[0], mult(g, *memPre))
|
||||
*memPre = temp
|
||||
}
|
||||
|
||||
// post-process output high-pass biquad coefficients (post_pro.cpp).
|
||||
var postB = [3]int16{7699, -15398, 7699}
|
||||
var postA = [3]int16{8192, 15836, -7667}
|
||||
|
||||
// postProcessState holds the biquad's double-precision input/output memory.
|
||||
type postProcessState struct {
|
||||
x0, x1 int16
|
||||
y1hi, y1lo, y2hi, y2lo int16
|
||||
}
|
||||
|
||||
// process applies the output high-pass filter (with ×2 gain) in place over lg
|
||||
// samples. The feedback memory is kept as (hi,lo) double precision. Mirrors
|
||||
// Post_Process.
|
||||
func (st *postProcessState) process(signal []int16, lg int) {
|
||||
a1, a2 := int32(postA[1]), int32(postA[2])
|
||||
b0, b1, b2 := int32(postB[0]), int32(postB[1]), int32(postB[2])
|
||||
for i := 0; i < lg; i++ {
|
||||
x2 := st.x1
|
||||
st.x1 = st.x0
|
||||
st.x0 = signal[i]
|
||||
|
||||
L := int32(st.y1hi) * a1
|
||||
L += (int32(st.y1lo) * a1) >> 15
|
||||
L += int32(st.y2hi) * a2
|
||||
L += (int32(st.y2lo) * a2) >> 15
|
||||
L += int32(st.x0) * b0
|
||||
L += int32(st.x1) * b1
|
||||
L += int32(x2) * b2
|
||||
|
||||
L = L_shl(L, 3)
|
||||
signal[i] = round_(L_shl(L, 1))
|
||||
|
||||
st.y2hi = st.y1hi
|
||||
st.y2lo = st.y1lo
|
||||
st.y1hi = int16(L >> 16)
|
||||
st.y1lo = int16((L >> 1) - (int32(st.y1hi) << 15))
|
||||
}
|
||||
}
|
||||
Reference in new issue
Block a user