51 lines
1.6 KiB
Go
51 lines
1.6 KiB
Go
package amrnb
|
|
|
|
// Decoder-side bit de-serialization, ported from opencore-amrnb bits2prm.cpp
|
|
// (Bin2int/Bits2prm) and the IETF->ETS reordering in wmf_to_ets.cpp (used for
|
|
// MIME_IETF input). The chain inverts the encoder side: IETF storage bytes ->
|
|
// ETS serial bits (unpacked MSB-first then inverse-permuted by reorderBits) ->
|
|
// parameter array (each parameter read MSB-first from its bitno width).
|
|
|
|
// bin2int reads nBits from bits[0:nBits], MSB first (bits[0] is the most
|
|
// significant bit), and returns the assembled value. Mirrors Bin2int.
|
|
func bin2int(nBits int, bits []int16) int16 {
|
|
var v int16
|
|
for i := 0; i < nBits; i++ {
|
|
v = (v << 1) | (bits[i] & 1)
|
|
}
|
|
return v
|
|
}
|
|
|
|
// ietfToEts unpacks the RFC 4867 speech payload bytes (IETF storage order,
|
|
// MSB-first) and inverse-permutes them via reorderBits[mode] into the ETS
|
|
// serial bit array. Mirrors the speech branch of wmf_to_ets.
|
|
func ietfToEts(mode Mode, data []byte) []int16 {
|
|
nb := modeBits[mode]
|
|
ro := reorderBits[mode]
|
|
ets := make([]int16, nb)
|
|
for i := 0; i < nb; i++ {
|
|
bit := (data[i>>3] >> uint(7-(i&7))) & 1
|
|
ets[ro[i]] = int16(bit)
|
|
}
|
|
return ets
|
|
}
|
|
|
|
// bits2prm reads the ETS serial bit array back into the mode's parameter array.
|
|
// Mirrors Bits2prm.
|
|
func bits2prm(mode Mode, ets []int16) []int16 {
|
|
bn := bitno[mode]
|
|
prm := make([]int16, len(bn))
|
|
pos := 0
|
|
for i, w := range bn {
|
|
prm[i] = bin2int(int(w), ets[pos:])
|
|
pos += int(w)
|
|
}
|
|
return prm
|
|
}
|
|
|
|
// mimeUnsort decodes the RFC 4867 speech payload bytes for the given mode into
|
|
// the decoder parameter array (the inverse of packFrame).
|
|
func mimeUnsort(data []byte, mode Mode) []int16 {
|
|
return bits2prm(mode, ietfToEts(mode, data))
|
|
}
|