64 lines
1.2 KiB
Go
64 lines
1.2 KiB
Go
|
package audio
|
||
|
|
||
|
import (
|
||
|
"sync/atomic"
|
||
|
"time"
|
||
|
)
|
||
|
|
||
|
type Sink interface {
|
||
|
Process(source Source)
|
||
|
}
|
||
|
|
||
|
type NullSink struct {
|
||
|
Sink
|
||
|
}
|
||
|
|
||
|
func NewNullSink() *NullSink {
|
||
|
return &NullSink{}
|
||
|
}
|
||
|
|
||
|
func (n *NullSink) Process(source Source) {
|
||
|
for range source.Blocks {
|
||
|
|
||
|
}
|
||
|
}
|
||
|
|
||
|
type ForwardSink struct {
|
||
|
Sink
|
||
|
Target Sink
|
||
|
SamplesRead int64
|
||
|
Duration time.Duration
|
||
|
}
|
||
|
|
||
|
func NewForwardSink(target Sink) *ForwardSink {
|
||
|
return &ForwardSink{
|
||
|
Target: target,
|
||
|
}
|
||
|
}
|
||
|
|
||
|
func (n *ForwardSink) GetDuration() time.Duration {
|
||
|
return time.Duration(atomic.LoadInt64((*int64)(&n.Duration)))
|
||
|
}
|
||
|
|
||
|
func (n *ForwardSink) GetSamplesRead() int64 {
|
||
|
return atomic.LoadInt64(&n.SamplesRead)
|
||
|
}
|
||
|
|
||
|
func (n *ForwardSink) Process(source Source) {
|
||
|
processor := Source{
|
||
|
Channels: source.Channels,
|
||
|
SampleRate: source.SampleRate,
|
||
|
Blocks: make(chan []float32),
|
||
|
}
|
||
|
go func() {
|
||
|
defer close(processor.Blocks)
|
||
|
for block := range source.Blocks {
|
||
|
atomic.AddInt64((*int64)(&n.Duration), int64((time.Second*time.Duration(len(block)/source.Channels))/time.Duration(source.SampleRate)))
|
||
|
atomic.AddInt64(&n.SamplesRead, int64(len(block)/source.Channels))
|
||
|
processor.Blocks <- block
|
||
|
}
|
||
|
}()
|
||
|
|
||
|
n.Target.Process(processor)
|
||
|
}
|