Add unit tests for SILK Decoder

* TestDecodeStereoTODO
* TestDecodeFrameType
* TestDecodeSubframeQuantizations
* TestNormalizeLineSpectralFrequencyStageOne
* TestNormalizeLineSpectralFrequencyStageTwo
* TestNormalizeLineSpectralFrequencyCoefficients
This commit is contained in:
Sean DuBois 2022-08-05 14:53:38 -04:00
parent e1fb3069de
commit 15b20878e0
3 changed files with 98 additions and 8 deletions

View file

@ -208,6 +208,14 @@ func (r *Decoder) update(scale, low, high, total uint32) {
r.normalize()
}
// SetInternalValues is used when using the RangeDecoder when testing
func (r *Decoder) SetInternalValues(data []byte, bitsRead uint, rangeSize uint32, highAndCodedDifference uint32) {
r.data = data
r.bitsRead = bitsRead
r.rangeSize = rangeSize
r.highAndCodedDifference = highAndCodedDifference
}
func min(a, b uint) uint {
if a < b {
return a

View file

@ -26,6 +26,17 @@ func NewDecoder() *Decoder {
return &Decoder{}
}
// The LP layer begins with two to eight header bits These consist of one
// Voice Activity Detection (VAD) bit per frame (up to 3), followed by a
// single flag indicating the presence of LBRR frames.
//
// https://datatracker.ietf.org/doc/html/rfc6716#section-4.2.3
func (d *Decoder) decodeHeaderBits() (voiceActivityDetected, lowBitRateRedundancy bool) {
voiceActivityDetected = d.rangeDecoder.DecodeSymbolLogP(1) == 1
lowBitRateRedundancy = d.rangeDecoder.DecodeSymbolLogP(1) == 1
return
}
// Each SILK frame contains a single "frame type" symbol that jointly
// codes the signal type and quantization offset type of the
// corresponding frame.
@ -503,12 +514,7 @@ func (d *Decoder) Decode(in []byte, isStereo bool, nanoseconds int, bandwidth Ba
d.rangeDecoder.Init(in)
//The LP layer begins with two to eight header bits These consist of one
// Voice Activity Detection (VAD) bit per frame (up to 3), followed by a
// single flag indicating the presence of LBRR frames.
// https://datatracker.ietf.org/doc/html/rfc6716#section-4.2.3
voiceActivityDetected := d.rangeDecoder.DecodeSymbolLogP(1) == 1
lowBitRateRedundancy := d.rangeDecoder.DecodeSymbolLogP(1) == 1
voiceActivityDetected, lowBitRateRedundancy := d.decodeHeaderBits()
if lowBitRateRedundancy {
return nil, errUnsupportedSilkLowBitrateRedundancy
}

View file

@ -1,14 +1,63 @@
package silk
import (
"errors"
"reflect"
"testing"
"github.com/pion/opus/internal/rangecoding"
)
func TestDecodeSubframeQuantizations(t *testing.T) {
func testSilkFrame() []byte {
return []byte{0x0B, 0xE4, 0xC1, 0x36, 0xEC, 0xC5, 0x80}
}
func testResQ10() []int16 {
return []int16{138, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}
}
func testNlsfQ1() []int16 {
return []int16{2132, 3584, 5504, 7424, 9472, 11392, 13440, 15360, 17280, 19200, 21120, 23040, 25088, 27008, 28928, 30848}
}
func createRangeDecoder(data []byte, bitsRead uint, rangeSize uint32, highAndCodedDifference uint32) rangecoding.Decoder {
d := rangecoding.Decoder{}
d.SetInternalValues(data, bitsRead, rangeSize, highAndCodedDifference)
return d
}
func TestDecode20MsOnly(t *testing.T) {
d := &Decoder{}
if _, err := d.Decode([]byte{0x0B, 0xE4, 0xC1, 0x36, 0xEC, 0xC5, 0x80}, false, nanoseconds20Ms, BandwidthNarrowband); err != nil {
_, err := d.Decode(testSilkFrame(), false, 1, BandwidthNarrowband)
if !errors.Is(err, errUnsupportedSilkFrameDuration) {
t.Fatal(err)
}
}
func TestDecodeStereoTODO(t *testing.T) {
d := &Decoder{}
_, err := d.Decode(testSilkFrame(), true, nanoseconds20Ms, BandwidthNarrowband)
if !errors.Is(err, errUnsupportedSilkStereo) {
t.Fatal(err)
}
}
func TestDecodeFrameType(t *testing.T) {
d := &Decoder{rangeDecoder: createRangeDecoder(testSilkFrame(), 31, 536870912, 437100388)}
signalType, quantizationOffsetType := d.determineFrameType(false)
if signalType != frameSignalTypeInactive {
t.Fatal()
}
if quantizationOffsetType != frameQuantizationOffsetTypeHigh {
t.Fatal()
}
}
func TestDecodeSubframeQuantizations(t *testing.T) {
d := &Decoder{rangeDecoder: createRangeDecoder(testSilkFrame(), 31, 482344960, 437100388)}
d.decodeSubframeQuantizations(frameSignalTypeInactive)
switch {
case d.subframeState[0].gain != 3.21875:
@ -21,3 +70,30 @@ func TestDecodeSubframeQuantizations(t *testing.T) {
t.Fatal()
}
}
func TestNormalizeLineSpectralFrequencyStageOne(t *testing.T) {
d := &Decoder{rangeDecoder: createRangeDecoder(testSilkFrame(), 47, 722810880, 387065757)}
I1 := d.normalizeLineSpectralFrequencyStageOne(false, BandwidthWideband)
if I1 != 9 {
t.Fatal()
}
}
func TestNormalizeLineSpectralFrequencyStageTwo(t *testing.T) {
d := &Decoder{rangeDecoder: createRangeDecoder(testSilkFrame(), 47, 50822640, 5895957)}
resQ10 := d.normalizeLineSpectralFrequencyStageTwo(BandwidthWideband, 9)
if !reflect.DeepEqual(resQ10, testResQ10()) {
t.Fatal()
}
}
func TestNormalizeLineSpectralFrequencyCoefficients(t *testing.T) {
d := &Decoder{rangeDecoder: createRangeDecoder(testSilkFrame(), 55, 493249168, 174371199)}
nlsfQ1 := d.normalizeLineSpectralFrequencyCoefficients(BandwidthWideband, testResQ10(), 9)
if !reflect.DeepEqual(nlsfQ1, testNlsfQ1()) {
t.Fatal()
}
}