263 lines
5.4 KiB
Go
263 lines
5.4 KiB
Go
package amrnb
|
|
|
|
// Per-mode algebraic (fixed) codebook decoders, ported from opencore-amrnb
|
|
// d2_9pf.cpp, d2_11pf.cpp, d3_14pf.cpp, d4_17pf.cpp, d8_31pf.cpp and
|
|
// d1035pf.cpp. Each reconstructs the 40-sample innovation vector cod[] from a
|
|
// mode's pulse-position and sign indices (GSM-style tracks, Gray-coded for the
|
|
// 4/8/10-pulse modes). Pulse amplitudes are ±8191/∓8192 (or ±4096 for MR122),
|
|
// matching the reference exactly.
|
|
|
|
// pulse amplitude for the ±1.0 codebook entries (MR122 uses ±4096).
|
|
const cPOS_CODE = 8191
|
|
|
|
// decode2i40_9bits decodes the 2-pulse codebook for MR475/MR515. Mirrors
|
|
// decode_2i40_9bits (d2_9pf.cpp); subNr is the subframe number.
|
|
func decode2i40_9bits(subNr, sign, index int16, cod []int16) {
|
|
var pos [2]int16
|
|
|
|
j := index & 64
|
|
j >>= 3
|
|
i := index & 7
|
|
k := shl(subNr, 1)
|
|
k += j
|
|
pos[0] = i*5 + startPos[k]
|
|
k++
|
|
|
|
index >>= 3
|
|
i = index & 7
|
|
pos[1] = i*5 + startPos[k]
|
|
|
|
for n := 0; n < cL_SUBFR; n++ {
|
|
cod[n] = 0
|
|
}
|
|
for j := 0; j < 2; j++ {
|
|
s := sign & 0x1
|
|
cod[pos[j]] = s*16383 - 8192
|
|
sign >>= 1
|
|
}
|
|
}
|
|
|
|
// decode2i40_11bits decodes the 2-pulse codebook for MR59. Mirrors
|
|
// decode_2i40_11bits (d2_11pf.cpp).
|
|
func decode2i40_11bits(sign, index int16, cod []int16) {
|
|
var pos [2]int16
|
|
|
|
j := index & 0x1
|
|
index >>= 1
|
|
i := index & 0x7
|
|
pos[0] = i*5 + j*2 + 1
|
|
|
|
index >>= 3
|
|
j = index & 0x3
|
|
index >>= 2
|
|
i = index & 0x7
|
|
if j == 3 {
|
|
pos[1] = i*5 + 4
|
|
} else {
|
|
pos[1] = i*5 + j
|
|
}
|
|
|
|
for n := 0; n < cL_SUBFR; n++ {
|
|
cod[n] = 0
|
|
}
|
|
for j := 0; j < 2; j++ {
|
|
s := sign & 1
|
|
cod[pos[j]] = s*16383 - 8192
|
|
sign >>= 1
|
|
}
|
|
}
|
|
|
|
// decode3i40_14bits decodes the 3-pulse codebook for MR67. Mirrors
|
|
// decode_3i40_14bits (d3_14pf.cpp).
|
|
func decode3i40_14bits(sign, index int16, cod []int16) {
|
|
var pos [3]int16
|
|
|
|
i := index & 0x7
|
|
pos[0] = i * 5
|
|
|
|
index >>= 3
|
|
j := index & 0x1
|
|
index >>= 1
|
|
i = index & 0x7
|
|
pos[1] = i*5 + j*2 + 1
|
|
|
|
index >>= 3
|
|
j = index & 0x1
|
|
index >>= 1
|
|
i = index & 0x7
|
|
pos[2] = i*5 + j*2 + 2
|
|
|
|
for n := 0; n < cL_SUBFR; n++ {
|
|
cod[n] = 0
|
|
}
|
|
for j := 0; j < 3; j++ {
|
|
s := sign & 1
|
|
cod[pos[j]] = s*16383 - 8192
|
|
sign >>= 1
|
|
}
|
|
}
|
|
|
|
// decode4i40_17bits decodes the 4-pulse Gray-coded codebook for MR74/MR795.
|
|
// Mirrors decode_4i40_17bits (d4_17pf.cpp).
|
|
func decode4i40_17bits(sign, index int16, cod []int16) {
|
|
var pos [4]int16
|
|
|
|
i := index & 0x7
|
|
i = dgray[i]
|
|
pos[0] = i * 5
|
|
|
|
index >>= 3
|
|
i = index & 0x7
|
|
i = dgray[i]
|
|
pos[1] = i*5 + 1
|
|
|
|
index >>= 3
|
|
i = index & 0x7
|
|
i = dgray[i]
|
|
pos[2] = i*5 + 2
|
|
|
|
index >>= 3
|
|
j := index & 0x1
|
|
index >>= 1
|
|
i = index & 0x7
|
|
i = dgray[i]
|
|
pos[3] = i*5 + 3 + j
|
|
|
|
for n := 0; n < cL_SUBFR; n++ {
|
|
cod[n] = 0
|
|
}
|
|
for j := 0; j < 4; j++ {
|
|
s := sign & 0x1
|
|
cod[pos[j]] = s*16383 - 8192
|
|
sign >>= 1
|
|
}
|
|
}
|
|
|
|
// decompress10 expands one compressed 10x10x10 track index into three pulse
|
|
// positions. Mirrors decompress10 (d8_31pf.cpp).
|
|
func decompress10(MSBs, LSBs, index1, index2, index3 int16, posIndx []int16) {
|
|
if MSBs > 124 {
|
|
MSBs = 124
|
|
}
|
|
ia := mult(MSBs, 1311)
|
|
ia = int16(int32(MSBs) - (L_mult(ia, 25) >> 1))
|
|
ib := mult(ia, 6554)
|
|
ib = ia - int16(L_mult(ib, 5)>>1)
|
|
ib = shl(ib, 1)
|
|
ic := LSBs - ((LSBs >> 2) << 2)
|
|
posIndx[index1] = ib + (ic & 1)
|
|
|
|
ib = mult(ia, 6554)
|
|
ib = shl(ib, 1)
|
|
posIndx[index2] = ib + (ic >> 1)
|
|
|
|
ib = LSBs >> 2
|
|
ic = mult(MSBs, 1311)
|
|
ic = shl(ic, 1)
|
|
posIndx[index3] = add(ib, ic)
|
|
}
|
|
|
|
// decompressCode expands the eight compressed MR102 pulse indices into linear
|
|
// signs and codeword positions. Mirrors decompress_code (d8_31pf.cpp).
|
|
func decompressCode(indx, signIndx, posIndx []int16) {
|
|
const nbTrack = 4
|
|
for i := 0; i < nbTrack; i++ {
|
|
signIndx[i] = indx[i]
|
|
}
|
|
|
|
MSBs := indx[nbTrack] >> 3
|
|
LSBs := indx[nbTrack] & 0x7
|
|
decompress10(MSBs, LSBs, 0, 4, 1, posIndx)
|
|
|
|
MSBs = indx[nbTrack+1] >> 3
|
|
LSBs = indx[nbTrack+1] & 0x7
|
|
decompress10(MSBs, LSBs, 2, 6, 5, posIndx)
|
|
|
|
MSBs = indx[nbTrack+2] >> 2
|
|
LSBs = indx[nbTrack+2] & 0x3
|
|
ia := int16(L_mult(MSBs, 25) >> 1)
|
|
ia += 12
|
|
MSBs0_24 := ia >> 5
|
|
|
|
ia = mult(MSBs0_24, 6554)
|
|
ia &= 1
|
|
ib := mult(MSBs0_24, 6554)
|
|
ib = MSBs0_24 - int16(L_mult(ib, 5)>>1)
|
|
if ia == 1 {
|
|
ib = 4 - ib
|
|
}
|
|
ib = shl(ib, 1)
|
|
ia = LSBs & 0x1
|
|
posIndx[3] = add(ib, ia)
|
|
|
|
ia = mult(MSBs0_24, 6554)
|
|
ia = shl(ia, 1)
|
|
posIndx[7] = ia + (LSBs >> 1)
|
|
}
|
|
|
|
// dec8i40_31bits decodes the 8-pulse codebook for MR102. Mirrors
|
|
// dec_8i40_31bits (d8_31pf.cpp).
|
|
func dec8i40_31bits(index, cod []int16) {
|
|
const nbTrack = 4
|
|
var linearSigns [nbTrack]int16
|
|
var linearCodewords [8]int16
|
|
|
|
for i := 0; i < cL_CODE; i++ {
|
|
cod[i] = 0
|
|
}
|
|
decompressCode(index, linearSigns[:], linearCodewords[:])
|
|
|
|
for j := int16(0); j < nbTrack; j++ {
|
|
pos1 := (linearCodewords[j] << 2) + j
|
|
var sign int16
|
|
if linearSigns[j] == 0 {
|
|
sign = cPOS_CODE // +1.0
|
|
} else {
|
|
sign = -cPOS_CODE // -1.0
|
|
}
|
|
if pos1 < cL_SUBFR {
|
|
cod[pos1] = sign
|
|
}
|
|
pos2 := (linearCodewords[j+4] << 2) + j
|
|
if pos2 < pos1 {
|
|
sign = negate(sign)
|
|
}
|
|
if pos2 < cL_SUBFR {
|
|
cod[pos2] += sign
|
|
}
|
|
}
|
|
}
|
|
|
|
// dec10i40_35bits decodes the 10-pulse Gray-coded codebook for MR122. Mirrors
|
|
// dec_10i40_35bits (d1035pf.cpp).
|
|
func dec10i40_35bits(index, cod []int16) {
|
|
const nbTrack = 5
|
|
for i := 0; i < cL_CODE; i++ {
|
|
cod[i] = 0
|
|
}
|
|
for j := int16(0); j < nbTrack; j++ {
|
|
tmp := index[j]
|
|
i := tmp & 7
|
|
i = dgray[i]
|
|
i = i * 5
|
|
pos1 := i + j
|
|
|
|
var sign int16
|
|
if (tmp>>3)&1 == 0 {
|
|
sign = 4096 // +1.0
|
|
} else {
|
|
sign = -4096 // -1.0
|
|
}
|
|
cod[pos1] = sign
|
|
|
|
i = index[j+5] & 7
|
|
i = dgray[i]
|
|
i = i * 5
|
|
pos2 := i + j
|
|
if pos2 < pos1 {
|
|
sign = negate(sign)
|
|
}
|
|
cod[pos2] += sign
|
|
}
|
|
}
|