Add test cases for all subframes

LPC unit test was only checking first run
This commit is contained in:
Sean DuBois 2022-09-13 15:59:05 -04:00
parent b9266e005e
commit 5d12791c86
4 changed files with 114 additions and 32 deletions

View file

@ -12,8 +12,10 @@ type Decoder struct {
}
// NewDecoder creates a new Opus Decoder
func NewDecoder() *Decoder {
return &Decoder{}
func NewDecoder() Decoder {
return Decoder{
silkDecoder: silk.NewDecoder(),
}
}
// Decode decodes the Opus bitstream into PCM

View file

@ -12,7 +12,7 @@ import (
)
func main() {
decoder := &opus.Decoder{}
decoder := opus.NewDecoder()
homeDir, err := os.UserHomeDir()
if err != nil {

View file

@ -17,14 +17,24 @@ type Decoder struct {
previousLogGain uint32
// The decoder saves the final d_LPC values, i.e., lpc[i] such that
// (j + n - d_LPC) <= i < (j + n), to feed into the LPC synthesis of the
// next subframe. This requires storage for up to 16 values of lpc[i]
// (for WB frames).
//
// https://www.rfc-editor.org/rfc/rfc6716.html#section-4.2.7.9.2
finalLPCValues []float64
// n0Q15 are the LSF coefficients decoded for the prior frame
// see normalizeLSFInterpolation
n0Q15 []int16
}
// NewDecoder creates a new Silk Decoder
func NewDecoder() *Decoder {
return &Decoder{}
func NewDecoder() Decoder {
return Decoder{
finalLPCValues: make([]float64, 16),
}
}
// The LP layer begins with two to eight header bits These consist of one
@ -1353,6 +1363,8 @@ func (d *Decoder) ltpSynthesis(signalType frameSignalType, eQ23 []int32) (res []
//
// https://www.rfc-editor.org/rfc/rfc6716.html#section-4.2.7.9.2
func (d *Decoder) lpcSynthesis(out []float64, bandwidth Bandwidth, dLPC int, aQ12, res, gainQ16 []float64) {
finalLPCValuesIndex := 0
// let n be the number of samples in a subframe
n := d.samplesInSubframe(bandwidth)
@ -1373,13 +1385,19 @@ func (d *Decoder) lpcSynthesis(out []float64, bandwidth Bandwidth, dLPC int, aQ1
// 65536.0 /_ 4096.0
// k=0
//
var currentLPCVal float64
for i := j; i < (j + n); i++ {
lpcVal := gainQ16[0] / 65536.0
lpcVal *= res[i]
for k := 0; k < dLPC; k++ {
if i-k > 0 {
lpcVal += lpc[i-k-1] * (aQ12[k] / 4096.0)
currentLPCVal = lpc[i-k-1]
} else {
currentLPCVal = d.finalLPCValues[len(d.finalLPCValues)-1+(i-k)]
}
lpcVal += currentLPCVal * (aQ12[k] / 4096.0)
}
lpc[i] = lpcVal
@ -1388,6 +1406,10 @@ func (d *Decoder) lpcSynthesis(out []float64, bandwidth Bandwidth, dLPC int, aQ1
// (j + n - d_LPC) <= i < (j + n), to feed into the LPC synthesis of the
// next subframe. This requires storage for up to 16 values of lpc[i]
// (for WB frames).
if (j+n-dLPC) <= i && i < (j+n) {
d.finalLPCValues[finalLPCValuesIndex] = lpcVal
finalLPCValuesIndex++
}
// Then, the signal is clamped into the final nominal range:
//

View file

@ -212,7 +212,7 @@ func TestLimitLPCFilterPredictionGain(t *testing.T) {
}
func TestLPCSynthesis(t *testing.T) {
d := &Decoder{}
d := NewDecoder()
bandwidth := BandwidthWideband
dLPC := 16
@ -220,6 +220,7 @@ func TestLPCSynthesis(t *testing.T) {
405, 305, 131, 114, -118, -138, -72, -146, -108, -120,
-140, -50, -61, -97, -67, -91,
}
res := []float64{
7.152557373046875e-06, 7.152557373046875e-06, 7.152557373046875e-06, -7.152557373046875e-06, 7.152557373046875e-06,
-7.152557373046875e-06, 7.152557373046875e-06, -7.152557373046875e-06, 7.152557373046875e-06, 7.152557373046875e-06,
@ -286,37 +287,94 @@ func TestLPCSynthesis(t *testing.T) {
7.152557373046875e-06, -7.152557373046875e-06, -7.152557373046875e-06, 7.152557373046875e-06, -7.152557373046875e-06,
-7.152557373046875e-06, -7.152557373046875e-06, 7.152557373046875e-06, 7.152557373046875e-06, 7.152557373046875e-06,
}
gainQ16 := []float64{
210944, 112640, 96256, 96256,
}
expectedOut := []float64{
2.302229404449463e-05, 2.529866833356209e-05, 2.7238055850808962e-05, -1.7708957379176547e-05,
2.4749380560290345e-05, -2.0981798454772844e-05, 2.1477830715765397e-05, -2.4204054632453483e-05,
2.0573308751838655e-05, 2.1253221788382786e-05, -2.1795743617147622e-05, -2.5572395890179134e-05,
1.8106643964895232e-05, 2.1679570267935762e-05, -2.3421448312108795e-05, -2.5406199017389676e-05,
-2.6599602275986916e-05, 1.7052067576811296e-05, 2.0067949408694348e-05, -2.1078623688906863e-05,
2.271243480683997e-05, 2.72150166867741e-05, -1.7916321594691292e-05, -2.270884152381766e-05,
-2.4033412923016192e-05, 2.0436563417128885e-05, -2.427532508544255e-05, 2.099238635148557e-05,
2.3130783534808538e-05, 2.749115150529425e-05, 2.9121850985151823e-05, -1.6076042144548942e-05,
-2.0142893098101348e-05, -2.5156895229144312e-05, 1.8372226407770105e-05, -2.6231528245909858e-05,
-2.7873633118355813e-05, -2.827462776329132e-05, -2.8362645350449658e-05, 1.5891388432233637e-05,
-2.5135526747850188e-05, -2.4985248615337324e-05, 2.064507848100911e-05, 2.5244048336741552e-05,
2.739063247080468e-05, -1.59980955341928e-05, 2.986235454333743e-05, -1.5701907849066896e-05,
-1.9655022837758317e-05, -2.3930568720535936e-05, -2.5864346366616522e-05, 1.8898232022390776e-05,
2.181083873255081e-05, 2.5461110645823852e-05, -1.8590886796307292e-05, -2.050522154748354e-05,
-2.3710687868596256e-05, -2.7372444700744424e-05, -2.944923186846253e-05, -2.950886965229287e-05,
1.686553027485115e-05, 2.2160990035467353e-05, 2.6091190985943028e-05, 3.0279020155065333e-05,
3.3413790911176856e-05, -1.2277945607991174e-05, -1.797789733287015e-05, -2.3009254117084007e-05,
-2.6130379141626882e-05, -2.9129650057967384e-05, -2.9311587554258764e-05, 1.6120577972288713e-05,
-2.5391204288454823e-05, 2.0852605782226922e-05, 2.4056945286107526e-05, 2.8484019080176072e-05,
-1.714856704971997e-05, 2.653301837863552e-05, 2.7821685893519827e-05, 2.860888470653348e-05,
expectedOut := [][]float64{
{
0.000023, 0.000025, 0.000027, -0.000018, 0.000025,
-0.000021, 0.000021, -0.000024, 0.000021, 0.000021,
-0.000022, -0.000026, 0.000018, 0.000022, -0.000023,
-0.000025, -0.000027, 0.000017, 0.000020, -0.000021,
0.000023, 0.000027, -0.000018, -0.000023, -0.000024,
0.000020, -0.000024, 0.000021, 0.000023, 0.000027,
0.000029, -0.000016, -0.000020, -0.000025, 0.000018,
-0.000026, -0.000028, -0.000028, -0.000028, 0.000016,
-0.000025, -0.000025, 0.000021, 0.000025, 0.000027,
-0.000016, 0.000030, -0.000016, -0.000020, -0.000024,
-0.000026, 0.000019, 0.000022, 0.000025, -0.000019,
-0.000021, -0.000024, -0.000027, -0.000029, -0.000030,
0.000017, 0.000022, 0.000026, 0.000030, 0.000033,
-0.000012, -0.000018, -0.000023, -0.000026, -0.000029,
-0.000029, 0.000016, -0.000025, 0.000021, 0.000024,
0.000028, -0.000017, 0.000027, 0.000028, 0.000029,
},
{
-0.000006, 0.000017, 0.000015, 0.000015, -0.000011,
0.000011, 0.000011, -0.000014, 0.000008, -0.000016,
0.000008, -0.000016, -0.000016, -0.000018, -0.000017,
-0.000017, 0.000008, -0.000014, -0.000013, -0.000013,
-0.000012, 0.000011, -0.000010, 0.000015, 0.000016,
-0.000006, 0.000015, -0.000008, -0.000009, -0.000012,
0.000012, 0.000012, 0.000013, -0.000009, -0.000011,
0.000011, 0.000012, -0.000012, 0.000012, 0.000013,
0.000014, -0.000011, 0.000013, -0.000011, -0.000013,
-0.000016, 0.000008, -0.000015, 0.000010, -0.000013,
-0.000013, -0.000015, 0.000010, -0.000013, 0.000011,
-0.000011, -0.000011, -0.000013, 0.000012, -0.000011,
0.000013, 0.000015, 0.000016, 0.000016, 0.000017,
-0.000007, -0.000010, -0.000013, -0.000015, -0.000017,
0.000007, -0.000015, -0.000015, 0.000009, 0.000012,
-0.000011, 0.000012, -0.000010, 0.000013, -0.000011,
},
{
0.000012, 0.000012, 0.000014, 0.000014, -0.000007,
0.000012, -0.000010, 0.000010, 0.000010, 0.000011,
-0.000010, 0.000009, -0.000011, 0.000008, 0.000009,
-0.000010, -0.000013, -0.000013, -0.000014, 0.000006,
0.000009, -0.000010, -0.000011, -0.000011, -0.000012,
0.000008, 0.000011, 0.000013, -0.000007, -0.000008,
-0.000010, -0.000011, 0.000009, -0.000010, -0.000011,
0.000009, -0.000010, -0.000011, 0.000010, 0.000012,
-0.000009, -0.000010, -0.000010, -0.000012, 0.000009,
0.000011, 0.000012, 0.000014, -0.000007, 0.000012,
-0.000009, 0.000011, -0.000010, 0.000010, -0.000011,
-0.000012, -0.000013, -0.000013, -0.000014, 0.000007,
-0.000012, 0.000009, -0.000010, -0.000010, -0.000011,
0.000010, 0.000012, 0.000013, -0.000006, 0.000013,
-0.000007, -0.000009, 0.000010, -0.000010, -0.000011,
0.000008, -0.000010, -0.000012, -0.000012, 0.000009,
},
{
0.000009, 0.000011, 0.000013, 0.000014, 0.000015,
0.000014, -0.000007, 0.000012, 0.000011, 0.000012,
-0.000010, -0.000012, 0.000008, 0.000008, 0.000009,
0.000009, -0.000010, -0.000012, -0.000014, -0.000014,
0.000006, 0.000008, -0.000010, -0.000012, 0.000010,
-0.000010, 0.000010, 0.000012, 0.000013, -0.000008,
-0.000009, -0.000010, 0.000009, -0.000010, -0.000011,
0.000008, -0.000011, -0.000012, -0.000012, -0.000012,
-0.000013, 0.000008, -0.000011, -0.000011, 0.000010,
0.000013, -0.000007, -0.000008, -0.000009, -0.000010,
0.000009, 0.000011, 0.000013, -0.000007, 0.000013,
-0.000008, 0.000011, -0.000010, 0.000011, 0.000011,
0.000012, 0.000012, 0.000013, -0.000008, 0.000010,
-0.000011, 0.000009, -0.000012, -0.000013, -0.000014,
0.000006, -0.000013, -0.000013, 0.000008, -0.000011,
-0.000012, -0.000012, 0.000010, 0.000011, 0.000013,
},
}
out := make([]float64, 80)
d.lpcSynthesis(out, bandwidth, dLPC, aQ12, res, gainQ16)
if !reflect.DeepEqual(out, expectedOut) {
t.Fatal()
for i := range expectedOut {
out := make([]float64, 80)
d.lpcSynthesis(out, bandwidth, dLPC, aQ12, res, gainQ16)
for j := range out {
if out[j]-expectedOut[i][j] > 0.0001 {
t.Fatalf("%d (%f) != (%f)", j, out[j], expectedOut[i][j])
}
}
}
}