diff --git a/.golangci.yaml b/.golangci.yaml index 2f8424a..00109e5 100644 --- a/.golangci.yaml +++ b/.golangci.yaml @@ -13,8 +13,11 @@ # - internal/reftest is a cgo differential harness (build tag refc); it is held # to the idiomatic standard but exempted from a few cgo-hostile checks. # - opus/, oggopus/, cmd/ are idiomatic Go at full strength. -# - modernize stays disabled: it panics on Go 1.26 + atomic types in -# golangci-lint v2 (known upstream bug), same as go-flac. +# - modernize runs on the idiomatic packages; inside the transliteration +# packages it joins the relaxed style linters, because its rangeint and +# loop rewrites fight diffability against the C. It stayed off until +# golangci-lint v2.13.2 on Go 1.27 fixed the v2 panic on atomic types +# (previously shared with go-flac). version: "2" output: sort-order: @@ -38,6 +41,7 @@ linters: - iface - ineffassign - misspell + - modernize - nilerr - nilnil - predeclared @@ -95,6 +99,7 @@ linters: - gocyclo - goconst - misspell + - modernize - prealloc - predeclared - revive @@ -110,10 +115,13 @@ linters: linters: - staticcheck text: "(ST1003|ST1016|QF1|S1021)" - # cgo differential harness: cgo pointer patterns and C-mirroring names. + # cgo differential harness: cgo pointer patterns, C-mirroring names, and + # C-mirroring loops (modernize's rangeint rewrites fight diffability with + # the libopus reference the harness is checked against). - path: internal/reftest/ linters: - gocritic + - modernize - revive # Test files: table-driven tests are naturally long and repetitive. - path: _test\.go diff --git a/internal/packet/toc_test.go b/internal/packet/toc_test.go index 8d49f54..f6bbe92 100644 --- a/internal/packet/toc_test.go +++ b/internal/packet/toc_test.go @@ -53,7 +53,7 @@ func TestParseTOCConfigTable(t *testing.T) { // Sweep the stereo flag and all four frame-count codes for each config // to prove those low bits do not perturb the config decoding. for _, stereo := range []bool{false, true} { - for code := uint8(0); code < 4; code++ { + for code := range uint8(4) { b := tc.config<<3 | code if stereo { b |= 0x4 diff --git a/oggopus/decoder.go b/oggopus/decoder.go index 77923da..9403773 100644 --- a/oggopus/decoder.go +++ b/oggopus/decoder.go @@ -200,10 +200,7 @@ func (d *Decoder) fill() (done bool, err error) { } // End-trim so the total delivered equals finalGranule - preSkip. if d.limit >= 0 && d.delivered+int64(perChan) > d.limit { - keep := int(d.limit - d.delivered) - if keep < 0 { - keep = 0 - } + keep := max(int(d.limit-d.delivered), 0) samples = samples[:keep*d.info.Channels] perChan = keep } diff --git a/oggopus/family1_test.go b/oggopus/family1_test.go index 50adbda..14419d2 100644 --- a/oggopus/family1_test.go +++ b/oggopus/family1_test.go @@ -257,10 +257,7 @@ func genInterleavedPCM(n, channels int) []int16 { // firstDiffByte returns the index of the first differing byte, or the shorter // length when one is a prefix of the other. func firstDiffByte(a, b []byte) int { - n := len(a) - if len(b) < n { - n = len(b) - } + n := min(len(b), len(a)) for i := range n { if a[i] != b[i] { return i diff --git a/oggopus/writer.go b/oggopus/writer.go index 4e6267f..0fd3231 100644 --- a/oggopus/writer.go +++ b/oggopus/writer.go @@ -173,14 +173,11 @@ func (cw *containerWriter) writePacket(pkt []byte, samples48k int) error { // end-of-stream flag. close is idempotent. func (cw *containerWriter) close(sourceSamples int64) error { if cw.hasHeld { - finalGranule := cw.preSkip + sourceSamples // Guard monotonicity: the final granule must not regress below the // previous page's cumulative count. This never triggers for consistent // inputs; it defends against a caller passing a sourceSamples smaller // than the already-committed audio. - if finalGranule < cw.granule { - finalGranule = cw.granule - } + finalGranule := max(cw.preSkip+sourceSamples, cw.granule) if err := cw.sw.writeAudioPacket(cw.heldPacket, finalGranule); err != nil { return err }