audio: add Err method to Streamer

This commit is contained in:
faiface 2017-07-11 23:42:57 +02:00
parent 35a24edbda
commit d1953900cc
4 changed files with 39 additions and 1 deletions

View File

@ -6,6 +6,8 @@ import (
) )
// Take returns a Streamer which streams s for at most d duration. // Take returns a Streamer which streams s for at most d duration.
//
// TODO: should Take propagate an error?
func Take(d time.Duration, s Streamer) Streamer { func Take(d time.Duration, s Streamer) Streamer {
currSample := 0 currSample := 0
numSamples := int(math.Ceil(d.Seconds() * SampleRate)) numSamples := int(math.Ceil(d.Seconds() * SampleRate))
@ -24,6 +26,8 @@ func Take(d time.Duration, s Streamer) Streamer {
} }
// Seq takes zero or more Streamers and returns a Streamer which streams them one by one without pauses. // Seq takes zero or more Streamers and returns a Streamer which streams them one by one without pauses.
//
// Seq does not propagate errors from the Streamers.
func Seq(s ...Streamer) Streamer { func Seq(s ...Streamer) Streamer {
i := 0 i := 0
return StreamerFunc(func(samples [][2]float64) (n int, ok bool) { return StreamerFunc(func(samples [][2]float64) (n int, ok bool) {
@ -40,6 +44,8 @@ func Seq(s ...Streamer) Streamer {
} }
// Mix takes zero or more Streamers and returns a Streamer which streames them mixed together. // Mix takes zero or more Streamers and returns a Streamer which streames them mixed together.
//
// Mix does not propagate errors from the Streamers.
func Mix(s ...Streamer) Streamer { func Mix(s ...Streamer) Streamer {
return StreamerFunc(func(samples [][2]float64) (n int, ok bool) { return StreamerFunc(func(samples [][2]float64) (n int, ok bool) {
var tmp [512][2]float64 var tmp [512][2]float64

View File

@ -22,3 +22,10 @@ func (c *Ctrl) Stream(samples [][2]float64) (n int, ok bool) {
c.Position += time.Duration(n) * time.Second / time.Duration(SampleRate) c.Position += time.Duration(n) * time.Second / time.Duration(SampleRate)
return n, ok return n, ok
} }
func (c *Ctrl) Err() error {
if c.Streamer == nil {
return nil
}
return c.Err()
}

View File

@ -28,13 +28,24 @@ type Streamer interface {
// 2. 0 < n && n < len(samples) && ok // 2. 0 < n && n < len(samples) && ok
// //
// Stream streamed n samples and drained the Streamer. Only case 3 may occur in the // Stream streamed n samples and drained the Streamer. Only case 3 may occur in the
// following calls. // following calls. If Err return a non-nil error, only this case is valid.
// //
// 3. n == 0 && !ok // 3. n == 0 && !ok
// //
// The Streamer is drained and no more samples will come. Only this case may occur in the // The Streamer is drained and no more samples will come. Only this case may occur in the
// following calls. // following calls.
Stream(samples [][2]float64) (n int, ok bool) Stream(samples [][2]float64) (n int, ok bool)
// Err returns an error which occured during streaming. If no error occured, nil is
// returned.
//
// When an error occurs, Streamer must become drained and Stream must return 0, false
// forever.
//
// The reason why Stream doesn't return an error is that it dramatically simplifies
// programming with Streamer. It's not very important to catch the error right when it
// happens.
Err() error
} }
// StreamerFunc is a Streamer created by simply wrapping a streaming function (usually a closure, // StreamerFunc is a Streamer created by simply wrapping a streaming function (usually a closure,
@ -55,3 +66,8 @@ type StreamerFunc func(samples [][2]float64) (n int, ok bool)
func (sf StreamerFunc) Stream(samples [][2]float64) (n int, ok bool) { func (sf StreamerFunc) Stream(samples [][2]float64) (n int, ok bool) {
return sf(samples) return sf(samples)
} }
// Err always returns nil.
func (sf StreamerFunc) Err() error {
return nil
}

View File

@ -54,3 +54,12 @@ func (m *Mixer) Stream(samples [][2]float64) (n int, ok bool) {
return n, true return n, true
} }
// Err always returns nil for Mixer.
//
// There are two reasons. The first one is that erroring Streamers are immediately drained and
// removed from the Mixer. The second one is that one Streamer shouldn't break the whole Mixer and
// you should handle the errors right where they can happen.
func (m *Mixer) Err() error {
return nil
}