go-opengl-pixel/audio/compositors.go

89 lines
1.9 KiB
Go
Raw Normal View History

2017-07-05 10:59:43 -05:00
package audio
2017-07-05 11:14:18 -05:00
import (
"math"
"time"
)
// Take returns a Streamer which streams s for at most d duration.
2017-07-11 16:42:57 -05:00
//
// TODO: should Take propagate an error?
2017-07-05 11:14:18 -05:00
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
})
}
2017-07-05 10:59:43 -05:00
// Seq takes zero or more Streamers and returns a Streamer which streams them one by one without pauses.
2017-07-11 16:42:57 -05:00
//
// Seq does not propagate errors from the Streamers.
2017-07-05 10:59:43 -05:00
func Seq(s ...Streamer) Streamer {
i := 0
return StreamerFunc(func(samples [][2]float64) (n int, ok bool) {
for i < len(s) && len(samples) > 0 {
sn, sok := s[i].Stream(samples)
samples = samples[sn:]
n, ok = n+sn, ok || sok
if !sok {
i++
}
}
return n, ok
})
}
2017-07-07 09:11:48 -05:00
// Mix takes zero or more Streamers and returns a Streamer which streames them mixed together.
2017-07-11 16:42:57 -05:00
//
// Mix does not propagate errors from the Streamers.
2017-07-07 09:11:48 -05:00
func Mix(s ...Streamer) Streamer {
return StreamerFunc(func(samples [][2]float64) (n int, ok bool) {
var tmp [512][2]float64
2017-07-07 09:11:48 -05:00
for len(samples) > 0 {
toStream := len(tmp)
2017-07-07 09:11:48 -05:00
if toStream > len(samples) {
toStream = len(samples)
}
// clear the samples
for i := range samples[:toStream] {
samples[i] = [2]float64{}
2017-07-07 09:11:48 -05:00
}
snMax := 0 // max number of streamed samples in this iteration
for _, st := range s {
// mix the stream
sn, sok := st.Stream(tmp[:toStream])
if sn > snMax {
snMax = sn
}
ok = ok || sok
for i := range tmp[:sn] {
samples[i][0] += tmp[i][0]
samples[i][1] += tmp[i][1]
2017-07-07 09:11:48 -05:00
}
}
n += snMax
if snMax < len(tmp) {
2017-07-07 09:11:48 -05:00
break
}
samples = samples[snMax:]
}
return n, ok
})
}