Implement decoding LTP Filter Coefficients

section-4.2.7.6.2
This commit is contained in:
Sean DuBois 2022-09-12 17:14:13 -04:00
parent 1dcc971611
commit 2067ca5ac0
4 changed files with 287 additions and 8 deletions

View file

@ -1034,4 +1034,195 @@ var (
{8, 3, -2, -7},
{-9, -3, 3, 9},
}
// +-------+---------------------+
// | Index | Filter Taps (Q7) |
// +-------+---------------------+
// | 0 | 4 6 24 7 5 |
// | | |
// | 1 | 0 0 2 0 0 |
// | | |
// | 2 | 12 28 41 13 -4 |
// | | |
// | 3 | -9 15 42 25 14 |
// | | |
// | 4 | 1 -2 62 41 -9 |
// | | |
// | 5 | -10 37 65 -4 3 |
// | | |
// | 6 | -6 4 66 7 -8 |
// | | |
// | 7 | 16 14 38 -3 33 |
// +-------+---------------------+
//
// Table 39: Codebook Vectors for LTP Filter, Periodicity Index 0
codebookLTPFilterPeriodicityIndex0 = [][]int8{
{4, 6, 24, 7, 5},
{0, 0, 2, 0, 0},
{12, 28, 41, 13, -4},
{-9, 15, 42, 25, 14},
{1, -2, 62, 41, -9},
{-10, 37, 65, -4, 3},
{-6, 4, 66, 7, -8},
{16, 14, 38, -3, 33},
}
// +-------+---------------------+
// | Index | Filter Taps (Q7) |
// +-------+---------------------+
// | 0 | 13 22 39 23 12 |
// | | |
// | 1 | -1 36 64 27 -6 |
// | | |
// | 2 | -7 10 55 43 17 |
// | | |
// | 3 | 1 1 8 1 1 |
// | | |
// | 4 | 6 -11 74 53 -9 |
// | | |
// | 5 | -12 55 76 -12 8 |
// | | |
// | 6 | -3 3 93 27 -4 |
// | | |
// | 7 | 26 39 59 3 -8 |
// | | |
// | 8 | 2 0 77 11 9 |
// | | |
// | 9 | -8 22 44 -6 7 |
// | | |
// | 10 | 40 9 26 3 9 |
// | | |
// | 11 | -7 20 101 -7 4 |
// | | |
// | 12 | 3 -8 42 26 0 |
// | | |
// | 13 | -15 33 68 2 23 |
// | | |
// | 14 | -2 55 46 -2 15 |
// | | |
// | 15 | 3 -1 21 16 41 |
// +-------+---------------------+
//
// Table 40: Codebook Vectors for LTP Filter, Periodicity Index 1
codebookLTPFilterPeriodicityIndex1 = [][]int8{
{13, 22, 39, 23, 12},
{-1, 36, 64, 27, -6},
{-7, 10, 55, 43, 17},
{1, 1, 8, 1, 1},
{6, -11, 74, 53, -9},
{-12, 55, 76, -12, 8},
{-3, 3, 93, 27, -4},
{26, 39, 59, 3, -8},
{2, 0, 77, 11, 9},
{-8, 22, 44, -6, 7},
{40, 9, 26, 3, 9},
{-7, 20, 101, -7, 4},
{3, -8, 42, 26, 0},
{-15, 33, 68, 2, 23},
{-2, 55, 46, -2, 15},
{3, -1, 21, 16, 41},
}
// +-------+---------------------+
// | Index | Filter Taps (Q7) |
// +-------+---------------------+
// | 0 | -6 27 61 39 5 |
// | | |
// | 1 | -11 42 88 4 1 |
// | | |
// | 2 | -2 60 65 6 -4 |
// | | |
// | 3 | -1 -5 73 56 1 |
// | 4 | -9 19 94 29 -9 |
// | | |
// | 5 | 0 12 99 6 4 |
// | | |
// | 6 | 8 -19 102 46 -13 |
// | | |
// | 7 | 3 2 13 3 2 |
// | | |
// | 8 | 9 -21 84 72 -18 |
// | | |
// | 9 | -11 46 104 -22 8 |
// | | |
// | 10 | 18 38 48 23 0 |
// | | |
// | 11 | -16 70 83 -21 11 |
// | | |
// | 12 | 5 -11 117 22 -8 |
// | | |
// | 13 | -6 23 117 -12 3 |
// | | |
// | 14 | 3 -8 95 28 4 |
// | | |
// | 15 | -10 15 77 60 -15 |
// | | |
// | 16 | -1 4 124 2 -4 |
// | | |
// | 17 | 3 38 84 24 -25 |
// | | |
// | 18 | 2 13 42 13 31 |
// | | |
// | 19 | 21 -4 56 46 -1 |
// | | |
// | 20 | -1 35 79 -13 19 |
// | | |
// | 21 | -7 65 88 -9 -14 |
// | | |
// | 22 | 20 4 81 49 -29 |
// | | |
// | 23 | 20 0 75 3 -17 |
// | | |
// | 24 | 5 -9 44 92 -8 |
// | | |
// | 25 | 1 -3 22 69 31 |
// | | |
// | 26 | -6 95 41 -12 5 |
// | | |
// | 27 | 39 67 16 -4 1 |
// | | |
// | 28 | 0 -6 120 55 -36 |
// | | |
// | 29 | -13 44 122 4 -24 |
// | | |
// | 30 | 81 5 11 3 7 |
// | | |
// | 31 | 2 0 9 10 88 |
// +-------+---------------------+
//
// Table 41: Codebook Vectors for LTP Filter, Periodicity Index 2
codebookLTPFilterPeriodicityIndex2 = [][]int8{
{-6, 27, 61, 39, 5},
{-11, 42, 88, 4, 1},
{-2, 60, 65, 6, -4},
{-1, -5, 73, 56, 1},
{-9, 19, 94, 29, -9},
{0, 12, 99, 6, 4},
{8, -19, 102, 46, -13},
{3, 2, 13, 3, 2},
{9, -21, 84, 72, -18},
{-11, 46, 104, -22, 8},
{18, 38, 48, 23, 0},
{-16, 70, 83, -21, 11},
{5, -11, 117, 22, -8},
{-6, 23, 117, -12, 3},
{3, -8, 95, 28, 4},
{-10, 15, 77, 60, -15},
{-1, 4, 124, 2, -4},
{3, 38, 84, 24, -25},
{2, 13, 42, 13, 31},
{21, -4, 56, 46, -1},
{-1, 35, 79, -13, 19},
{-7, 65, 88, -9, -14},
{20, 4, 81, 49, -29},
{20, 0, 75, 3, -17},
{5, -9, 44, 92, -8},
{1, -3, 22, 69, 31},
{-6, 95, 41, -12, 5},
{39, 67, 16, -4, 1},
{0, -6, 120, 55, -36},
{-13, 44, 122, 4, -24},
{81, 5, 11, 3, 7},
{2, 0, 9, 10, 88},
}
)

View file

@ -1253,13 +1253,47 @@ func (d *Decoder) decodeLTPScalingParamater(signalType frameSignalType) (float64
// from one of three codebooks.
//
// https://www.rfc-editor.org/rfc/rfc6716.html#section-4.2.7.6.2
func (d *Decoder) decodeLTPFilterCoefficients(signalType frameSignalType) error {
if signalType == frameSignalTypeVoiced {
return errUnsupportedVoicedFrames
func (d *Decoder) decodeLTPFilterCoefficients(signalType frameSignalType) (bQ7 []int8) {
if signalType != frameSignalTypeVoiced {
return
}
// TODO
return nil
bQ7 = make([]int8, 5)
// This is signaled with an explicitly-coded "periodicity index". This
// immediately follows the subframe pitch lags, and is coded using the
// 3-entry PDF from Table 37.
periodicityIndex := d.rangeDecoder.DecodeSymbolWithICDF(icdfPeriodicityIndex)
// The indices of the filters for each subframe follow. They are all
// coded using the PDF from Table 38 corresponding to the periodicity
// index. Tables 39 through 41 contain the corresponding filter taps as
// signed Q7 integers.
var filterIndiceIcdf []uint
switch periodicityIndex {
case 0:
filterIndiceIcdf = icdfLTPFilterIndex0
case 1:
filterIndiceIcdf = icdfLTPFilterIndex1
case 2:
filterIndiceIcdf = icdfLTPFilterIndex2
}
filterIndex := d.rangeDecoder.DecodeSymbolWithICDF(filterIndiceIcdf)
var LTPFilterCodebook [][]int8
switch periodicityIndex {
case 0:
LTPFilterCodebook = codebookLTPFilterPeriodicityIndex0
case 1:
LTPFilterCodebook = codebookLTPFilterPeriodicityIndex1
case 2:
LTPFilterCodebook = codebookLTPFilterPeriodicityIndex2
}
copy(bQ7, LTPFilterCodebook[filterIndex])
return
}
// let n be the number of samples in a subframe (40 for NB, 60 for
@ -1293,8 +1327,11 @@ func (d *Decoder) ltpSynthesis(signalType frameSignalType, eQ23 []int32) (res []
for i := range eQ23 {
res[i] = float64(eQ23[i]) / 8388608
}
return
}
// TODO
return
}
@ -1430,9 +1467,7 @@ func (d *Decoder) Decode(in []byte, out []float64, isStereo bool, nanoseconds in
d.decodePitchLags(signalType, bandwidth)
// https://www.rfc-editor.org/rfc/rfc6716.html#section-4.2.7.6.2
if err := d.decodeLTPFilterCoefficients(signalType); err != nil {
return err
}
d.decodeLTPFilterCoefficients(signalType)
// https://www.rfc-editor.org/rfc/rfc6716.html#section-4.2.7.6.3
_, err := d.decodeLTPScalingParamater(signalType)

View file

@ -333,3 +333,13 @@ func TestDecodePitchLags(t *testing.T) {
t.Fatal()
}
}
func TestDecodeLTPFilterCoefficients(t *testing.T) {
silkFrame := []byte{0xb4, 0xe2, 0x2c, 0xe, 0x10, 0x65, 0x1d, 0xa9, 0x7, 0x5c, 0x36, 0x8f, 0x96, 0x7b, 0xf4, 0x89, 0x41, 0x55, 0x98, 0x7a, 0x39, 0x2e, 0x6b, 0x71, 0xa4, 0x3, 0x70, 0xbf}
d := &Decoder{rangeDecoder: createRangeDecoder(silkFrame, 89, 253853952, 138203876)}
bQ7 := d.decodeLTPFilterCoefficients(frameSignalTypeVoiced)
if !reflect.DeepEqual(bQ7, []int8{1, 1, 8, 1, 1}) {
t.Fatal()
}
}

View file

@ -711,4 +711,47 @@ var (
186, 194, 200, 206, 212, 217, 221, 225, 229, 232, 235, 238,
240, 242, 244, 246, 248, 250, 252, 253, 254, 255, 256,
}
// +------------------+
// | PDF |
// +------------------+
// | {77, 80, 99}/256 |
// +------------------+
//
// Table 37: Periodicity Index PDF
//
// https://www.rfc-editor.org/rfc/rfc6716.html#section-4.2.7.6.2
icdfPeriodicityIndex = []uint{
256, 77, 157, 256,
}
// +-------------+----------+------------------------------------------+
// | Periodicity | Codebook | PDF |
// | Index | Size | |
// +-------------+----------+------------------------------------------+
// | 0 | 8 | {185, 15, 13, 13, 9, 9, 6, 6}/256 |
// | | | |
// | 1 | 16 | {57, 34, 21, 20, 15, 13, 12, 13, 10, 10, |
// | | | 9, 10, 9, 8, 7, 8}/256 |
// | | | |
// | 2 | 32 | {15, 16, 14, 12, 12, 12, 11, 11, 11, 10, |
// | | | 9, 9, 9, 9, 8, 8, 8, 8, 7, 7, 6, 6, 5, |
// | | | 4, 5, 4, 4, 4, 3, 4, 3, 2}/256 |
// +-------------+----------+------------------------------------------+
//
// Table 38: LTP Filter PDFs
//
// https://www.rfc-editor.org/rfc/rfc6716.html#section-4.2.7.6.2
icdfLTPFilterIndex0 = []uint{
256, 185, 200, 213, 226, 235, 244, 250, 256,
}
icdfLTPFilterIndex1 = []uint{
256, 57, 91, 112, 132, 147, 160, 172, 185,
195, 205, 214, 224, 233, 241, 248, 256,
}
icdfLTPFilterIndex2 = []uint{
256, 15, 31, 45, 57, 69, 81, 92, 103, 114, 124,
133, 142, 151, 160, 168, 176, 184, 192, 199, 206, 212,
218, 223, 227, 232, 236, 240, 244, 247, 251, 254, 256,
}
)