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,106 @@
|
||||
package amrnb
|
||||
|
||||
// Parameterized codebook-search correlation, ported from opencore-amrnb
|
||||
// cor_h_x2.cpp. corHX2 is the generalized form of corHX used by the multi-pulse
|
||||
// searches (MR102: 4 tracks, MR122: 5 tracks): dn[i] = normalized 2·Σ x[j]·h[j-i]
|
||||
// with a configurable track count and step. Bit-exact with the reference.
|
||||
|
||||
const cLOG2_OF_32 = 5
|
||||
|
||||
// corHX2 computes the normalized target↔impulse correlation dn[] over nbTrack
|
||||
// tracks with the given step, scaled by sf. Mirrors cor_h_x2.
|
||||
func corHX2(h, x, dn []int16, sf, nbTrack, step int16) {
|
||||
// y32[i] = 2·sum_{j=i}^{L-1} x[j]·h[j-i] = 2·sum_{j'=0}^{L-1-i} x[i+j']·h[j'].
|
||||
// Zero-padding x past L turns this into one L-tap FIR over the padded input
|
||||
// (firRaw); s<<1 == dst[i]<<1 holds mod 2^32 since <<1 distributes over the
|
||||
// wrapping sum.
|
||||
var xpad [2 * cL_CODE]int16
|
||||
copy(xpad[:cL_CODE], x[:cL_CODE])
|
||||
var dst [cL_CODE]int32
|
||||
firRaw(dst[:], xpad[:], h[:cL_CODE])
|
||||
|
||||
var y32 [cL_CODE]int32
|
||||
for i := 0; i < cL_CODE; i++ {
|
||||
y32[i] = dst[i] << 1
|
||||
}
|
||||
|
||||
tot := int32(cLOG2_OF_32)
|
||||
for k := int16(0); k < nbTrack; k++ {
|
||||
var max int32
|
||||
for i := k; i < cL_CODE; i += step {
|
||||
if a := L_abs(y32[i]); a > max {
|
||||
max = a
|
||||
}
|
||||
}
|
||||
tot += max >> 1
|
||||
}
|
||||
|
||||
j := norm_l(tot) - sf
|
||||
for i := 0; i < cL_CODE; i++ {
|
||||
dn[i] = round_(L_shl(y32[i], j))
|
||||
}
|
||||
}
|
||||
|
||||
// setSign12k2 combines the residual cn and the correlation dn to determine each
|
||||
// position's pulse sign, the per-track maximum positions (posMax), and a cyclic
|
||||
// pulse-track ordering (ipos, length 2*nbTrack) starting from the strongest
|
||||
// track — the prep for the multi-pulse search_10and8i40. dn is updated in place
|
||||
// (negated where the combined sign is negative). Mirrors set_sign12k2.
|
||||
func setSign12k2(dn, cn, sign, posMax []int16, nbTrack int16, ipos []int16, step int16) {
|
||||
const L = cL_CODE
|
||||
var en [cL_CODE]int16
|
||||
|
||||
s := int32(256)
|
||||
t := int32(256)
|
||||
for i := 0; i < L; i++ {
|
||||
s = L_mac(s, cn[i], cn[i])
|
||||
t += (int32(dn[i]) * int32(dn[i])) << 1
|
||||
}
|
||||
s = invSqrt(s)
|
||||
kCn := int16(L_shl(s, 5) >> 16)
|
||||
t = invSqrt(t)
|
||||
kDn := int16(t >> 11)
|
||||
|
||||
for i := L - 1; i >= 0; i-- {
|
||||
lTemp := (int32(kCn) * int32(cn[i])) << 1
|
||||
val := dn[i]
|
||||
ss := L_mac(lTemp, kDn, val)
|
||||
cor := round_(L_shl(ss, 10))
|
||||
if cor >= 0 {
|
||||
sign[i] = 32767
|
||||
} else {
|
||||
sign[i] = -32767
|
||||
cor = negate(cor)
|
||||
dn[i] = negate(val)
|
||||
}
|
||||
en[i] = cor
|
||||
}
|
||||
|
||||
maxOfAll := int16(-1)
|
||||
var pos int16
|
||||
for i := int16(0); i < nbTrack; i++ {
|
||||
max := int16(-1)
|
||||
for j := i; j < L; j += step {
|
||||
if en[j] > max {
|
||||
max = en[j]
|
||||
pos = j
|
||||
}
|
||||
}
|
||||
posMax[i] = pos
|
||||
if max > maxOfAll {
|
||||
maxOfAll = max
|
||||
ipos[0] = i
|
||||
}
|
||||
}
|
||||
|
||||
pos = ipos[0]
|
||||
ipos[nbTrack] = pos
|
||||
for i := int16(1); i < nbTrack; i++ {
|
||||
pos++
|
||||
if pos >= nbTrack {
|
||||
pos = 0
|
||||
}
|
||||
ipos[i] = pos
|
||||
ipos[i+nbTrack] = pos
|
||||
}
|
||||
}
|
||||
Reference in new issue
Block a user