From 00258b3d2a195bd85a29eab7a22c53cc25d117b6 Mon Sep 17 00:00:00 2001 From: Mark Kremer Date: Mon, 30 Oct 2023 15:12:36 +0100 Subject: [PATCH 1/9] Fix flac.Decode EOF handling --- flac/decode.go | 3 +++ 1 file changed, 3 insertions(+) diff --git a/flac/decode.go b/flac/decode.go index 7bc2041..dda6043 100644 --- a/flac/decode.go +++ b/flac/decode.go @@ -62,6 +62,9 @@ func (d *decoder) Stream(samples [][2]float64) (n int, ok bool) { if j >= len(d.buf) { // refill buffer. if err := d.refill(); err != nil { + if err == io.EOF { + return 0, false + } d.err = err d.pos += n return n, n > 0 From b6af53a9b0e919607b97091862520d7f48f5f863 Mon Sep 17 00:00:00 2001 From: Mark Kremer Date: Mon, 30 Oct 2023 15:13:19 +0100 Subject: [PATCH 2/9] Fix typos in Streamer docblock --- interface.go | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/interface.go b/interface.go index 8099767..93ab4f1 100644 --- a/interface.go +++ b/interface.go @@ -14,11 +14,11 @@ type Streamer interface { // samples will be produced, it returns 0 and false. Stream must not touch any samples // outside samples[:n]. // - // There are 3 valid return pattterns of the Stream method: + // There are 3 valid return patterns of the Stream method: // // 1. n == len(samples) && ok // - // Stream streamed all of the requested samples. Cases 1, 2 and 3 may occur in the following + // Stream streamed all the requested samples. Cases 1, 2 and 3 may occur in the following // calls. // // 2. 0 < n && n < len(samples) && ok From b303a269f682f433dd5275b3dba1f478ae736934 Mon Sep 17 00:00:00 2001 From: Mark Kremer Date: Mon, 30 Oct 2023 15:15:17 +0100 Subject: [PATCH 3/9] Update CHANGELOG.md --- CHANGELOG.md | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 2630592..8400aab 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -11,7 +11,8 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - Support for single channel ogg/vorbis ([#10](https://github.com/gopxl/beep/pull/10)) ### Fixed -- Fix FileSize for saving .wav ([#6](https://github.com/gopxl/beep/pull/6)) +- Fix `FileSize` for saving .wav ([#6](https://github.com/gopxl/beep/pull/6)) +- Fix `flac.Decode` handling of `io.EOF` ([#127](https://github.com/gopxl/beep/pull/127)) ### Changed - Upgrade Go version to 1.21 ([#2](https://github.com/gopxl/beep/pull/2)) From 804710de2b9ac0e6f72156905cc1f48d85bd5cbb Mon Sep 17 00:00:00 2001 From: Mark Kremer Date: Mon, 30 Oct 2023 15:23:47 +0100 Subject: [PATCH 4/9] Fix flac.Decode EOF handling (2) --- flac/decode.go | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/flac/decode.go b/flac/decode.go index dda6043..5658fe3 100644 --- a/flac/decode.go +++ b/flac/decode.go @@ -62,11 +62,11 @@ func (d *decoder) Stream(samples [][2]float64) (n int, ok bool) { if j >= len(d.buf) { // refill buffer. if err := d.refill(); err != nil { + d.pos += n if err == io.EOF { - return 0, false + return n, n > 0 } d.err = err - d.pos += n return n, n > 0 } j = 0 From 7c98b053627b73c912633a7a56bd62ea43a5afa9 Mon Sep 17 00:00:00 2001 From: Mark Kremer Date: Mon, 30 Oct 2023 15:29:25 +0100 Subject: [PATCH 5/9] Fix flac.Decode EOF handling (3) --- flac/decode.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/flac/decode.go b/flac/decode.go index 5658fe3..c939e27 100644 --- a/flac/decode.go +++ b/flac/decode.go @@ -67,7 +67,7 @@ func (d *decoder) Stream(samples [][2]float64) (n int, ok bool) { return n, n > 0 } d.err = err - return n, n > 0 + return 0, false } j = 0 } From 6ec313a987cdbcac425f59d6506f9cbc03cb6daa Mon Sep 17 00:00:00 2001 From: Mark Kremer Date: Wed, 1 Nov 2023 15:11:21 +0100 Subject: [PATCH 6/9] Move testing helpers to internal directory --- compositors_test.go | 76 +++++---------------------------- internal/testtools/sinks.go | 18 ++++++++ internal/testtools/streamers.go | 47 ++++++++++++++++++++ resample_test.go | 5 ++- 4 files changed, 78 insertions(+), 68 deletions(-) create mode 100644 internal/testtools/sinks.go create mode 100644 internal/testtools/streamers.go diff --git a/compositors_test.go b/compositors_test.go index bc937f2..94759fe 100644 --- a/compositors_test.go +++ b/compositors_test.go @@ -1,6 +1,7 @@ package beep_test import ( + "github.com/gopxl/beep/internal/testtools" "math/rand" "reflect" "testing" @@ -8,71 +9,14 @@ import ( "github.com/gopxl/beep" ) -// randomDataStreamer generates random samples of duration d and returns a StreamSeeker which streams -// them and the data itself. -func randomDataStreamer(numSamples int) (s beep.StreamSeeker, data [][2]float64) { - data = make([][2]float64, numSamples) - for i := range data { - data[i][0] = rand.Float64()*2 - 1 - data[i][1] = rand.Float64()*2 - 1 - } - return &dataStreamer{data, 0}, data -} - -type dataStreamer struct { - data [][2]float64 - pos int -} - -func (ds *dataStreamer) Stream(samples [][2]float64) (n int, ok bool) { - if ds.pos >= len(ds.data) { - return 0, false - } - n = copy(samples, ds.data[ds.pos:]) - ds.pos += n - return n, true -} - -func (ds *dataStreamer) Err() error { - return nil -} - -func (ds *dataStreamer) Len() int { - return len(ds.data) -} - -func (ds *dataStreamer) Position() int { - return ds.pos -} - -func (ds *dataStreamer) Seek(p int) error { - ds.pos = p - return nil -} - -// collect drains Streamer s and returns all of the samples it streamed. -func collect(s beep.Streamer) [][2]float64 { - var ( - result [][2]float64 - buf [479][2]float64 - ) - for { - n, ok := s.Stream(buf[:]) - if !ok { - return result - } - result = append(result, buf[:n]...) - } -} - func TestTake(t *testing.T) { for i := 0; i < 7; i++ { total := rand.Intn(1e5) + 1e4 - s, data := randomDataStreamer(total) + s, data := testtools.RandomDataStreamer(total) take := rand.Intn(total) want := data[:take] - got := collect(beep.Take(take, s)) + got := testtools.Collect(beep.Take(take, s)) if !reflect.DeepEqual(want, got) { t.Error("Take not working correctly") @@ -83,13 +27,13 @@ func TestTake(t *testing.T) { func TestLoop(t *testing.T) { for i := 0; i < 7; i++ { for n := 0; n < 5; n++ { - s, data := randomDataStreamer(10) + s, data := testtools.RandomDataStreamer(10) var want [][2]float64 for j := 0; j < n; j++ { want = append(want, data...) } - got := collect(beep.Loop(n, s)) + got := testtools.Collect(beep.Loop(n, s)) if !reflect.DeepEqual(want, got) { t.Error("Loop not working correctly") @@ -105,7 +49,7 @@ func TestSeq(t *testing.T) { data = make([][][2]float64, n) ) for i := range s { - s[i], data[i] = randomDataStreamer(rand.Intn(1e5) + 1e4) + s[i], data[i] = testtools.RandomDataStreamer(rand.Intn(1e5) + 1e4) } var want [][2]float64 @@ -113,7 +57,7 @@ func TestSeq(t *testing.T) { want = append(want, d...) } - got := collect(beep.Seq(s...)) + got := testtools.Collect(beep.Seq(s...)) if !reflect.DeepEqual(want, got) { t.Errorf("Seq not working properly") @@ -127,7 +71,7 @@ func TestMix(t *testing.T) { data = make([][][2]float64, n) ) for i := range s { - s[i], data[i] = randomDataStreamer(rand.Intn(1e5) + 1e4) + s[i], data[i] = testtools.RandomDataStreamer(rand.Intn(1e5) + 1e4) } maxLen := 0 @@ -145,7 +89,7 @@ func TestMix(t *testing.T) { } } - got := collect(beep.Mix(s...)) + got := testtools.Collect(beep.Mix(s...)) if !reflect.DeepEqual(want, got) { t.Error("Mix not working correctly") @@ -154,7 +98,7 @@ func TestMix(t *testing.T) { func TestDup(t *testing.T) { for i := 0; i < 7; i++ { - s, data := randomDataStreamer(rand.Intn(1e5) + 1e4) + s, data := testtools.RandomDataStreamer(rand.Intn(1e5) + 1e4) st, su := beep.Dup(s) var tData, uData [][2]float64 diff --git a/internal/testtools/sinks.go b/internal/testtools/sinks.go new file mode 100644 index 0000000..f8681b5 --- /dev/null +++ b/internal/testtools/sinks.go @@ -0,0 +1,18 @@ +package testtools + +import "github.com/gopxl/beep" + +// Collect drains Streamer s and returns all the samples it streamed. +func Collect(s beep.Streamer) [][2]float64 { + var ( + result [][2]float64 + buf [479][2]float64 + ) + for { + n, ok := s.Stream(buf[:]) + if !ok { + return result + } + result = append(result, buf[:n]...) + } +} diff --git a/internal/testtools/streamers.go b/internal/testtools/streamers.go new file mode 100644 index 0000000..693793a --- /dev/null +++ b/internal/testtools/streamers.go @@ -0,0 +1,47 @@ +package testtools + +import ( + "github.com/gopxl/beep" + "math/rand" +) + +// RandomDataStreamer generates numSamples random samples and returns a StreamSeeker to stream them. +func RandomDataStreamer(numSamples int) (s beep.StreamSeeker, data [][2]float64) { + data = make([][2]float64, numSamples) + for i := range data { + data[i][0] = rand.Float64()*2 - 1 + data[i][1] = rand.Float64()*2 - 1 + } + return &dataStreamer{data, 0}, data +} + +type dataStreamer struct { + data [][2]float64 + pos int +} + +func (ds *dataStreamer) Stream(samples [][2]float64) (n int, ok bool) { + if ds.pos >= len(ds.data) { + return 0, false + } + n = copy(samples, ds.data[ds.pos:]) + ds.pos += n + return n, true +} + +func (ds *dataStreamer) Err() error { + return nil +} + +func (ds *dataStreamer) Len() int { + return len(ds.data) +} + +func (ds *dataStreamer) Position() int { + return ds.pos +} + +func (ds *dataStreamer) Seek(p int) error { + ds.pos = p + return nil +} diff --git a/resample_test.go b/resample_test.go index 08e7add..2d5ed3d 100644 --- a/resample_test.go +++ b/resample_test.go @@ -5,6 +5,7 @@ import ( "testing" "github.com/gopxl/beep" + "github.com/gopxl/beep/internal/testtools" ) func TestResample(t *testing.T) { @@ -15,11 +16,11 @@ func TestResample(t *testing.T) { continue // skip too expensive combinations } - s, data := randomDataStreamer(numSamples) + s, data := testtools.RandomDataStreamer(numSamples) want := resampleCorrect(3, old, new, data) - got := collect(beep.Resample(3, old, new, s)) + got := testtools.Collect(beep.Resample(3, old, new, s)) if !reflect.DeepEqual(want, got) { t.Fatal("Resample not working correctly") From 4ce3936eceec2d747aa17fc3041500df362d02f5 Mon Sep 17 00:00:00 2001 From: Mark Kremer Date: Wed, 1 Nov 2023 15:15:45 +0100 Subject: [PATCH 7/9] Add test for flac.Decoder.Stream --- flac/decode_test.go | 35 ++++++++++++++++++ .../testdata/valid_44100hz_22050_samples.flac | Bin 0 -> 17081 bytes internal/testtools/sinks.go | 5 +++ internal/testtools/testdata.go | 16 ++++++++ 4 files changed, 56 insertions(+) create mode 100644 flac/decode_test.go create mode 100644 internal/testdata/valid_44100hz_22050_samples.flac create mode 100644 internal/testtools/testdata.go diff --git a/flac/decode_test.go b/flac/decode_test.go new file mode 100644 index 0000000..ff6d140 --- /dev/null +++ b/flac/decode_test.go @@ -0,0 +1,35 @@ +package flac_test + +import ( + "github.com/gopxl/beep/flac" + "github.com/gopxl/beep/internal/testtools" + "github.com/stretchr/testify/assert" + "os" + "testing" +) + +func TestDecoder_Stream(t *testing.T) { + f, err := os.Open(testtools.TestFilePath("valid_44100hz_22050_samples.flac")) + assert.NoError(t, err) + defer f.Close() + + streamer, _, err := flac.Decode(f) + assert.NoError(t, err) + + // Case 1: return ok with all requested samples + buf := testtools.CollectNum(22000, streamer) + assert.Lenf(t, buf, 22000, "streamer quit prematurely; expected %d samples, got %d", 22000, len(buf)) + assert.NoError(t, streamer.Err()) + + buf = make([][2]float64, 512) + + // Case 2: return ok with 0 < n < 512 samples + n, ok := streamer.Stream(buf[:]) + assert.True(t, ok) + assert.Equal(t, 50, n) + + // Case 3: return !ok with n == 0 + n, ok = streamer.Stream(buf[:]) + assert.False(t, ok) + assert.Equal(t, 0, n) +} diff --git a/internal/testdata/valid_44100hz_22050_samples.flac b/internal/testdata/valid_44100hz_22050_samples.flac new file mode 100644 index 0000000000000000000000000000000000000000..b6dd4315c1cfea0fad3fac8eb9e006ba804dd7d8 GIT binary patch literal 17081 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

Kdiu58P{R&1c!8lJf<+8G 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 oq?${i>YpK_2=Jz Date: Wed, 1 Nov 2023 15:20:18 +0100 Subject: [PATCH 8/9] Organize imports --- compositors_test.go | 2 +- flac/decode.go | 3 ++- flac/decode_test.go | 8 +++++--- internal/testtools/streamers.go | 3 ++- 4 files changed, 10 insertions(+), 6 deletions(-) diff --git a/compositors_test.go b/compositors_test.go index 94759fe..53b9dd5 100644 --- a/compositors_test.go +++ b/compositors_test.go @@ -1,12 +1,12 @@ package beep_test import ( - "github.com/gopxl/beep/internal/testtools" "math/rand" "reflect" "testing" "github.com/gopxl/beep" + "github.com/gopxl/beep/internal/testtools" ) func TestTake(t *testing.T) { diff --git a/flac/decode.go b/flac/decode.go index c939e27..324172b 100644 --- a/flac/decode.go +++ b/flac/decode.go @@ -4,9 +4,10 @@ import ( "fmt" "io" - "github.com/gopxl/beep" "github.com/mewkiz/flac" "github.com/pkg/errors" + + "github.com/gopxl/beep" ) // Decode takes a Reader containing audio data in FLAC format and returns a StreamSeekCloser, diff --git a/flac/decode_test.go b/flac/decode_test.go index ff6d140..0206a6f 100644 --- a/flac/decode_test.go +++ b/flac/decode_test.go @@ -1,11 +1,13 @@ package flac_test import ( - "github.com/gopxl/beep/flac" - "github.com/gopxl/beep/internal/testtools" - "github.com/stretchr/testify/assert" "os" "testing" + + "github.com/stretchr/testify/assert" + + "github.com/gopxl/beep/flac" + "github.com/gopxl/beep/internal/testtools" ) func TestDecoder_Stream(t *testing.T) { diff --git a/internal/testtools/streamers.go b/internal/testtools/streamers.go index 693793a..b59f873 100644 --- a/internal/testtools/streamers.go +++ b/internal/testtools/streamers.go @@ -1,8 +1,9 @@ package testtools import ( - "github.com/gopxl/beep" "math/rand" + + "github.com/gopxl/beep" ) // RandomDataStreamer generates numSamples random samples and returns a StreamSeeker to stream them. From 0d4fd3cded36d085ebc22b42bafcea68a53b2761 Mon Sep 17 00:00:00 2001 From: Mark Kremer Date: Wed, 1 Nov 2023 16:19:24 +0100 Subject: [PATCH 9/9] Test that the flac streamer doesn't return any errors as well --- flac/decode_test.go | 2 ++ 1 file changed, 2 insertions(+) diff --git a/flac/decode_test.go b/flac/decode_test.go index 0206a6f..4dd5dbd 100644 --- a/flac/decode_test.go +++ b/flac/decode_test.go @@ -29,9 +29,11 @@ func TestDecoder_Stream(t *testing.T) { n, ok := streamer.Stream(buf[:]) assert.True(t, ok) assert.Equal(t, 50, n) + assert.NoError(t, streamer.Err()) // Case 3: return !ok with n == 0 n, ok = streamer.Stream(buf[:]) assert.False(t, ok) assert.Equal(t, 0, n) + assert.NoError(t, streamer.Err()) }