From 33c6f0ca5d47e8b21c75c5c61ff4d21a6d9bcec2 Mon Sep 17 00:00:00 2001 From: faiface Date: Fri, 7 Jul 2017 18:46:26 +0200 Subject: [PATCH] audio: add Mixer --- audio/mixer.go | 51 ++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 51 insertions(+) create mode 100644 audio/mixer.go diff --git a/audio/mixer.go b/audio/mixer.go new file mode 100644 index 0000000..1c0c3a3 --- /dev/null +++ b/audio/mixer.go @@ -0,0 +1,51 @@ +package audio + +type Mixer struct { + streamers []Streamer +} + +func (m *Mixer) Play(s ...Streamer) { + m.streamers = append(m.streamers, s...) +} + +func (m *Mixer) Stream(samples [][2]float64) (n int, ok bool) { + var tmp, mix [512][2]float64 + + for len(samples) > 0 { + toStream := len(mix) + if toStream > len(samples) { + toStream = len(samples) + } + + // clear the mix buffer + for i := range mix[:toStream] { + mix[i] = [2]float64{} + } + + for si := 0; si < len(m.streamers); si++ { + // mix the stream + sn, sok := m.streamers[si].Stream(tmp[:toStream]) + for i := range tmp[:sn] { + mix[i][0] += tmp[i][0] + mix[i][1] += tmp[i][1] + } + if !sok { + // remove drained streamer + sj := len(m.streamers) - 1 + m.streamers[si], m.streamers[sj] = m.streamers[sj], m.streamers[si] + m.streamers = m.streamers[:sj] + si-- + } + } + + // copy mix buffer into samples + for i := range mix[:toStream] { + samples[i] = mix[i] + } + + samples = samples[toStream:] + n += toStream + } + + return n, true +}