diff --git a/.golangci.yml b/.golangci.yml index a3235be..88cb4fb 100644 --- a/.golangci.yml +++ b/.golangci.yml @@ -25,17 +25,32 @@ linters-settings: - ^os.Exit$ - ^panic$ - ^print(ln)?$ + varnamelen: + max-distance: 12 + min-name-length: 2 + ignore-type-assert-ok: true + ignore-map-index-ok: true + ignore-chan-recv-ok: true + ignore-decls: + - i int + - n int + - w io.Writer + - r io.Reader + - b []byte linters: enable: - asciicheck # Simple linter to check that your code does not contain non-ASCII identifiers - bidichk # Checks for dangerous unicode character sequences - bodyclose # checks whether HTTP response body is closed successfully + - containedctx # containedctx is a linter that detects struct contained context.Context field - contextcheck # check the function whether use a non-inherited context + - cyclop # checks function and package cyclomatic complexity - decorder # check declaration order and count of types, constants, variables and functions - dogsled # Checks assignments with too many blank identifiers (e.g. x, _, _, _, := f()) - dupl # Tool for code clone detection - durationcheck # check for two durations multiplied together + - err113 # Golang linter to check the errors handling expressions - errcheck # Errcheck is a program for checking for unchecked errors in go programs. These unchecked errors can be critical bugs in some cases - errchkjson # Checks types passed to the json encoding functions. Reports unsupported types and optionally reports occations, where the check for the returned error can be omitted. - errname # Checks that sentinel errors are prefixed with the `Err` and error types are suffixed with the `Error`. @@ -46,18 +61,17 @@ linters: - forcetypeassert # finds forced type assertions - gci # Gci control golang package import order and make it always deterministic. - gochecknoglobals # Checks that no globals are present in Go code - - gochecknoinits # Checks that no init functions are present in Go code - gocognit # Computes and checks the cognitive complexity of functions - goconst # Finds repeated strings that could be replaced by a constant - gocritic # The most opinionated Go source code linter + - gocyclo # Computes and checks the cyclomatic complexity of functions + - godot # Check if comments end in a period - godox # Tool for detection of FIXME, TODO and other comment keywords - - err113 # Golang linter to check the errors handling expressions - gofmt # Gofmt checks whether code was gofmt-ed. By default this tool runs with -s option to check for code simplification - gofumpt # Gofumpt checks whether code was gofumpt-ed. - goheader # Checks is file header matches to pattern - goimports # Goimports does everything that gofmt does. Additionally it checks unused imports - gomoddirectives # Manage the use of 'replace', 'retract', and 'excludes' directives in go.mod. - - gomodguard # Allow and block list linter for direct Go module dependencies. This is different from depguard where there are different block types for example version constraints and module recommendations. - goprintffuncname # Checks that printf-like functions are named with `f` at the end - gosec # Inspects source code for security problems - gosimple # Linter for Go source code that specializes in simplifying a code @@ -65,9 +79,15 @@ linters: - grouper # An analyzer to analyze expression groups. - importas # Enforces consistent import aliases - ineffassign # Detects when assignments to existing variables are not used + - lll # Reports long lines + - maintidx # maintidx measures the maintainability index of each function. + - makezero # Finds slice declarations with non-zero initial length - misspell # Finds commonly misspelled English words in comments + - nakedret # Finds naked returns in functions greater than a specified function length + - nestif # Reports deeply nested if statements - nilerr # Finds the code that returns nil even if it checks that the error is not nil. - nilnil # Checks that there is no simultaneous return of `nil` error and an invalid value. + - nlreturn # nlreturn checks for a new line before return and branch statements to increase code clarity - noctx # noctx finds sending http request without context.Context - predeclared # find code that shadows one of Go's predeclared identifiers - revive # golint replacement, finds style mistakes @@ -75,28 +95,22 @@ linters: - stylecheck # Stylecheck is a replacement for golint - tagliatelle # Checks the struct tags. - tenv # tenv is analyzer that detects using os.Setenv instead of t.Setenv since Go1.17 - - tparallel # tparallel detects inappropriate usage of t.Parallel() method in your Go test codes + - thelper # thelper detects golang test helpers without t.Helper() call and checks the consistency of test helpers - typecheck # Like the front-end of a Go compiler, parses and type-checks Go code - unconvert # Remove unnecessary type conversions - unparam # Reports unused function parameters - unused # Checks Go code for unused constants, variables, functions and types + - varnamelen # checks that the length of a variable's name matches its scope - wastedassign # wastedassign finds wasted assignment statements - whitespace # Tool for detection of leading and trailing whitespace disable: - depguard # Go linter that checks if package imports are in a list of acceptable packages - - containedctx # containedctx is a linter that detects struct contained context.Context field - - cyclop # checks function and package cyclomatic complexity - funlen # Tool for detection of long functions - - gocyclo # Computes and checks the cyclomatic complexity of functions - - godot # Check if comments end in a period - - gomnd # An analyzer to detect magic numbers. + - gochecknoinits # Checks that no init functions are present in Go code + - gomodguard # Allow and block list linter for direct Go module dependencies. This is different from depguard where there are different block types for example version constraints and module recommendations. + - interfacebloat # A linter that checks length of interface. - ireturn # Accept Interfaces, Return Concrete Types - - lll # Reports long lines - - maintidx # maintidx measures the maintainability index of each function. - - makezero # Finds slice declarations with non-zero initial length - - nakedret # Finds naked returns in functions greater than a specified function length - - nestif # Reports deeply nested if statements - - nlreturn # nlreturn checks for a new line before return and branch statements to increase code clarity + - mnd # An analyzer to detect magic numbers - nolintlint # Reports ill-formed or insufficient nolint directives - paralleltest # paralleltest detects missing usage of t.Parallel() method in your Go test - prealloc # Finds slice declarations that could potentially be preallocated @@ -104,8 +118,7 @@ linters: - rowserrcheck # checks whether Err of rows is checked successfully - sqlclosecheck # Checks that sql.Rows and sql.Stmt are closed. - testpackage # linter that makes you use a separate _test package - - thelper # thelper detects golang test helpers without t.Helper() call and checks the consistency of test helpers - - varnamelen # checks that the length of a variable's name matches its scope + - tparallel # tparallel detects inappropriate usage of t.Parallel() method in your Go test codes - wrapcheck # Checks that errors returned from external packages are wrapped - wsl # Whitespace Linter - Forces you to use empty lines! diff --git a/decoder.go b/decoder.go index daa6173..60e2ad0 100644 --- a/decoder.go +++ b/decoder.go @@ -12,13 +12,13 @@ import ( "github.com/pion/opus/internal/silk" ) -// Decoder decodes the Opus bitstream into PCM +// Decoder decodes the Opus bitstream into PCM. type Decoder struct { silkDecoder silk.Decoder silkBuffer []float32 } -// NewDecoder creates a new Opus Decoder +// NewDecoder creates a new Opus Decoder. func NewDecoder() Decoder { return Decoder{ silkDecoder: silk.NewDecoder(), @@ -47,7 +47,13 @@ func (d *Decoder) decode(in []byte, out []float32) (bandwidth Bandwidth, isStere } for _, encodedFrame := range encodedFrames { - err := d.silkDecoder.Decode(encodedFrame, out, tocHeader.isStereo(), cfg.frameDuration().nanoseconds(), silk.Bandwidth(cfg.bandwidth())) + err := d.silkDecoder.Decode( + encodedFrame, + out, + tocHeader.isStereo(), + cfg.frameDuration().nanoseconds(), + silk.Bandwidth(cfg.bandwidth()), + ) if err != nil { return 0, false, err } @@ -56,7 +62,7 @@ func (d *Decoder) decode(in []byte, out []float32) (bandwidth Bandwidth, isStere return cfg.bandwidth(), tocHeader.isStereo(), nil } -// Decode decodes the Opus bitstream into S16LE PCM +// Decode decodes the Opus bitstream into S16LE PCM. func (d *Decoder) Decode(in, out []byte) (bandwidth Bandwidth, isStereo bool, err error) { bandwidth, isStereo, err = d.decode(in, d.silkBuffer) if err != nil { @@ -64,10 +70,11 @@ func (d *Decoder) Decode(in, out []byte) (bandwidth Bandwidth, isStereo bool, er } err = bitdepth.ConvertFloat32LittleEndianToSigned16LittleEndian(d.silkBuffer, out, 3) + return } -// DecodeFloat32 decodes the Opus bitstream into F32LE PCM +// DecodeFloat32 decodes the Opus bitstream into F32LE PCM. func (d *Decoder) DecodeFloat32(in []byte, out []float32) (bandwidth Bandwidth, isStereo bool, err error) { bandwidth, isStereo, err = d.decode(in, d.silkBuffer) if err != nil { @@ -75,5 +82,6 @@ func (d *Decoder) DecodeFloat32(in []byte, out []float32) (bandwidth Bandwidth, } resample.Up(d.silkBuffer, out, 3) + return } diff --git a/decoder_test.go b/decoder_test.go index b3487ca..b8abcd1 100644 --- a/decoder_test.go +++ b/decoder_test.go @@ -27,6 +27,8 @@ var ( ) func loadTestOgg(tb testing.TB) []byte { + tb.Helper() + if *testoggfile == "" { tb.Skip("-oggfile not specified") } @@ -37,6 +39,7 @@ func loadTestOgg(tb testing.TB) []byte { if _testogg.err != nil { tb.Fatal("unable to load -oggfile", _testogg.err) } + return _testogg.data } @@ -49,6 +52,8 @@ func BenchmarkDecode(b *testing.B) { } func benchmarkData(b *testing.B, data []byte) { + b.Helper() + var out [1920]byte ogg, _, err := oggreader.NewWith(bytes.NewReader(data)) if err != nil { diff --git a/examples/decode/main.go b/examples/decode/main.go index e8f67f9..d83ca08 100644 --- a/examples/decode/main.go +++ b/examples/decode/main.go @@ -14,7 +14,7 @@ import ( "github.com/pion/opus/pkg/oggreader" ) -func main() { +func main() { // nolint:cyclop if len(os.Args) != 3 { panic("Usage: ") } @@ -30,7 +30,7 @@ func main() { } out := make([]byte, 1920) - f, err := os.Create(os.Args[2]) + fd, err := os.Create(os.Args[2]) if err != nil { panic(err) } @@ -54,7 +54,7 @@ func main() { panic(err) } - if _, err := f.Write(out); err != nil { + if _, err := fd.Write(out); err != nil { panic(err) } } diff --git a/internal/bitdepth/bitdepth.go b/internal/bitdepth/bitdepth.go index 69233f7..4ec5a66 100644 --- a/internal/bitdepth/bitdepth.go +++ b/internal/bitdepth/bitdepth.go @@ -8,7 +8,7 @@ import ( "math" ) -// ConvertFloat32LittleEndianToSigned16LittleEndian converts a f32le to s16le +// ConvertFloat32LittleEndianToSigned16LittleEndian converts a f32le to s16le. func ConvertFloat32LittleEndianToSigned16LittleEndian(in []float32, out []byte, resampleCount int) error { currIndex := 0 for i := range in { diff --git a/internal/rangecoding/decoder.go b/internal/rangecoding/decoder.go index 183dbd8..1f7ed03 100644 --- a/internal/rangecoding/decoder.go +++ b/internal/rangecoding/decoder.go @@ -103,27 +103,28 @@ func (r *Decoder) Init(data []byte) { // // https://datatracker.ietf.org/doc/html/rfc6716#section-4.1.3.3 func (r *Decoder) DecodeSymbolWithICDF(cumulativeDistributionTable []uint) uint32 { - var k, scale, total, symbol, low, high uint32 + var k, scale, total, symbol, low, high uint32 //nolint:varnamelen - total = uint32(cumulativeDistributionTable[0]) + total = uint32(cumulativeDistributionTable[0]) //nolint:gosec // G115 cumulativeDistributionTable = cumulativeDistributionTable[1:] scale = r.rangeSize / total symbol = r.highAndCodedDifference/scale + 1 - symbol = total - uint32(localMin(uint(symbol), uint(total))) + symbol = total - uint32(localMin(uint(symbol), uint(total))) //nolint:gosec // G115 // nolint: revive - for k = 0; uint32(cumulativeDistributionTable[k]) <= symbol; k++ { + for k = 0; uint32(cumulativeDistributionTable[k]) <= symbol; k++ { //nolint:gosec // G115 } - high = uint32(cumulativeDistributionTable[k]) + high = uint32(cumulativeDistributionTable[k]) //nolint:gosec // G115 if k != 0 { - low = uint32(cumulativeDistributionTable[k-1]) + low = uint32(cumulativeDistributionTable[k-1]) //nolint:gosec // G115 } else { low = 0 } r.update(scale, low, high, total) + return k } @@ -134,7 +135,7 @@ func (r *Decoder) DecodeSymbolWithICDF(cumulativeDistributionTable []uint) uint3 // // https://datatracker.ietf.org/doc/html/rfc6716#section-4.1.3.2 func (r *Decoder) DecodeSymbolLogP(logp uint) uint32 { - var k uint32 + var k uint32 //nolint:varnamelen scale := r.rangeSize >> logp if r.highAndCodedDifference >= scale { @@ -154,11 +155,12 @@ func (r *Decoder) getBit() uint32 { index := r.bitsRead / 8 offset := r.bitsRead % 8 - if index > uint(len(r.data)-1) { + if index > uint(len(r.data)-1) { //nolint:gosec // G115 return 0 } r.bitsRead++ + return uint32((r.data[index] >> (7 - offset)) & 1) } @@ -213,7 +215,7 @@ func (r *Decoder) update(scale, low, high, total uint32) { r.normalize() } -// SetInternalValues is used when using the RangeDecoder when testing +// 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 @@ -225,5 +227,6 @@ func localMin(a, b uint) uint { if a < b { return a } + return b } diff --git a/internal/rangecoding/decoder_test.go b/internal/rangecoding/decoder_test.go index d95f0bc..5028fdc 100644 --- a/internal/rangecoding/decoder_test.go +++ b/internal/rangecoding/decoder_test.go @@ -128,152 +128,152 @@ var ( } ) -func TestDecoder(t *testing.T) { - d := &Decoder{} - d.Init([]byte{0x0b, 0xe4, 0xc1, 0x36, 0xec, 0xc5, 0x80}) +func TestDecoder(t *testing.T) { // nolint:cyclop,gocyclo + decoder := &Decoder{} + decoder.Init([]byte{0x0b, 0xe4, 0xc1, 0x36, 0xec, 0xc5, 0x80}) - if result := d.DecodeSymbolLogP(0x1); result != 0 { + if result := decoder.DecodeSymbolLogP(0x1); result != 0 { t.Fatal("") } - if result := d.DecodeSymbolLogP(0x1); result != 0 { + if result := decoder.DecodeSymbolLogP(0x1); result != 0 { t.Fatal("") } - if result := d.DecodeSymbolWithICDF(silkModelFrameTypeInactive); result != 1 { + if result := decoder.DecodeSymbolWithICDF(silkModelFrameTypeInactive); result != 1 { t.Fatal("") } - if result := d.DecodeSymbolWithICDF(silkModelGainHighbits[0]); result != 0 { + if result := decoder.DecodeSymbolWithICDF(silkModelGainHighbits[0]); result != 0 { t.Fatal("") } - if result := d.DecodeSymbolWithICDF(silkModelGainLowbits); result != 6 { + if result := decoder.DecodeSymbolWithICDF(silkModelGainLowbits); result != 6 { t.Fatal("") } - if result := d.DecodeSymbolWithICDF(silkModelGainDelta); result != 0 { + if result := decoder.DecodeSymbolWithICDF(silkModelGainDelta); result != 0 { t.Fatal("") } - if result := d.DecodeSymbolWithICDF(silkModelGainDelta); result != 3 { + if result := decoder.DecodeSymbolWithICDF(silkModelGainDelta); result != 3 { t.Fatal("") } - if result := d.DecodeSymbolWithICDF(silkModelGainDelta); result != 4 { + if result := decoder.DecodeSymbolWithICDF(silkModelGainDelta); result != 4 { t.Fatal("") } - if result := d.DecodeSymbolWithICDF(silkModelLsfS1[1][0]); result != 9 { + if result := decoder.DecodeSymbolWithICDF(silkModelLsfS1[1][0]); result != 9 { t.Fatal("") } - if result := d.DecodeSymbolWithICDF(silkModelLsfS2[10]); result != 5 { + if result := decoder.DecodeSymbolWithICDF(silkModelLsfS2[10]); result != 5 { t.Fatal("") } - if result := d.DecodeSymbolWithICDF(silkModelLsfS2[9]); result != 4 { + if result := decoder.DecodeSymbolWithICDF(silkModelLsfS2[9]); result != 4 { t.Fatal("") } - if result := d.DecodeSymbolWithICDF(silkModelLsfS2[8]); result != 4 { + if result := decoder.DecodeSymbolWithICDF(silkModelLsfS2[8]); result != 4 { t.Fatal("") } - if result := d.DecodeSymbolWithICDF(silkModelLsfS2[8]); result != 4 { + if result := decoder.DecodeSymbolWithICDF(silkModelLsfS2[8]); result != 4 { t.Fatal("") } - if result := d.DecodeSymbolWithICDF(silkModelLsfS2[8]); result != 4 { + if result := decoder.DecodeSymbolWithICDF(silkModelLsfS2[8]); result != 4 { t.Fatal("") } - if result := d.DecodeSymbolWithICDF(silkModelLsfS2[8]); result != 4 { + if result := decoder.DecodeSymbolWithICDF(silkModelLsfS2[8]); result != 4 { t.Fatal("") } - if result := d.DecodeSymbolWithICDF(silkModelLsfS2[8]); result != 4 { + if result := decoder.DecodeSymbolWithICDF(silkModelLsfS2[8]); result != 4 { t.Fatal("") } - if result := d.DecodeSymbolWithICDF(silkModelLsfS2[8]); result != 4 { + if result := decoder.DecodeSymbolWithICDF(silkModelLsfS2[8]); result != 4 { t.Fatal("") } - if result := d.DecodeSymbolWithICDF(silkModelLsfS2[8]); result != 4 { + if result := decoder.DecodeSymbolWithICDF(silkModelLsfS2[8]); result != 4 { t.Fatal("") } - if result := d.DecodeSymbolWithICDF(silkModelLsfS2[8]); result != 4 { + if result := decoder.DecodeSymbolWithICDF(silkModelLsfS2[8]); result != 4 { t.Fatal("") } - if result := d.DecodeSymbolWithICDF(silkModelLsfS2[8]); result != 4 { + if result := decoder.DecodeSymbolWithICDF(silkModelLsfS2[8]); result != 4 { t.Fatal("") } - if result := d.DecodeSymbolWithICDF(silkModelLsfS2[8]); result != 4 { + if result := decoder.DecodeSymbolWithICDF(silkModelLsfS2[8]); result != 4 { t.Fatal("") } - if result := d.DecodeSymbolWithICDF(silkModelLsfS2[8]); result != 4 { + if result := decoder.DecodeSymbolWithICDF(silkModelLsfS2[8]); result != 4 { t.Fatal("") } - if result := d.DecodeSymbolWithICDF(silkModelLsfS2[8]); result != 4 { + if result := decoder.DecodeSymbolWithICDF(silkModelLsfS2[8]); result != 4 { t.Fatal("") } - if result := d.DecodeSymbolWithICDF(silkModelLsfS2[8]); result != 4 { + if result := decoder.DecodeSymbolWithICDF(silkModelLsfS2[8]); result != 4 { t.Fatal("") } - if result := d.DecodeSymbolWithICDF(silkModelLsfS2[8]); result != 4 { + if result := decoder.DecodeSymbolWithICDF(silkModelLsfS2[8]); result != 4 { t.Fatal("") } - if result := d.DecodeSymbolWithICDF(silkModelLsfInterpolationOffset); result != 4 { + if result := decoder.DecodeSymbolWithICDF(silkModelLsfInterpolationOffset); result != 4 { t.Fatal("") } - if result := d.DecodeSymbolWithICDF(silkModelLcgSeed); result != 2 { + if result := decoder.DecodeSymbolWithICDF(silkModelLcgSeed); result != 2 { t.Fatal("") } - if result := d.DecodeSymbolWithICDF(silkModelExcRate[0]); result != 0 { + if result := decoder.DecodeSymbolWithICDF(silkModelExcRate[0]); result != 0 { t.Fatal("") } - if result := d.DecodeSymbolWithICDF(silkModelPulseCount[0]); result != 0 { + if result := decoder.DecodeSymbolWithICDF(silkModelPulseCount[0]); result != 0 { t.Fatal("") } - if result := d.DecodeSymbolWithICDF(silkModelPulseCount[0]); result != 0 { + if result := decoder.DecodeSymbolWithICDF(silkModelPulseCount[0]); result != 0 { t.Fatal("") } - if result := d.DecodeSymbolWithICDF(silkModelPulseCount[0]); result != 0 { + if result := decoder.DecodeSymbolWithICDF(silkModelPulseCount[0]); result != 0 { t.Fatal("") } - if result := d.DecodeSymbolWithICDF(silkModelPulseCount[0]); result != 0 { + if result := decoder.DecodeSymbolWithICDF(silkModelPulseCount[0]); result != 0 { t.Fatal("") } - if result := d.DecodeSymbolWithICDF(silkModelPulseCount[0]); result != 0 { + if result := decoder.DecodeSymbolWithICDF(silkModelPulseCount[0]); result != 0 { t.Fatal("") } - if result := d.DecodeSymbolWithICDF(silkModelPulseCount[0]); result != 0 { + if result := decoder.DecodeSymbolWithICDF(silkModelPulseCount[0]); result != 0 { t.Fatal("") } - if result := d.DecodeSymbolWithICDF(silkModelPulseCount[0]); result != 0 { + if result := decoder.DecodeSymbolWithICDF(silkModelPulseCount[0]); result != 0 { t.Fatal("") } - if result := d.DecodeSymbolWithICDF(silkModelPulseCount[0]); result != 0 { + if result := decoder.DecodeSymbolWithICDF(silkModelPulseCount[0]); result != 0 { t.Fatal("") } - if result := d.DecodeSymbolWithICDF(silkModelPulseCount[0]); result != 0 { + if result := decoder.DecodeSymbolWithICDF(silkModelPulseCount[0]); result != 0 { t.Fatal("") } - if result := d.DecodeSymbolWithICDF(silkModelPulseCount[0]); result != 0 { + if result := decoder.DecodeSymbolWithICDF(silkModelPulseCount[0]); result != 0 { t.Fatal("") } - if result := d.DecodeSymbolWithICDF(silkModelPulseCount[0]); result != 0 { + if result := decoder.DecodeSymbolWithICDF(silkModelPulseCount[0]); result != 0 { t.Fatal("") } - if result := d.DecodeSymbolWithICDF(silkModelPulseCount[0]); result != 0 { + if result := decoder.DecodeSymbolWithICDF(silkModelPulseCount[0]); result != 0 { t.Fatal("") } - if result := d.DecodeSymbolWithICDF(silkModelPulseCount[0]); result != 0 { + if result := decoder.DecodeSymbolWithICDF(silkModelPulseCount[0]); result != 0 { t.Fatal("") } - if result := d.DecodeSymbolWithICDF(silkModelPulseCount[0]); result != 0 { + if result := decoder.DecodeSymbolWithICDF(silkModelPulseCount[0]); result != 0 { t.Fatal("") } - if result := d.DecodeSymbolWithICDF(silkModelPulseCount[0]); result != 0 { + if result := decoder.DecodeSymbolWithICDF(silkModelPulseCount[0]); result != 0 { t.Fatal("") } - if result := d.DecodeSymbolWithICDF(silkModelPulseCount[0]); result != 0 { + if result := decoder.DecodeSymbolWithICDF(silkModelPulseCount[0]); result != 0 { t.Fatal("") } - if result := d.DecodeSymbolWithICDF(silkModelPulseCount[0]); result != 0 { + if result := decoder.DecodeSymbolWithICDF(silkModelPulseCount[0]); result != 0 { t.Fatal("") } - if result := d.DecodeSymbolWithICDF(silkModelPulseCount[0]); result != 0 { + if result := decoder.DecodeSymbolWithICDF(silkModelPulseCount[0]); result != 0 { t.Fatal("") } - if result := d.DecodeSymbolWithICDF(silkModelPulseCount[0]); result != 0 { + if result := decoder.DecodeSymbolWithICDF(silkModelPulseCount[0]); result != 0 { t.Fatal("") } - if result := d.DecodeSymbolWithICDF(silkModelPulseCount[0]); result != 0 { + if result := decoder.DecodeSymbolWithICDF(silkModelPulseCount[0]); result != 0 { t.Fatal("") } } diff --git a/internal/resample/resample.go b/internal/resample/resample.go index 52f4ed0..aff3754 100644 --- a/internal/resample/resample.go +++ b/internal/resample/resample.go @@ -4,7 +4,7 @@ // Package resample provides tools to resample audio package resample -// Up upsamples the requested amount +// Up upsamples the requested amount. func Up(in, out []float32, upsampleCount int) { currIndex := 0 for i := range in { diff --git a/internal/silk/codebook.go b/internal/silk/codebook.go index 6c12410..4afe410 100644 --- a/internal/silk/codebook.go +++ b/internal/silk/codebook.go @@ -5,7 +5,7 @@ package silk // nolint: dupl, gochecknoglobals, deadcode, unused, varcheck var ( - // In definition of codebook 'a = 0, b = 1...' + // In definition of codebook 'a = 0, b = 1...'. // +----+---------------------+ // | I1 | Coefficient | @@ -223,7 +223,7 @@ var ( } // A+B is Narrowband/Mediumband Prediction Weights - // C+D is Wideband Prediction Weights + // C+D is Wideband Prediction Weights. // // +-------------+-----+-----+-----+-----+ // | Coefficient | A | B | C | D | @@ -259,7 +259,7 @@ var ( // | 14 | | | 182 | 155 | // +-------------+-----+-----+-----+-----+ // - // Table 20: Prediction Weights for Normalized LSF Decoding + // Table 20: Prediction Weights for Normalized LSF Decoding. predictionWeightForNarrowbandAndMediumbandNormalizedLSF = [][]uint{ {179, 138, 140, 148, 151, 149, 153, 151, 163}, @@ -449,7 +449,7 @@ var ( // | 31 | C C D C C D D D C C D C C D C | // +----+---------------------------------------------+ // - // Table 22: Prediction Weight Selection for WB Normalized LSF Decoding + // Table 22: Prediction Weight Selection for WB Normalized LSF Decoding. predictionWeightSelectionForWidebandNormalizedLSF = [][]uint{ {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1}, {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, @@ -555,7 +555,7 @@ var ( // | 31 | 37 48 64 84 104 118 156 177 201 230 | // +----+----------------------------------------+ // - // Table 23: NB/MB Normalized LSF Stage-1 Codebook Vectors + // Table 23: NB/MB Normalized LSF Stage-1 Codebook Vectors. codebookNormalizedLSFStageOneNarrowbandOrMediumband = [][]uint{ {12, 35, 60, 83, 108, 132, 157, 180, 206, 228}, {15, 32, 55, 77, 101, 125, 151, 175, 201, 225}, @@ -660,7 +660,7 @@ var ( // | | | // | 31 | 15 21 35 50 61 73 86 97 110 119 129 141 175 198 218 237 | // +----+------------------------------------------------------------+ - // Table 24: WB Normalized LSF Stage-1 Codebook Vectors + // Table 24: WB Normalized LSF Stage-1 Codebook Vectors. codebookNormalizedLSFStageOneWideband = [][]uint{ {7, 23, 38, 54, 69, 85, 100, 116, 131, 147, 162, 178, 193, 208, 223, 239}, {13, 25, 41, 55, 69, 83, 98, 112, 127, 142, 157, 171, 187, 203, 220, 236}, @@ -734,7 +734,9 @@ var ( // Table 27: LSF Ordering for Polynomial Evaluation lsfOrderingForPolynomialEvaluationNarrowbandAndMediumband = []uint8{0, 9, 6, 3, 4, 5, 8, 1, 2, 7} - lsfOrderingForPolynomialEvaluationWideband = []uint8{0, 15, 8, 7, 4, 11, 12, 3, 2, 13, 10, 5, 6, 9, 14, 1} + lsfOrderingForPolynomialEvaluationWideband = []uint8{ + 0, 15, 8, 7, 4, 11, 12, 3, 2, 13, 10, 5, 6, 9, 14, 1, + } // +-----+-------+-------+-------+-------+ // | i | +0 | +1 | +2 | +3 | @@ -806,7 +808,7 @@ var ( // | 128 | -4096 | | | | // +-----+-------+-------+-------+-------+ // - // Table 28: Q12 Cosine Table for LSF Conversion + // Table 28: Q12 Cosine Table for LSF Conversion. q12CosineTableForLSFConverion = []int32{ 4096, 4095, 4091, 4085, 4076, 4065, 4052, 4036, 4017, 3997, 3973, 3948, 3920, 3889, 3857, 3822, 3784, 3745, 3703, 3659, diff --git a/internal/silk/decoder.go b/internal/silk/decoder.go index f5b6479..f6595ac 100644 --- a/internal/silk/decoder.go +++ b/internal/silk/decoder.go @@ -11,7 +11,7 @@ import ( ) // Decoder maintains the state needed to decode a stream -// of Silk frames +// of Silk frames. type Decoder struct { rangeDecoder rangecoding.Decoder @@ -39,7 +39,7 @@ type Decoder struct { n0Q15 []int16 } -// NewDecoder creates a new Silk Decoder +// NewDecoder creates a new Silk Decoder. func NewDecoder() Decoder { return Decoder{ finalOutValues: make([]float32, 306), @@ -54,6 +54,7 @@ func NewDecoder() Decoder { func (d *Decoder) decodeHeaderBits() (voiceActivityDetected, lowBitRateRedundancy bool) { voiceActivityDetected = d.rangeDecoder.DecodeSymbolLogP(1) == 1 lowBitRateRedundancy = d.rangeDecoder.DecodeSymbolLogP(1) == 1 + return } @@ -62,7 +63,10 @@ func (d *Decoder) decodeHeaderBits() (voiceActivityDetected, lowBitRateRedundanc // corresponding frame. // // https://datatracker.ietf.org/doc/html/rfc6716#section-4.2.7.3 -func (d *Decoder) determineFrameType(voiceActivityDetected bool) (signalType frameSignalType, quantizationOffsetType frameQuantizationOffsetType) { +func (d *Decoder) determineFrameType(voiceActivityDetected bool) ( + signalType frameSignalType, + quantizationOffsetType frameQuantizationOffsetType, +) { var frameTypeSymbol uint32 if voiceActivityDetected { frameTypeSymbol = d.rangeDecoder.DecodeSymbolWithICDF(icdfFrameTypeVADActive) @@ -130,15 +134,20 @@ func (d *Decoder) decodeSubframeQuantizations(signalType frameSignalType) (gainQ // Table 11 based on the decoded signal type switch signalType { case frameSignalTypeInactive: + //nolint:gosec gainIndex = int32(d.rangeDecoder.DecodeSymbolWithICDF(icdfIndependentQuantizationGainMSBInactive)) case frameSignalTypeVoiced: + //nolint:gosec gainIndex = int32(d.rangeDecoder.DecodeSymbolWithICDF(icdfIndependentQuantizationGainMSBVoiced)) case frameSignalTypeUnvoiced: + //nolint:gosec gainIndex = int32(d.rangeDecoder.DecodeSymbolWithICDF(icdfIndependentQuantizationGainMSBUnvoiced)) } // The 3 least significant bits are decoded using a uniform PDF: // These 6 bits are combined to form a value, gain_index, between 0 and 63. + // + //nolint:gosec gainIndex = (gainIndex << 3) | int32(d.rangeDecoder.DecodeSymbolWithICDF(icdfIndependentQuantizationGainLSB)) // When the gain for the previous subframe is available, then the @@ -154,6 +163,8 @@ func (d *Decoder) decodeSubframeQuantizations(signalType frameSignalType) (gainQ // first subframe of frames not listed as using independent coding // above), the quantization gain is coded relative to the gain from the // previous subframe + // + //nolint:gosec deltaGainIndex = int32(d.rangeDecoder.DecodeSymbolWithICDF(icdfDeltaQuantizationGain)) // The following formula translates this index into a quantization gain @@ -170,8 +181,8 @@ func (d *Decoder) decodeSubframeQuantizations(signalType frameSignalType) (gainQ // gain_Q16[k] = silk_log2lin((0x1D1C71*log_gain>>16) + 2090) // inLogQ7 := (0x1D1C71 * logGain >> 16) + 2090 - i := inLogQ7 >> 7 - f := inLogQ7 & 127 + i := inLogQ7 >> 7 //nolint:varnamelen // integer exponent + f := inLogQ7 & 127 //nolint:varnamelen // fractional exponent // The function silk_log2lin() (log2lin.c) computes an approximation of // 2**(inLog_Q7/128.0), where inLog_Q7 is its Q7 input. Let i = @@ -194,7 +205,9 @@ func (d *Decoder) decodeSubframeQuantizations(signalType frameSignalType) (gainQ // the quantization gains in the bitstream and represent the Linear // Predictive Coding (LPC) coefficients for the current SILK frame. // -// https://datatracker.ietf.org/doc/html/rfc6716#section-4.2.7.5.1 +// https://datatracker.ietf.org/doc/html/rfc6716#section-4.2.7.5.1. +// +//nolint:cyclop,lll func (d *Decoder) normalizeLineSpectralFrequencyStageOne(voiceActivityDetected bool, bandwidth Bandwidth) (I1 uint32) { // nolint: gocritic // The first VQ stage uses a 32-element codebook, coded with one of the // PDFs in Table 14, depending on the audio bandwidth and the signal @@ -225,7 +238,9 @@ func (d *Decoder) normalizeLineSpectralFrequencyStageOne(voiceActivityDetected b // the quantization gains in the bitstream and represent the Linear // Predictive Coding (LPC) coefficients for the current SILK frame. // -// https://datatracker.ietf.org/doc/html/rfc6716#section-4.2.7.5.2 +// https://datatracker.ietf.org/doc/html/rfc6716#section-4.2.7.5.2. +// +//nolint:lll func (d *Decoder) normalizeLineSpectralFrequencyStageTwo(bandwidth Bandwidth, I1 uint32) (dLPC int, resQ10 []int16) { // nolint: gocritic // Decoding the second stage residual proceeds as follows. For each // coefficient, the decoder reads a symbol using the PDF corresponding @@ -245,6 +260,8 @@ func (d *Decoder) normalizeLineSpectralFrequencyStageTwo(bandwidth Bandwidth, I1 // result to give an index in the range -4 to 4, inclusive. // // https://datatracker.ietf.org/doc/html/rfc6716#section-4.2.7.5.2 + // + //nolint:gosec I2[i] = int8(d.rangeDecoder.DecodeSymbolWithICDF(icdfNormalizedLSFStageTwoIndex[codebook[I1][i]])) - 4 // If the index is either -4 or 4, it reads a second symbol using the PDF in @@ -254,8 +271,10 @@ func (d *Decoder) normalizeLineSpectralFrequencyStageTwo(bandwidth Bandwidth, I1 // // https://datatracker.ietf.org/doc/html/rfc6716#section-4.2.7.5.2 if I2[i] == -4 { + //nolint:gosec // G115 I2[i] -= int8(d.rangeDecoder.DecodeSymbolWithICDF(icdfNormalizedLSFStageTwoIndexExtension)) } else if I2[i] == 4 { + //nolint:gosec // G115 I2[i] += int8(d.rangeDecoder.DecodeSymbolWithICDF(icdfNormalizedLSFStageTwoIndexExtension)) } } @@ -285,7 +304,7 @@ func (d *Decoder) normalizeLineSpectralFrequencyStageTwo(bandwidth Bandwidth, I1 dLPC = len(I2) // for 0 <= k < d_LPC-1 - for k := dLPC - 1; k >= 0; k-- { + for k := dLPC - 1; k >= 0; k-- { //nolint:varnamelen // The stage-2 residual for each coefficient is computed via // // res_Q10[k] = (k+1 < d_LPC ? (res_Q10[k+1]*pred_Q8[k])>>8 : 0) + ((((I2[k]<<10) - sign(I2[k])*102)*qstep)>>16) , @@ -301,8 +320,10 @@ func (d *Decoder) normalizeLineSpectralFrequencyStageTwo(bandwidth Bandwidth, I1 // let pred_Q8[k] be the weight for the k'th coefficient selected by this process for 0 <= k < d_LPC-1 var predQ8 int if bandwidth == BandwidthWideband { + //nolint:gosec // G115 predQ8 = int(predictionWeightForWidebandNormalizedLSF[predictionWeightSelectionForWidebandNormalizedLSF[I1][k]][k]) } else { + //nolint:lll,gosec // G115 predQ8 = int(predictionWeightForNarrowbandAndMediumbandNormalizedLSF[predictionWeightSelectionForNarrowbandAndMediumbandNormalizedLSF[I1][k]][k]) } @@ -312,10 +333,10 @@ func (d *Decoder) normalizeLineSpectralFrequencyStageTwo(bandwidth Bandwidth, I1 // The following computes // // (((I2[k]<<10) - sign(I2[k])*102)*qstep)>>16 - // + //. secondOperand := (((int(I2[k]) << 10) - sign(int(I2[k]))*102) * qstep) >> 16 - resQ10[k] = int16(firstOperand + secondOperand) + resQ10[k] = int16(firstOperand + secondOperand) //nolint:gosec // G115 } return dLPC, resQ10 @@ -326,7 +347,14 @@ func (d *Decoder) normalizeLineSpectralFrequencyStageTwo(bandwidth Bandwidth, I1 // reconstructed. // // https://datatracker.ietf.org/doc/html/rfc6716#section-4.2.7.5.3 -func (d *Decoder) normalizeLineSpectralFrequencyCoefficients(dLPC int, bandwidth Bandwidth, resQ10 []int16, I1 uint32) (nlsfQ15 []int16) { //nolint: gocritic +// +//nolint:gocritic +func (d *Decoder) normalizeLineSpectralFrequencyCoefficients( + dLPC int, + bandwidth Bandwidth, + resQ10 []int16, + I1 uint32, +) (nlsfQ15 []int16) { nlsfQ15 = make([]int16, dLPC) w2Q18 := make([]uint, dLPC) wQ9 := make([]int16, dLPC) @@ -348,7 +376,7 @@ func (d *Decoder) normalizeLineSpectralFrequencyCoefficients(dLPC int, bandwidth // the following square-root approximation: // // https://datatracker.ietf.org/doc/html/rfc6716#section-4.2.7.5.3 - for k := 0; k < dLPC; k++ { + for k := 0; k < dLPC; k++ { //nolint:varnamelen kMinusOne, kPlusOne := uint(0), uint(256) //nolint: revive if k != 0 { kMinusOne = cb1Q8[I1][k-1] @@ -370,8 +398,8 @@ func (d *Decoder) normalizeLineSpectralFrequencyCoefficients(dLPC int, bandwidth // w_Q9[k] = y + ((213*f*y)>>16) // // https://datatracker.ietf.org/doc/html/rfc6716#section-4.2.7.5.3 - i := ilog(int(w2Q18[k])) - f := int((w2Q18[k] >> (i - 8)) & 127) + i := ilog(int(w2Q18[k])) //nolint:gosec // G115 + f := int((w2Q18[k] >> (i - 8)) & 127) //nolint:gosec // G115 y := 46214 if (i & 1) != 0 { @@ -379,7 +407,7 @@ func (d *Decoder) normalizeLineSpectralFrequencyCoefficients(dLPC int, bandwidth } y >>= ((32 - i) >> 1) - wQ9[k] = int16(y + ((213 * f * y) >> 16)) + wQ9[k] = int16(y + ((213 * f * y) >> 16)) //nolint:gosec // G115 // Given the stage-1 codebook entry cb1_Q8[], the stage-2 residual // res_Q10[], and their corresponding weights, w_Q9[], the reconstructed @@ -389,8 +417,8 @@ func (d *Decoder) normalizeLineSpectralFrequencyCoefficients(dLPC int, bandwidth // (cb1_Q8[k]<<7) + (res_Q10[k]<<14)/w_Q9[k], 32767) // // https://datatracker.ietf.org/doc/html/rfc6716#section-4.2.7.5.3 - nlsfQ15[k] = int16(clamp(0, - int32((int(cb1Q8[I1][k])<<7)+(int(resQ10[k])<<14)/int(wQ9[k])), 32767)) + nlsfQ15[k] = int16(clamp(0, //nolint:gosec // G115 + int32((int(cb1Q8[I1][k])<<7)+(int(resQ10[k])<<14)/int(wQ9[k])), 32767)) //nolint:gosec // G115 } return nlsfQ15 @@ -402,6 +430,8 @@ func (d *Decoder) normalizeLineSpectralFrequencyCoefficients(dLPC int, bandwidth // percentile of a large training set). // // https://datatracker.ietf.org/doc/html/rfc6716#section-4.2.7.5.4 +// +//nolint:cyclop func (d *Decoder) normalizeLSFStabilization(nlsfQ15 []int16, dLPC int, bandwidth Bandwidth) { // Let NDeltaMin_Q15[k] be the minimum required spacing for the current // audio bandwidth from Table 25. @@ -428,23 +458,23 @@ func (d *Decoder) normalizeLSFStabilization(nlsfQ15 []int16, dLPC int, bandwidth i := 0 iValue := int(math.MaxInt) - for j := 0; j <= len(nlsfQ15); j++ { + for nlsfIndex := 0; nlsfIndex <= len(nlsfQ15); nlsfIndex++ { // For the purposes of computing this spacing for the first and last coefficient, // NLSF_Q15[-1] is taken to be 0 and NLSF_Q15[d_LPC] is taken to be 32768 // // https://datatracker.ietf.org/doc/html/rfc6716#section-4.2.7.5.4 previousNLSF := 0 currentNLSF := 32768 - if j != 0 { - previousNLSF = int(nlsfQ15[j-1]) + if nlsfIndex != 0 { + previousNLSF = int(nlsfQ15[nlsfIndex-1]) } - if j != len(nlsfQ15) { - currentNLSF = int(nlsfQ15[j]) + if nlsfIndex != len(nlsfQ15) { + currentNLSF = int(nlsfQ15[nlsfIndex]) } - spacingValue := currentNLSF - previousNLSF - NDeltaMinQ15[j] + spacingValue := currentNLSF - previousNLSF - NDeltaMinQ15[nlsfIndex] if spacingValue < iValue { - i = j + i = nlsfIndex iValue = spacingValue } } @@ -460,14 +490,16 @@ func (d *Decoder) normalizeLSFStabilization(nlsfQ15 []int16, dLPC int, bandwidth // // https://datatracker.ietf.org/doc/html/rfc6716#section-4.2.7.5.4 case i == 0: - nlsfQ15[0] = int16(NDeltaMinQ15[0]) + nlsfQ15[0] = int16(NDeltaMinQ15[0]) //nolint:gosec // G115 + continue // if i == d_LPC, it sets // NLSF_Q15[d_LPC-1] to (32768 - NDeltaMin_Q15[d_LPC]) // // https://datatracker.ietf.org/doc/html/rfc6716#section-4.2.7.5.4 case i == dLPC: - nlsfQ15[dLPC-1] = int16(32768 - NDeltaMinQ15[dLPC]) + nlsfQ15[dLPC-1] = int16(32768 - NDeltaMinQ15[dLPC]) //nolint:gosec // G115 + continue } @@ -498,15 +530,15 @@ func (d *Decoder) normalizeLSFStabilization(nlsfQ15 []int16, dLPC int, bandwidth // (NLSF_Q15[i-1] + NLSF_Q15[i] + 1)>>1 // max_center_Q15[i]) centerFreqQ15 := int(clamp( - int32(minCenterQ15), - int32((int(nlsfQ15[i-1])+int(nlsfQ15[i])+1)>>1), - int32(maxCenterQ15)), + int32(minCenterQ15), //nolint:gosec // G115 + int32((int(nlsfQ15[i-1])+int(nlsfQ15[i])+1)>>1), //nolint:gosec // G115 + int32(maxCenterQ15)), //nolint:gosec // G115 ) // NLSF_Q15[i-1] = center_freq_Q15 - (NDeltaMin_Q15[i]>>1) // NLSF_Q15[i] = NLSF_Q15[i-1] + NDeltaMin_Q15[i] - nlsfQ15[i-1] = int16(centerFreqQ15 - NDeltaMinQ15[i]>>1) - nlsfQ15[i] = nlsfQ15[i-1] + int16(NDeltaMinQ15[i]) + nlsfQ15[i-1] = int16(centerFreqQ15 - NDeltaMinQ15[i]>>1) //nolint:gosec // G115 + nlsfQ15[i] = nlsfQ15[i-1] + int16(NDeltaMinQ15[i]) //nolint:gosec // G115 } // After the 20th repetition of the above procedure, the following @@ -526,7 +558,7 @@ func (d *Decoder) normalizeLSFStabilization(nlsfQ15 []int16, dLPC int, bandwidth prevNLSF = nlsfQ15[k-1] } - nlsfQ15[k] = maxInt16(nlsfQ15[k], prevNLSF+int16(NDeltaMinQ15[k])) + nlsfQ15[k] = maxInt16(nlsfQ15[k], prevNLSF+int16(NDeltaMinQ15[k])) //nolint:gosec // G115 } // Next, for each value of k from d_LPC-1 down to 0, NLSF_Q15[k] is set @@ -539,7 +571,7 @@ func (d *Decoder) normalizeLSFStabilization(nlsfQ15 []int16, dLPC int, bandwidth nextNLSF = int(nlsfQ15[k+1]) } - nlsfQ15[k] = minInt16(nlsfQ15[k], int16(nextNLSF-NDeltaMinQ15[k+1])) + nlsfQ15[k] = minInt16(nlsfQ15[k], int16(nextNLSF-NDeltaMinQ15[k+1])) //nolint:gosec // G115 } } @@ -552,7 +584,7 @@ func (d *Decoder) normalizeLSFInterpolation(n2Q15 []int16) (n1Q15 []int16, wQ2 i // 20 ms frame, n1_Q15[k], are // // n1_Q15[k] = n0_Q15[k] + (w_Q2*(n2_Q15[k] - n0_Q15[k]) >> 2) - wQ2 = int16(d.rangeDecoder.DecodeSymbolWithICDF(icdfNormalizedLSFInterpolationIndex)) + wQ2 = int16(d.rangeDecoder.DecodeSymbolWithICDF(icdfNormalizedLSFInterpolationIndex)) //nolint:gosec // G115 if wQ2 == 4 || !d.haveDecoded { return nil, wQ2 } @@ -578,6 +610,7 @@ func (d *Decoder) generateAQ12(Q15 []int16, bandwidth Bandwidth, aQ12 [][]float3 // https://www.rfc-editor.org/rfc/rfc6716.html#section-4.2.7.5.8 aQ12 = append(aQ12, d.limitLPCFilterPredictionGain(a32Q17)) + return aQ12 } @@ -652,12 +685,12 @@ func (d *Decoder) convertNormalizedLSFsToLPCCoefficients(n1Q15 []int16, bandwidt // https://datatracker.ietf.org/doc/html/rfc6716#section-4.2.7.5.6 for k := 1; k < d2; k++ { - pQ16[k+1] = pQ16[k-1]*2 - int32(((int64(cQ17[2*k])*int64(pQ16[k]))+32768)>>16) - qQ16[k+1] = qQ16[k-1]*2 - int32(((int64(cQ17[(2*k)+1])*int64(qQ16[k]))+32768)>>16) + pQ16[k+1] = pQ16[k-1]*2 - int32(((int64(cQ17[2*k])*int64(pQ16[k]))+32768)>>16) //nolint:gosec // G115 + qQ16[k+1] = qQ16[k-1]*2 - int32(((int64(cQ17[(2*k)+1])*int64(qQ16[k]))+32768)>>16) //nolint:gosec // G115 for j := k; j > 1; j-- { - pQ16[j] += pQ16[j-2] - int32(((int64(cQ17[2*k])*int64(pQ16[j-1]))+32768)>>16) - qQ16[j] += qQ16[j-2] - int32(((int64(cQ17[(2*k)+1])*int64(qQ16[j-1]))+32768)>>16) + pQ16[j] += pQ16[j-2] - int32(((int64(cQ17[2*k])*int64(pQ16[j-1]))+32768)>>16) //nolint:gosec // G115 + qQ16[j] += qQ16[j-2] - int32(((int64(cQ17[(2*k)+1])*int64(qQ16[j-1]))+32768)>>16) //nolint:gosec // G115 } pQ16[1] -= cQ17[2*k] @@ -686,6 +719,7 @@ func (d *Decoder) convertNormalizedLSFsToLPCCoefficients(n1Q15 []int16, bandwidt a32Q17[k] = -(qQ16[k+1] - qQ16[k]) - (pQ16[k+1] + pQ16[k]) a32Q17[dLPC-k-1] = (qQ16[k+1] - qQ16[k]) - (pQ16[k+1] + pQ16[k]) } + return a32Q17 } @@ -724,6 +758,8 @@ func (d *Decoder) decodeLinearCongruentialGeneratorSeed() uint32 { // Table 44: Number of Shell Blocks Per SILK Frame // // https://datatracker.ietf.org/doc/html/rfc6716#section-4.2.7.8 +// +//nolint:cyclop func (d *Decoder) decodeShellblocks(nanoseconds int, bandwidth Bandwidth) (shellblocks int) { switch { case bandwidth == BandwidthNarrowband && nanoseconds == nanoseconds10Ms: @@ -739,6 +775,7 @@ func (d *Decoder) decodeShellblocks(nanoseconds int, bandwidth Bandwidth) (shell case bandwidth == BandwidthWideband && nanoseconds == nanoseconds20Ms: shellblocks = 20 } + return } @@ -763,7 +800,7 @@ func (d *Decoder) decodePulseAndLSBCounts(shellblocks int, rateLevel uint32) (pu pulsecounts = make([]uint8, shellblocks) lsbcounts = make([]uint8, shellblocks) for i := 0; i < shellblocks; i++ { - pulsecounts[i] = uint8(d.rangeDecoder.DecodeSymbolWithICDF(icdfPulseCount[rateLevel])) + pulsecounts[i] = uint8(d.rangeDecoder.DecodeSymbolWithICDF(icdfPulseCount[rateLevel])) //nolint:gosec // g115 // The special value 17 indicates that this block // has one or more additional LSBs to decode for each coefficient. @@ -776,7 +813,7 @@ func (d *Decoder) decodePulseAndLSBCounts(shellblocks int, rateLevel uint32) (pu // For that block. lsbcount := uint8(0) for ; pulsecounts[i] == 17 && lsbcount < 10; lsbcount++ { - pulsecounts[i] = uint8(d.rangeDecoder.DecodeSymbolWithICDF(icdfPulseCount[9])) + pulsecounts[i] = uint8(d.rangeDecoder.DecodeSymbolWithICDF(icdfPulseCount[9])) //nolint:gosec // g115 } lsbcounts[i] = lsbcount @@ -788,7 +825,7 @@ func (d *Decoder) decodePulseAndLSBCounts(shellblocks int, rateLevel uint32) (pu // Version of that for 9 and thus does not require any additional // Storage. if lsbcount == 10 { - pulsecounts[i] = uint8(d.rangeDecoder.DecodeSymbolWithICDF(icdfPulseCount[10])) + pulsecounts[i] = uint8(d.rangeDecoder.DecodeSymbolWithICDF(icdfPulseCount[10])) //nolint:gosec // g115 } } } @@ -856,7 +893,7 @@ func (d *Decoder) decodePulseLocation(pulsecounts []uint8) (eRaw []int32) { func (d *Decoder) decodeExcitationLSB(eRaw []int32, lsbcounts []uint8) { for i := 0; i < len(eRaw); i++ { for bit := uint8(0); bit < lsbcounts[i/pulsecountLargestPartitionSize]; bit++ { - eRaw[i] = (eRaw[i] << 1) | int32(d.rangeDecoder.DecodeSymbolWithICDF(icdfExcitationLSB)) + eRaw[i] = (eRaw[i] << 1) | int32(d.rangeDecoder.DecodeSymbolWithICDF(icdfExcitationLSB)) //nolint:gosec // g115 } } } @@ -865,7 +902,14 @@ func (d *Decoder) decodeExcitationLSB(eRaw []int32, lsbcounts []uint8) { // the magnitude of each coefficient in the excitation. // // https://datatracker.ietf.org/doc/html/rfc6716#section-4.2.7.8.5 -func (d *Decoder) decodeExcitationSign(eRaw []int32, signalType frameSignalType, quantizationOffsetType frameQuantizationOffsetType, pulsecounts []uint8) { //nolint: gocognit +// +//nolint:cyclop,gocyclo,gocognit +func (d *Decoder) decodeExcitationSign( + eRaw []int32, + signalType frameSignalType, + quantizationOffsetType frameQuantizationOffsetType, + pulsecounts []uint8, +) { for i := 0; i < len(eRaw); i++ { // It then decodes a sign for all coefficients // with a non-zero magnitude @@ -1011,6 +1055,8 @@ func (d *Decoder) decodeExcitationSign(eRaw []int32, signalType frameSignalType, // position are required to have the same sign. // // https://datatracker.ietf.org/doc/html/rfc6716#section-4.2.7.8 +// +//nolint:cyclop,lll func (d *Decoder) decodeExcitation(signalType frameSignalType, quantizationOffsetType frameQuantizationOffsetType, seed uint32, pulsecounts, lsbcounts []uint8) (eQ23 []int32) { // After the signs have been read, there is enough information to // reconstruct the complete excitation signal. This requires adding a @@ -1084,12 +1130,12 @@ func (d *Decoder) decodeExcitation(signalType frameSignalType, quantizationOffse // e_Q23[i] value may require more than 16 bits per sample, but it will // not require more than 23, including the sign. - eQ23[i] = (eRaw[i] << 8) - int32(sign(int(eRaw[i])))*20 + offsetQ23 + eQ23[i] = (eRaw[i] << 8) - int32(sign(int(eRaw[i])))*20 + offsetQ23 //nolint:gosec // g115 seed = (196314165*seed + 907633515) & 0xFFFFFFFF if seed&0x80000000 != 0 { eQ23[i] *= -1 } - seed = (seed + uint32(eRaw[i])) & 0xFFFFFFFF + seed = (seed + uint32(eRaw[i])) & 0xFFFFFFFF //nolint:gosec // g115 } return eQ23 @@ -1109,7 +1155,7 @@ func (d *Decoder) partitionPulseCount(icdf [][]uint, block uint8, halves []uint8 halves[0] = 0 halves[1] = 0 } else { - halves[0] = uint8(d.rangeDecoder.DecodeSymbolWithICDF(icdf[block-1])) + halves[0] = uint8(d.rangeDecoder.DecodeSymbolWithICDF(icdf[block-1])) //nolint:gosec // g115 halves[1] = block - halves[0] } } @@ -1133,10 +1179,10 @@ func (d *Decoder) limitLPCCoefficientsRange(a32Q17 []int32) { maxabsQ17 := uint(0) for k, val := range a32Q17 { - abs := int32(sign(int(val))) * val - if maxabsQ17 < uint(abs) { - maxabsQ17K = uint(k) - maxabsQ17 = uint(abs) + abs := int32(sign(int(val))) * val //nolint:gosec // g115 + if maxabsQ17 < uint(abs) { //nolint:gosec // g115 + maxabsQ17K = uint(k) //nolint:gosec // g115 + maxabsQ17 = uint(abs) //nolint:gosec // g115 } } @@ -1174,7 +1220,7 @@ func (d *Decoder) limitLPCCoefficientsRange(a32Q17 []int32) { // // https://datatracker.ietf.org/doc/html/rfc6716#section-4.2.7.5.7 for k := 0; k < len(a32Q17); k++ { - a32Q17[k] = (a32Q17[k] * int32(scQ16[k])) >> 16 + a32Q17[k] = (a32Q17[k] * int32(scQ16[k])) >> 16 //nolint:gosec if len(scQ16) <= k { scQ16[k+1] = (scQ16[0]*scQ16[k] + 32768) >> 16 } @@ -1229,9 +1275,12 @@ func (d *Decoder) limitLPCFilterPredictionGain(a32Q17 []int32) (aQ12 []float32) } // https://www.rfc-editor.org/rfc/rfc6716.html#section-4.2.7.6.1 -func (d *Decoder) decodePitchLags(signalType frameSignalType, bandwidth Bandwidth) (lagMax uint32, pitchLags []int, err error) { +func (d *Decoder) decodePitchLags( + signalType frameSignalType, + bandwidth Bandwidth, +) (lagMax uint32, pitchLags []int, err error) { if signalType != frameSignalTypeVoiced { - return + return 0, nil, nil } var ( @@ -1371,9 +1420,9 @@ func (d *Decoder) decodePitchLags(signalType frameSignalType, bandwidth Bandwidt pitchLags = make([]int, subframeCount) for i := 0; i < subframeCount; i++ { pitchLags[i] = int(clamp( - int32(lagMin), - int32(lag+uint32(lagCb[contourIndex][i])), - int32(lagMax)), + int32(lagMin), //nolint:gosec + int32(lag+uint32(lagCb[contourIndex][i])), //nolint:gosec + int32(lagMax)), //nolint:gosec ) } @@ -1425,7 +1474,7 @@ func (d *Decoder) decodeLTPScalingParamater(signalType frameSignalType) (LTPscal // https://www.rfc-editor.org/rfc/rfc6716.html#section-4.2.7.6.2 func (d *Decoder) decodeLTPFilterCoefficients(signalType frameSignalType) (bQ7 [][]int8) { if signalType != frameSignalTypeVoiced { - return + return bQ7 } bQ7 = [][]int8{ @@ -1469,6 +1518,7 @@ func (d *Decoder) decodeLTPFilterCoefficients(signalType frameSignalType) (bQ7 [ copy(bQ7[i], LTPFilterCodebook[filterIndex]) } + return bQ7 } @@ -1489,12 +1539,13 @@ func (d *Decoder) samplesInSubframe(bandwidth Bandwidth) int { } // https://www.rfc-editor.org/rfc/rfc6716.html#section-4.2.7.9.1 -// nolint: gocognit +// +//nolint:gocognit,cyclop func (d *Decoder) ltpSynthesis( out []float32, bQ7 [][]int8, pitchLags []int, - n, j, s, dLPC int, + n, j, s, dLPC int, //nolint:varnamelen LTPScaleQ14 float32, //nolint: gocritic wQ2 int16, aQ12, gainQ16, res, resLag []float32, @@ -1635,7 +1686,11 @@ func (d *Decoder) ltpSynthesis( // after either // // https://www.rfc-editor.org/rfc/rfc6716.html#section-4.2.7.9.2 -func (d *Decoder) lpcSynthesis(out []float32, n, s, dLPC int, aQ12, res, gainQ16, lpc []float32) { +func (d *Decoder) lpcSynthesis( + out []float32, + n, s, dLPC int, //nolint:varnamelen + aQ12, res, gainQ16, lpc []float32, +) { // j be the index of the first sample in the residual corresponding to // the current subframe. j := 0 @@ -1731,9 +1786,9 @@ func (d *Decoder) silkFrameReconstruction( res[i] = float32(eQ23[i]) / 8388608.0 } - // s be the index of the current subframe in this SILK frame + // subFrame be the index of the current subframe in this SILK frame // (0 or 1 for 10 ms frames, or 0 to 3 for 20 ms frames) - for s := 0; s < subframeCount; s++ { + for subFrame := 0; subFrame < subframeCount; subFrame++ { // For 20 ms SILK frames, the first half of the frame (i.e., the first // two subframes) may use normalized LSF coefficients that are // interpolated between the decoded LSFs for the most recent coded frame @@ -1741,7 +1796,7 @@ func (d *Decoder) silkFrameReconstruction( // // https://datatracker.ietf.org/doc/html/rfc6716#section-4.2.7.5.5 aQ12Index := 0 - if s > 1 && len(aQ12) > 1 { + if subFrame > 1 && len(aQ12) > 1 { aQ12Index = 1 } @@ -1749,7 +1804,7 @@ func (d *Decoder) silkFrameReconstruction( // the current subframe. // // https://www.rfc-editor.org/rfc/rfc6716.html#section-4.2.7.9 - j := n * s + j := n * subFrame // Voiced SILK frames, on the other hand, pass the excitation through an // LTP filter using the parameters decoded in Section 4.2.7.6 to produce @@ -1760,7 +1815,7 @@ func (d *Decoder) silkFrameReconstruction( d.ltpSynthesis( out, bQ7, pitchLags, - n, j, s, dLPC, + n, j, subFrame, dLPC, LTPscaleQ14, wQ2, aQ12[aQ12Index], gainQ16, res, resLag, @@ -1768,7 +1823,7 @@ func (d *Decoder) silkFrameReconstruction( } // https://www.rfc-editor.org/rfc/rfc6716.html#section-4.2.7.9.2 - d.lpcSynthesis(out[n*s:], n, s, dLPC, aQ12[aQ12Index], res, gainQ16, lpc) + d.lpcSynthesis(out[n*subFrame:], n, subFrame, dLPC, aQ12[aQ12Index], res, gainQ16, lpc) } } @@ -1805,7 +1860,7 @@ func (d *Decoder) silkFrameReconstruction( // 8: Resampled signal // // https://datatracker.ietf.org/doc/html/rfc6716#section-4.2.1 -func (d *Decoder) Decode(in []byte, out []float32, isStereo bool, nanoseconds int, bandwidth Bandwidth) error { +func (d *Decoder) Decode(in []byte, out []float32, isStereo bool, nanoseconds int, bandwidth Bandwidth) error { // nolint:lll subframeSize := d.samplesInSubframe(bandwidth) switch { case nanoseconds != nanoseconds20Ms: diff --git a/internal/silk/decoder_test.go b/internal/silk/decoder_test.go index 3c80016..9d9f164 100644 --- a/internal/silk/decoder_test.go +++ b/internal/silk/decoder_test.go @@ -22,12 +22,20 @@ func testResQ10() []int16 { } func testNlsfQ1() []int16 { - return []int16{2132, 3584, 5504, 7424, 9472, 11392, 13440, 15360, 17280, 19200, 21120, 23040, 25088, 27008, 28928, 30848} + 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 { +func createRangeDecoder( + data []byte, + bitsRead uint, + rangeSize uint32, + highAndCodedDifference uint32, +) rangecoding.Decoder { d := rangecoding.Decoder{} d.SetInternalValues(data, bitsRead, rangeSize, highAndCodedDifference) + return d } @@ -86,7 +94,7 @@ func TestNormalizeLineSpectralFrequencyStageOne(t *testing.T) { } func TestNormalizeLSFStabilization(t *testing.T) { - d := &Decoder{} + decoder := &Decoder{} in := []int16{ 856, 2310, 3452, 4865, 4852, @@ -102,7 +110,7 @@ func TestNormalizeLSFStabilization(t *testing.T) { 30700, } - d.normalizeLSFStabilization(in, 16, BandwidthWideband) + decoder.normalizeLSFStabilization(in, 16, BandwidthWideband) if !reflect.DeepEqual(in, expectedOut) { t.Fatal() } @@ -117,7 +125,7 @@ func TestNormalizeLSFStabilization(t *testing.T) { 9867, 10260, 10691, 14397, 16969, 19355, 21645, 25228, 26972, 30360, 30363, } - d.normalizeLSFStabilization(in, 16, BandwidthWideband) + decoder.normalizeLSFStabilization(in, 16, BandwidthWideband) if !reflect.DeepEqual(in, expectedOut) { t.Fatal() } @@ -155,21 +163,28 @@ func TestNormalizeLSFInterpolation(t *testing.T) { }) t.Run("wQ2 == 1", func(t *testing.T) { - frame := []byte{0xac, 0xbd, 0xa9, 0xf7, 0x26, 0x24, 0x5a, 0xa4, 0x00, 0x37, 0xbf, 0x9c, 0xde, 0xe, 0xcf, 0x94, 0x64, 0xaa, 0xf9, 0x87, 0xd0, 0x79, 0x19, 0xa8, 0x21, 0xc0} - d := &Decoder{ + frame := []byte{ + 0xac, 0xbd, 0xa9, 0xf7, 0x26, 0x24, 0x5a, 0xa4, 0x00, 0x37, + 0xbf, 0x9c, 0xde, 0xe, 0xcf, 0x94, 0x64, 0xaa, 0xf9, 0x87, + 0xd0, 0x79, 0x19, 0xa8, 0x21, 0xc0, + } + decoder := &Decoder{ rangeDecoder: createRangeDecoder(frame, 65, 1231761776, 1068195183), haveDecoded: true, n0Q15: []int16{ 518, 380, 4444, 6982, 8752, 10510, 12381, 14102, 15892, 17651, 19340, 21888, 23936, 25984, 28160, 30208, }, } - n2Q15 := []int16{215, 1447, 3712, 5120, 7168, 9088, 11264, 13184, 15232, 17536, 19712, 21888, 24192, 26240, 28416, 30336} + n2Q15 := []int16{ + 215, 1447, 3712, 5120, 7168, 9088, 11264, 13184, 15232, 17536, + 19712, 21888, 24192, 26240, 28416, 30336, + } expectedN1Q15 := []int16{ 442, 646, 4261, 6516, 8356, 10154, 12101, 13872, 15727, 17622, 19433, 21888, 24000, 26048, 28224, 30240, } - actualN2Q15, _ := d.normalizeLSFInterpolation(n2Q15) + actualN2Q15, _ := decoder.normalizeLSFInterpolation(n2Q15) if !reflect.DeepEqual(actualN2Q15, expectedN1Q15) { t.Fatal() @@ -178,7 +193,7 @@ func TestNormalizeLSFInterpolation(t *testing.T) { } func TestConvertNormalizedLSFsToLPCCoefficients(t *testing.T) { - d := &Decoder{} + decoder := &Decoder{} nlsfQ15 := []int16{ 0x854, 0xe00, 0x1580, 0x1d00, 0x2500, 0x2c80, 0x3480, @@ -191,7 +206,7 @@ func TestConvertNormalizedLSFsToLPCCoefficients(t *testing.T) { -3441, -3848, -4493, -1614, -1960, -3112, -2153, -2898, } - if !reflect.DeepEqual(d.convertNormalizedLSFsToLPCCoefficients(nlsfQ15, BandwidthWideband), expectedA32Q17) { + if !reflect.DeepEqual(decoder.convertNormalizedLSFsToLPCCoefficients(nlsfQ15, BandwidthWideband), expectedA32Q17) { t.Fatal() } } @@ -234,7 +249,10 @@ func TestExcitation(t *testing.T) { -25, -25, -25, 25, } - silkFrame := []byte{0x84, 0x2e, 0x67, 0xd3, 0x85, 0x65, 0x54, 0xe3, 0x9d, 0x90, 0x0a, 0xfa, 0x98, 0xea, 0xfd, 0x98, 0x94, 0x41, 0xf9, 0x6d, 0x1d, 0xa0} + silkFrame := []byte{ + 0x84, 0x2e, 0x67, 0xd3, 0x85, 0x65, 0x54, 0xe3, 0x9d, 0x90, 0x0a, + 0xfa, 0x98, 0xea, 0xfd, 0x98, 0x94, 0x41, 0xf9, 0x6d, 0x1d, 0xa0, + } d := &Decoder{rangeDecoder: createRangeDecoder(silkFrame, 71, 851775140, 846837397)} lcgSeed := d.decodeLinearCongruentialGeneratorSeed() @@ -267,8 +285,8 @@ func TestLimitLPCFilterPredictionGain(t *testing.T) { } } -func TestLPCSynthesis(t *testing.T) { - d := NewDecoder() +func TestLPCSynthesis(t *testing.T) { //nolint:lll + decoder := NewDecoder() dLPC := 16 aQ12 := []float32{ @@ -276,7 +294,7 @@ func TestLPCSynthesis(t *testing.T) { -140, -50, -61, -97, -67, -91, } - // nolint: dupl + //nolint:dupl,lll res := []float32{ 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, @@ -423,10 +441,10 @@ func TestLPCSynthesis(t *testing.T) { }, } - lpc := make([]float32, d.samplesInSubframe(BandwidthWideband)*subframeCount) + lpc := make([]float32, decoder.samplesInSubframe(BandwidthWideband)*subframeCount) for i := range expectedOut { out := make([]float32, 80) - d.lpcSynthesis(out, d.samplesInSubframe(BandwidthWideband), i, dLPC, aQ12, res, gainQ16, lpc) + decoder.lpcSynthesis(out, decoder.samplesInSubframe(BandwidthWideband), i, dLPC, aQ12, res, gainQ16, lpc) for j := range out { if out[j]-expectedOut[i][j] > floatEqualityThreshold { t.Fatalf("run(%d) index(%d) (%f) != (%f)", i, j, out[j], expectedOut[i][j]) @@ -436,7 +454,11 @@ func TestLPCSynthesis(t *testing.T) { } func TestDecodePitchLags(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} + silkFrame := []byte{ + 0xb4, 0xe2, 0x2c, 0x0e, 0x10, 0x65, 0x1d, 0xa9, 0x07, 0x5c, 0x36, + 0x8f, 0x96, 0x7b, 0xf4, 0x89, 0x41, 0x55, 0x98, 0x7a, 0x39, 0x2e, + 0x6b, 0x71, 0xa4, 0x3, 0x70, 0xbf, + } d := &Decoder{rangeDecoder: createRangeDecoder(silkFrame, 73, 30770362, 1380489)} lagMax, pitchLags, _ := d.decodePitchLags(frameSignalTypeVoiced, BandwidthWideband) @@ -450,7 +472,11 @@ func TestDecodePitchLags(t *testing.T) { } 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} + silkFrame := []byte{ + 0xb4, 0xe2, 0x2c, 0x0e, 0x10, 0x65, 0x1d, 0xa9, 0x07, 0x5c, 0x36, + 0x8f, 0x96, 0x7b, 0xf4, 0x89, 0x41, 0x55, 0x98, 0x7a, 0x39, 0x2e, + 0x6b, 0x71, 0xa4, 0x03, 0x70, 0xbf, + } d := &Decoder{rangeDecoder: createRangeDecoder(silkFrame, 89, 253853952, 138203876)} bQ7 := d.decodeLTPFilterCoefficients(frameSignalTypeVoiced) @@ -466,7 +492,11 @@ func TestDecodeLTPFilterCoefficients(t *testing.T) { func TestDecodeLTPScalingParameter(t *testing.T) { t.Run("Voiced", func(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} + silkFrame := []byte{ + 0xb4, 0xe2, 0x2c, 0x0e, 0x10, 0x65, 0x1d, 0xa9, 0x07, 0x5c, 0x36, + 0x8f, 0x96, 0x7b, 0xf4, 0x89, 0x41, 0x55, 0x98, 0x7a, 0x39, 0x2e, + 0x6b, 0x71, 0xa4, 0x03, 0x70, 0xbf, + } d := &Decoder{rangeDecoder: createRangeDecoder(silkFrame, 105, 160412192, 164623240)} if d.decodeLTPScalingParamater(frameSignalTypeVoiced) != 15565.0 { @@ -483,10 +513,12 @@ func TestDecodeLTPScalingParameter(t *testing.T) { } func TestDecode(t *testing.T) { - d := NewDecoder() + decoder := NewDecoder() out := make([]float32, 320) - compareBuffer := func(out, expectedOut []float32, t *testing.T) { + compareBuffer := func(t *testing.T, out, expectedOut []float32) { + t.Helper() + for i := range expectedOut { if out[i]-expectedOut[i] > floatEqualityThreshold { t.Fatalf("%d (%f) != (%f)", i, out[i], expectedOut[i]) @@ -495,7 +527,7 @@ func TestDecode(t *testing.T) { } t.Run("Unvoiced Single Frame", func(t *testing.T) { - if err := d.Decode(testSilkFrame(), out, false, nanoseconds20Ms, BandwidthWideband); err != nil { + if err := decoder.Decode(testSilkFrame(), out, false, nanoseconds20Ms, BandwidthWideband); err != nil { t.Fatal(err) } @@ -566,11 +598,17 @@ func TestDecode(t *testing.T) { 0.000006, -0.000013, -0.000013, 0.000008, -0.000011, -0.000012, -0.000012, 0.000010, 0.000011, 0.000013, } - compareBuffer(out, expectedOut, t) + compareBuffer(t, out, expectedOut) }) t.Run("Unvoiced Subsequent Frame", func(t *testing.T) { - if err := d.Decode([]byte{0x07, 0xc9, 0x72, 0x27, 0xe1, 0x44, 0xea, 0x50}, out, false, nanoseconds20Ms, BandwidthWideband); err != nil { + if err := decoder.Decode( + []byte{0x07, 0xc9, 0x72, 0x27, 0xe1, 0x44, 0xea, 0x50}, + out, + false, + nanoseconds20Ms, + BandwidthWideband, + ); err != nil { t.Fatal(err) } @@ -640,6 +678,6 @@ func TestDecode(t *testing.T) { -0.000012, 0.000009, -0.000010, 0.000010, -0.000009, -0.000010, -0.000011, 0.000010, -0.000010, 0.000011, } - compareBuffer(out, expectedOut, t) + compareBuffer(t, out, expectedOut) }) } diff --git a/internal/silk/icdf.go b/internal/silk/icdf.go index f88cf73..c4eaf00 100644 --- a/internal/silk/icdf.go +++ b/internal/silk/icdf.go @@ -48,7 +48,7 @@ var ( // | 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, | // | 1}/256 | // +-------------------------------------------------------------------+ - // PDF for Delta Quantization Gain Coding + // PDF for Delta Quantization Gain Coding. icdfDeltaQuantizationGain = []uint{ 256, 6, 11, 22, 53, 185, 206, 214, 218, 221, 223, 225, 227, 228, 229, 230, 231, 232, 233, 234, 235, 236, 237, 238, 239, 240, 241, 242, @@ -75,7 +75,7 @@ var ( // | | | 13, 14, 14, 6, 14, 12, 2, 6, 1, 12, 12, | // | | | 11, 10, 3, 10, 5, 1, 1, 1, 3}/256 | // +-----------+----------+--------------------------------------------+ - // PDFs for Normalized LSF Stage-1 Index Decoding + // PDFs for Normalized LSF Stage-1 Index Decoding. icdfNormalizedLSFStageOneIndexNarrowbandOrMediumbandUnvoiced = []uint{ 256, 44, 78, 108, 127, 148, 160, 171, 174, 177, 179, 195, 197, 199, 200, 205, 207, 208, 211, 214, 215, 216, 218, 220, 222, 225, 226, 235, 244, 246, @@ -100,7 +100,7 @@ var ( // | {156, 60, 24, 9, 4, 2, 1}/256 | // +-------------------------------+ // - // Normalized LSF Index Extension Decoding + // Normalized LSF Index Extension Decoding. icdfNormalizedLSFStageTwoIndexExtension = []uint{256, 156, 216, 240, 249, 253, 255, 256} // +----------+--------------------------------------+ @@ -147,7 +147,7 @@ var ( // // NB/MD and WD ICDF are combined because the codebooks // do not overlap - // + //. icdfNormalizedLSFStageTwoIndex = [][]uint{ // Narrowband and Mediumband {256, 1, 2, 3, 18, 242, 253, 254, 255, 256}, @@ -176,7 +176,7 @@ var ( // | {13, 22, 29, 11, 181}/256 | // +---------------------------+ // - // Table 26: PDF for Normalized LSF Interpolation Index + // Table 26: PDF for Normalized LSF Interpolation Index. icdfNormalizedLSFInterpolationIndex = []uint{ 256, 13, 35, 64, 75, 256, } @@ -187,7 +187,7 @@ var ( // | {64, 64, 64, 64}/256 | // +----------------------+ // - // Table 43: PDF for LCG Seed + // Table 43: PDF for LCG Seed. icdfLinearCongruentialGeneratorSeed = []uint{ 256, 64, 128, 192, 256, } @@ -200,7 +200,7 @@ var ( // | Voiced | {33, 30, 36, 17, 34, 49, 18, 21, 18}/256 | // +----------------------+------------------------------------------+ // - // Table 45: PDFs for the Rate Level + // Table 45: PDFs for the Rate Level. icdfRateLevelUnvoiced = []uint{256, 15, 66, 78, 124, 169, 182, 215, 242, 256} icdfRateLevelVoiced = []uint{256, 33, 63, 99, 116, 150, 199, 217, 238, 256} @@ -242,7 +242,7 @@ var ( // | | 1, 2, 0}/256 | // +----------+--------------------------------------------------------+ // - // Table 46: PDFs for the Pulse Count + // Table 46: PDFs for the Pulse Count. icdfPulseCount = [][]uint{ {256, 131, 205, 230, 238, 241, 244, 245, 246, 247, 248, 249, 250, 251, 252, 253, 254, 255, 256}, {256, 58, 151, 211, 234, 241, 244, 245, 246, 247, 248, 249, 250, 251, 252, 253, 254, 255, 256}, @@ -298,7 +298,7 @@ var ( // | | 1, 1, 1}/256 | // +------------+------------------------------------------------------+ // - // Table 47: PDFs for Pulse Count Split, 16 Sample Partitions + // Table 47: PDFs for Pulse Count Split, 16 Sample Partitions. icdfPulseCountSplit16SamplePartitions = [][]uint{ {256, 126, 256}, {256, 56, 198, 256}, @@ -358,7 +358,7 @@ var ( // | 16 | {1, 1, 2, 6, 12, 21, 30, 36, 38, 36, 30, 21, 12, 6, | // | | 2, 1, 1}/256 | // +------------+------------------------------------------------------+ - // Table 48: PDFs for Pulse Count Split, 8 Sample Partitions + // Table 48: PDFs for Pulse Count Split, 8 Sample Partitions. icdfPulseCountSplit8SamplePartitions = [][]uint{ {256, 127, 256}, {256, 53, 202, 256}, @@ -418,7 +418,7 @@ var ( // | 16 | {1, 1, 4, 9, 15, 21, 28, 32, 34, 32, 28, 21, 15, 9, | // | | 4, 1, 1}/256 | // +------------+------------------------------------------------------+ - // Table 49: PDFs for Pulse Count Split, 4 Sample Partitions + // Table 49: PDFs for Pulse Count Split, 4 Sample Partitions. icdfPulseCountSplit4SamplePartitions = [][]uint{ {256, 127, 256}, {256, 49, 206, 256}, @@ -478,7 +478,7 @@ var ( // | 16 | {1, 2, 4, 7, 13, 21, 28, 34, 36, 34, 28, 21, 13, 7, | // | | 4, 2, 1}/256 | // +------------+------------------------------------------------------+ - // Table 50: PDFs for Pulse Count Split, 2 Sample Partitions + // Table 50: PDFs for Pulse Count Split, 2 Sample Partitions. icdfPulseCountSplit2SamplePartitions = [][]uint{ {256, 128, 256}, {256, 42, 214, 256}, @@ -504,7 +504,7 @@ var ( // | {136, 120}/256 | // +----------------+ // - // Table 51: PDF for Excitation LSBs + // Table 51: PDF for Excitation LSBs. icdfExcitationLSB = []uint{256, 136, 256} // +-------------+-----------------------+-------------+---------------+ @@ -598,7 +598,7 @@ var ( // | Voiced | High | 6 or more | {154,102}/256 | // +-------------+-----------------------+-------------+---------------+ // - // Table 52: PDFs for Excitation Signs + // Table 52: PDFs for Excitation Signs. icdfExcitationSignInactiveSignalLowQuantization0Pulse = []uint{256, 2, 256} icdfExcitationSignInactiveSignalLowQuantization1Pulse = []uint{256, 207, 256} icdfExcitationSignInactiveSignalLowQuantization2Pulse = []uint{256, 189, 256} diff --git a/internal/silk/silk.go b/internal/silk/silk.go index 38b9c7f..c3d3450 100644 --- a/internal/silk/silk.go +++ b/internal/silk/silk.go @@ -7,7 +7,7 @@ package silk import "math" type ( - // Bandwidth for Silk can be NB (narrowband) MB (medium-band) or WB (wideband) + // Bandwidth for Silk can be NB (narrowband) MB (medium-band) or WB (wideband). Bandwidth byte frameSignalType byte @@ -30,7 +30,7 @@ const ( frameQuantizationOffsetTypeHigh ) -// Bandwidth constants +// Bandwidth constants. const ( BandwidthNarrowband Bandwidth = iota + 1 BandwidthMediumband @@ -41,6 +41,7 @@ func maxInt32(a, b int32) int32 { if a > b { return a } + return b } @@ -48,6 +49,7 @@ func maxInt16(a, b int16) int16 { if a > b { return a } + return b } @@ -83,6 +85,7 @@ func clampNegativeOneToOne(v float32) float32 { } else if v >= 1 { return 1 } + return v } @@ -114,5 +117,6 @@ func ilog(n int) int { if n <= 0 { return 0 } + return int(math.Floor(math.Log2(float64(n)))) + 1 } diff --git a/pkg/oggreader/oggreader.go b/pkg/oggreader/oggreader.go index c0f716b..cf3fb76 100644 --- a/pkg/oggreader/oggreader.go +++ b/pkg/oggreader/oggreader.go @@ -30,7 +30,7 @@ var ( errChecksumMismatch = errors.New("expected and actual checksum do not match") ) -// OggReader is used to read Ogg files and return page payloads +// OggReader is used to read Ogg files and return page payloads. type OggReader struct { stream io.Reader bytesReadSuccesfully int64 @@ -67,7 +67,7 @@ type OggPageHeader struct { } // NewWith returns a new Ogg reader and Ogg header -// with an io.Reader input +// with an io.Reader input. func NewWith(in io.Reader) (*OggReader, *OggHeader, error) { return newWith(in /* doChecksum */, true) } @@ -126,26 +126,26 @@ func (o *OggReader) readHeaders() (*OggHeader, error) { // ParseNextPage reads from stream and returns Ogg page segments, header, // and an error if there is incomplete page data. -func (o *OggReader) ParseNextPage() ([][]byte, *OggPageHeader, error) { - h := make([]byte, pageHeaderLen) +func (o *OggReader) ParseNextPage() ([][]byte, *OggPageHeader, error) { // nolint:cyclop + header := make([]byte, pageHeaderLen) - n, err := io.ReadFull(o.stream, h) + n, err := io.ReadFull(o.stream, header) if err != nil { return nil, nil, err - } else if n < len(h) { + } else if n < len(header) { return nil, nil, errShortPageHeader } pageHeader := &OggPageHeader{ - sig: [4]byte{h[0], h[1], h[2], h[3]}, + sig: [4]byte{header[0], header[1], header[2], header[3]}, } - pageHeader.version = h[4] - pageHeader.headerType = h[5] - pageHeader.GranulePosition = binary.LittleEndian.Uint64(h[6 : 6+8]) - pageHeader.serial = binary.LittleEndian.Uint32(h[14 : 14+4]) - pageHeader.index = binary.LittleEndian.Uint32(h[18 : 18+4]) - pageHeader.segmentsCount = h[26] + pageHeader.version = header[4] + pageHeader.headerType = header[5] + pageHeader.GranulePosition = binary.LittleEndian.Uint64(header[6 : 6+8]) + pageHeader.serial = binary.LittleEndian.Uint32(header[14 : 14+4]) + pageHeader.index = binary.LittleEndian.Uint32(header[18 : 18+4]) + pageHeader.segmentsCount = header[26] sizeBuffer := make([]byte, pageHeader.segmentsCount) if _, err = io.ReadFull(o.stream, sizeBuffer); err != nil { @@ -169,14 +169,15 @@ func (o *OggReader) ParseNextPage() ([][]byte, *OggPageHeader, error) { checksum = (checksum << 8) ^ o.checksumTable[byte(checksum>>24)^v] } - for index := range h { + for index := range header { // Don't include expected checksum in our generation if index > 21 && index < 26 { updateChecksum(0) + continue } - updateChecksum(h[index]) + updateChecksum(header[index]) } for _, s := range sizeBuffer { updateChecksum(s) @@ -188,7 +189,7 @@ func (o *OggReader) ParseNextPage() ([][]byte, *OggPageHeader, error) { } } - if binary.LittleEndian.Uint32(h[22:22+4]) != checksum { + if binary.LittleEndian.Uint32(header[22:22+4]) != checksum { return nil, nil, errChecksumMismatch } } @@ -208,7 +209,8 @@ func generateChecksumTable() *[256]uint32 { const poly = 0x04c11db7 for i := range table { - r := uint32(i) << 24 + r := uint32(i) << 24 // nolint:gosec // G115 false positive + for j := 0; j < 8; j++ { if (r & 0x80000000) != 0 { r = (r << 1) ^ poly @@ -218,5 +220,6 @@ func generateChecksumTable() *[256]uint32 { table[i] = (r & 0xffffffff) } } + return &table } diff --git a/pkg/oggreader/oggreader_test.go b/pkg/oggreader/oggreader_test.go index 69b1b43..1e5e3e4 100644 --- a/pkg/oggreader/oggreader_test.go +++ b/pkg/oggreader/oggreader_test.go @@ -12,7 +12,7 @@ import ( ) // buildOggFile generates a valid oggfile that can -// be used for tests +// be used for tests. func buildOggContainer() []byte { return []byte{ 0x4f, 0x67, 0x67, 0x53, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, diff --git a/table_of_contents_header.go b/table_of_contents_header.go index 5887377..8f986df 100644 --- a/table_of_contents_header.go +++ b/table_of_contents_header.go @@ -101,16 +101,16 @@ type ( // The remaining two bits of the TOC byte, labeled "c", code the number // of frames per packet (codes 0 to 3) as follows: - - // o 0: 1 frame in the packet - - // o 1: 2 frames in the packet, each with equal compressed size - - // o 2: 2 frames in the packet, with different compressed sizes - + // + // o 0: 1 frame in the packet. + // + // o 1: 2 frames in the packet, each with equal compressed size. + // + // o 2: 2 frames in the packet, with different compressed sizes. + // // o 3: an arbitrary number of frames in the packet // - // https://datatracker.ietf.org/doc/html/rfc6716#section-3.1 + // https://datatracker.ietf.org/doc/html/rfc6716#section-3.1. frameCode byte ) @@ -149,6 +149,7 @@ func (c configurationMode) String() string { case configurationModeHybrid: return "Hybrid" } + return "Invalid Configuration Mode" } @@ -235,7 +236,7 @@ func (c Configuration) frameDuration() frameDuration { return 0 } -// Bandwidth constants +// Bandwidth constants. const ( BandwidthNarrowband Bandwidth = iota + 1 BandwidthMediumband @@ -284,10 +285,11 @@ func (b Bandwidth) String() string { case BandwidthFullband: return "Fullband" } + return "Invalid Bandwidth" } -// SampleRate returns the effective SampleRate for a given bandwidth +// SampleRate returns the effective SampleRate for a given bandwidth. func (b Bandwidth) SampleRate() int { switch b { case BandwidthNarrowband: @@ -301,6 +303,7 @@ func (b Bandwidth) SampleRate() int { case BandwidthFullband: return 48000 } + return 0 } @@ -326,5 +329,6 @@ func parseFrameCountByte(in byte) (isVBR bool, hasPadding bool, frameCount byte) isVBR = (in & 0b10000000) == 1 hasPadding = (in & 0b01000000) == 1 frameCount = in & 0b00111111 + return }