From d6408797755878783623690eeed2a6c1da909d73 Mon Sep 17 00:00:00 2001 From: faiface Date: Wed, 5 Jul 2017 18:14:18 +0200 Subject: [PATCH] add Take decorator function --- audio/compositors.go | 23 +++++++++++++++++++++++ audio/compositors_test.go | 16 ++++++++++++++++ 2 files changed, 39 insertions(+) diff --git a/audio/compositors.go b/audio/compositors.go index bb4740f..ceed138 100644 --- a/audio/compositors.go +++ b/audio/compositors.go @@ -1,5 +1,28 @@ package audio +import ( + "math" + "time" +) + +// Take returns a Streamer which streams s for at most d duration. +func Take(d time.Duration, s Streamer) Streamer { + currSample := 0 + numSamples := int(math.Ceil(d.Seconds() * SampleRate)) + return StreamerFunc(func(samples [][2]float64) (n int, ok bool) { + if currSample >= numSamples { + return 0, false + } + toStream := numSamples - currSample + if len(samples) < toStream { + toStream = len(samples) + } + sn, sok := s.Stream(samples[:toStream]) + currSample += sn + return sn, sok + }) +} + // Seq takes zero or more Streamers and returns a Streamer which streams them one by one without pauses. func Seq(s ...Streamer) Streamer { i := 0 diff --git a/audio/compositors_test.go b/audio/compositors_test.go index 4114b92..450430b 100644 --- a/audio/compositors_test.go +++ b/audio/compositors_test.go @@ -44,6 +44,22 @@ func collect(s audio.Streamer) [][2]float64 { } } +func TestTake(t *testing.T) { + for i := 0; i < 7; i++ { + total := time.Nanosecond * time.Duration(1e8+rand.Intn(1e9)) + s, data := randomDataStreamer(total) + d := time.Nanosecond * time.Duration(rand.Int63n(total.Nanoseconds())) + numSamples := int(math.Ceil(d.Seconds() * audio.SampleRate)) + + want := data[:numSamples] + got := collect(audio.Take(d, s)) + + if !reflect.DeepEqual(want, got) { + t.Error("Take not working correctly") + } + } +} + func TestSeq(t *testing.T) { var ( s = make([]audio.Streamer, 7)