Add unit tests for SILK Decoder
* TestDecodeStereoTODO * TestDecodeFrameType * TestDecodeSubframeQuantizations * TestNormalizeLineSpectralFrequencyStageOne * TestNormalizeLineSpectralFrequencyStageTwo * TestNormalizeLineSpectralFrequencyCoefficients
This commit is contained in:
parent
e1fb3069de
commit
15b20878e0
|
@ -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
|
||||
|
|
|
@ -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
|
||||
}
|
||||
|
|
|
@ -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()
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue