97 lines
2.4 KiB
Go
97 lines
2.4 KiB
Go
package amrnb
|
|
|
|
// 10-pulse algebraic codebook search (35 bits, MR122), ported from
|
|
// opencore-amrnb c1035pf.cpp. Reuses search10and8i40 (10 pulses, step 5), then
|
|
// builds the codeword (±4096 pulses) and Gray-encodes the per-track position
|
|
// indices (q_p). The exact encoder counterpart of dec10i40_35bits. Bit-exact
|
|
// with the reference.
|
|
|
|
// build10Code assembles the 10-pulse innovation cod, filtered code y, and the
|
|
// raw per-track position+sign indices (with the same-track ordering/swap logic
|
|
// that the decoder inverts). Mirrors build_code (c1035pf.cpp).
|
|
func build10Code(codvec, sign, cod, h, y, indx []int16) {
|
|
const L = cL_CODE
|
|
for i := 0; i < L; i++ {
|
|
cod[i] = 0
|
|
}
|
|
for t := 0; t < 5; t++ {
|
|
indx[t] = -1
|
|
}
|
|
|
|
var sgn [10]int16
|
|
for k := 0; k < 10; k++ {
|
|
i := codvec[k]
|
|
index := int16((int32(i) * 6554) >> 15)
|
|
track := i - (index + (index << 2)) // i - index*5
|
|
|
|
if sign[i] > 0 {
|
|
cod[i] += 4096
|
|
sgn[k] = 8192
|
|
} else {
|
|
cod[i] -= 4096
|
|
sgn[k] = -8192
|
|
index += 8
|
|
}
|
|
|
|
temp := indx[track]
|
|
switch {
|
|
case temp < 0:
|
|
indx[track] = index
|
|
case (index^temp)&8 == 0:
|
|
if temp <= index {
|
|
indx[track+5] = index
|
|
} else {
|
|
indx[track+5] = temp
|
|
indx[track] = index
|
|
}
|
|
default:
|
|
if (temp & 7) <= (index & 7) {
|
|
indx[track+5] = temp
|
|
indx[track] = index
|
|
} else {
|
|
indx[track+5] = index
|
|
}
|
|
}
|
|
}
|
|
|
|
for i := 0; i < L; i++ {
|
|
var s int32
|
|
for k := 0; k < 10; k++ {
|
|
ci := int(codvec[k])
|
|
var hv int16
|
|
if i-ci >= 0 {
|
|
hv = h[i-ci]
|
|
}
|
|
s += (int32(hv) * int32(sgn[k])) >> 7
|
|
}
|
|
y[i] = int16((s + 0x80) >> 8)
|
|
}
|
|
}
|
|
|
|
// code10i40_35bits runs the full MR122 10-pulse search, writing the innovation
|
|
// cod, filtered code y, and the 10-value Gray-coded index. Mirrors
|
|
// code_10i40_35bits.
|
|
func code10i40_35bits(x, cn, h, cod, y, indx []int16) {
|
|
var dn, sign [cL_CODE]int16
|
|
var rr [cL_CODE * cL_CODE]int16
|
|
var ipos, codvec [10]int16
|
|
var posMax [5]int16
|
|
|
|
corHX(h, x, dn[:], 2)
|
|
setSign12k2(dn[:], cn, sign[:], posMax[:], 5, ipos[:], 5)
|
|
corH(h, sign[:], rr[:])
|
|
search10and8i40(10, 5, 5, dn[:], rr[:], ipos[:], posMax[:], codvec[:])
|
|
build10Code(codvec[:], sign[:], cod, h, y, indx)
|
|
|
|
// q_p: Gray-encode each track's position index (keeping the sign bit for the
|
|
// first five).
|
|
for n := 0; n < 10; n++ {
|
|
tmp := indx[n]
|
|
if n < 5 {
|
|
indx[n] = (tmp & 0x8) | gray[tmp&0x7]
|
|
} else {
|
|
indx[n] = gray[tmp&0x7]
|
|
}
|
|
}
|
|
}
|