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,183 @@
|
||||
package amrnb
|
||||
|
||||
// Adaptive-codebook (pitch) reconstruction, ported from opencore-amrnb
|
||||
// pred_lt.cpp, dec_lag3.cpp and dec_lag6.cpp. predLt interpolates the past
|
||||
// excitation at a fractional pitch lag to build this subframe's adaptive
|
||||
// codebook contribution; decLag3/decLag6 turn the received pitch index into an
|
||||
// integer lag T0 and a fractional part. Bit-exact with the reference.
|
||||
|
||||
const (
|
||||
cL_INTER10 = 10 // interpolation FIR half-context (L_INTERPOL-1)
|
||||
cUP_SAMP_MAX = 6 // fractional pitch upsampling factor
|
||||
)
|
||||
|
||||
// predLt computes the interpolated past excitation for the current subframe in
|
||||
// place: exc[pos : pos+Lsubfr] is overwritten using exc[pos-T0 ...] convolved
|
||||
// with the 1/6-resolution FIR selected by frac. For short lags (T0 < Lsubfr)
|
||||
// the loop deliberately reads samples it just wrote, matching the reference.
|
||||
// Mirrors Pred_lt_3or6.
|
||||
func predLt(exc []int16, pos int, T0, frac, Lsubfr, flag3 int16) {
|
||||
var coeff [2 * cL_INTER10]int16
|
||||
|
||||
pX0 := pos - int(T0)
|
||||
frac = -frac
|
||||
if flag3 != 0 {
|
||||
frac <<= 1 // inter_3l[k] = inter_6[2k]
|
||||
}
|
||||
if frac < 0 {
|
||||
frac += cUP_SAMP_MAX
|
||||
pX0--
|
||||
}
|
||||
f := int(frac)
|
||||
|
||||
k := 0
|
||||
ci := 0
|
||||
for i := cL_INTER10 >> 1; i > 0; i-- {
|
||||
coeff[ci] = inter_6_pred_lt[f+k]
|
||||
coeff[ci+1] = inter_6_pred_lt[(cUP_SAMP_MAX-f)+k]
|
||||
ci += 2
|
||||
k += cUP_SAMP_MAX
|
||||
coeff[ci] = inter_6_pred_lt[f+k]
|
||||
coeff[ci+1] = inter_6_pred_lt[(cUP_SAMP_MAX-f)+k]
|
||||
ci += 2
|
||||
k += cUP_SAMP_MAX
|
||||
}
|
||||
|
||||
pExc := pos
|
||||
for j := int(Lsubfr) >> 1; j != 0; j-- {
|
||||
pX0++
|
||||
ix2 := pX0
|
||||
ix3 := pX0
|
||||
pX0++
|
||||
|
||||
ic := 0
|
||||
s1 := int32(0x4000)
|
||||
s2 := int32(0x4000)
|
||||
for i := cL_INTER10 >> 1; i > 0; i-- {
|
||||
s2 += int32(exc[ix3]) * int32(coeff[ic])
|
||||
ix3--
|
||||
s1 += int32(exc[ix3]) * int32(coeff[ic])
|
||||
ic++
|
||||
s1 += int32(exc[ix2]) * int32(coeff[ic])
|
||||
ix2++
|
||||
s2 += int32(exc[ix2]) * int32(coeff[ic])
|
||||
ic++
|
||||
s2 += int32(exc[ix3]) * int32(coeff[ic])
|
||||
ix3--
|
||||
s1 += int32(exc[ix3]) * int32(coeff[ic])
|
||||
ic++
|
||||
s1 += int32(exc[ix2]) * int32(coeff[ic])
|
||||
ix2++
|
||||
s2 += int32(exc[ix2]) * int32(coeff[ic])
|
||||
ic++
|
||||
}
|
||||
exc[pExc] = int16(s1 >> 15)
|
||||
pExc++
|
||||
exc[pExc] = int16(s2 >> 15)
|
||||
pExc++
|
||||
}
|
||||
}
|
||||
|
||||
// decLag3 decodes the 1/3-resolution pitch lag (used by most modes) from the
|
||||
// received index into an integer lag T0 and fractional part T0frac. i_subfr==0
|
||||
// marks the 1st/3rd subframe (absolute coding); otherwise the lag is coded
|
||||
// relative to t0_min (or, with flag4, to T0prev). Mirrors Dec_lag3.
|
||||
func decLag3(index, t0Min, t0Max, iSubfr, T0prev, flag4 int16) (T0, T0frac int16) {
|
||||
var i, tmpLag int16
|
||||
if iSubfr == 0 { // 1st or 3rd subframe
|
||||
if index < 197 {
|
||||
tmpLag = index + 2
|
||||
tmpLag = mult(tmpLag, 10923)
|
||||
i = tmpLag + 19
|
||||
T0 = i
|
||||
i <<= 1
|
||||
i += T0
|
||||
tmpLag = index - i
|
||||
T0frac = tmpLag + 58
|
||||
} else {
|
||||
T0 = index - 112
|
||||
T0frac = 0
|
||||
}
|
||||
} else { // 2nd or 4th subframe
|
||||
if flag4 == 0 {
|
||||
i = index + 2
|
||||
i = int16((int32(i) * 10923) >> 15)
|
||||
i -= 1
|
||||
T0 = i + t0Min
|
||||
i = i + (i << 1)
|
||||
tmpLag = index - 2
|
||||
T0frac = tmpLag - i
|
||||
} else {
|
||||
tmpLag = T0prev
|
||||
i = sub(tmpLag, t0Min)
|
||||
if i > 5 {
|
||||
tmpLag = t0Min + 5
|
||||
}
|
||||
i = t0Max - tmpLag
|
||||
if i > 4 {
|
||||
tmpLag = t0Max - 4
|
||||
}
|
||||
if index < 4 {
|
||||
i = tmpLag - 5
|
||||
T0 = i + index
|
||||
T0frac = 0
|
||||
} else if index < 12 {
|
||||
i = index - 5
|
||||
i = int16((int32(i) * 10923) >> 15)
|
||||
i--
|
||||
T0 = i + tmpLag
|
||||
i = i + (i << 1)
|
||||
tmpLag = index - 9
|
||||
T0frac = tmpLag - i
|
||||
} else {
|
||||
i = index - 12
|
||||
i = i + tmpLag
|
||||
T0 = i + 1
|
||||
T0frac = 0
|
||||
}
|
||||
}
|
||||
}
|
||||
return T0, T0frac
|
||||
}
|
||||
|
||||
// decLag6 decodes the 1/6-resolution pitch lag (MR122) from the received index.
|
||||
// T0in supplies the previous subframe's integer lag for the relative (2nd/4th)
|
||||
// subframe path. Mirrors Dec_lag6.
|
||||
func decLag6(index, pitMin, pitMax, iSubfr, T0in int16) (T0, T0frac int16) {
|
||||
var i, T0min, T0max, k int16
|
||||
if iSubfr == 0 { // 1st or 3rd subframe
|
||||
if index < 463 {
|
||||
i = index + 5
|
||||
i = int16((int32(i) * 5462) >> 15)
|
||||
i += 17
|
||||
T0 = i
|
||||
i <<= 1
|
||||
i += T0
|
||||
i <<= 1
|
||||
i = index - i
|
||||
T0frac = i + 105
|
||||
} else {
|
||||
T0 = index - 368
|
||||
T0frac = 0
|
||||
}
|
||||
} else { // 2nd or 4th subframe
|
||||
T0min = T0in - 5
|
||||
if T0min < pitMin {
|
||||
T0min = pitMin
|
||||
}
|
||||
T0max = T0min + 9
|
||||
if T0max > pitMax {
|
||||
T0max = pitMax
|
||||
T0min = T0max - 9
|
||||
}
|
||||
i = index + 5
|
||||
i = int16((int32(i) * 5462) >> 15)
|
||||
i -= 1
|
||||
T0 = i + T0min
|
||||
i = i + (i << 1)
|
||||
i <<= 1
|
||||
k = index - 3
|
||||
T0frac = k - i
|
||||
}
|
||||
return T0, T0frac
|
||||
}
|
||||
Reference in new issue
Block a user