Kirika/audio/sink.go

61 lines
1.2 KiB
Go
Raw Normal View History

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) {
//TODO: native process
for range source.ToFloat32().GetBlocks() {
}
}
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 := NewFloat32Source(source.GetSampleRate(), source.GetChannels())
go func() {
defer processor.Close()
for block := range source.ToFloat32().GetBlocks() {
atomic.AddInt64((*int64)(&n.Duration), int64((time.Second*time.Duration(len(block)/source.GetChannels()))/time.Duration(source.GetSampleRate())))
atomic.AddInt64(&n.SamplesRead, int64(len(block)/source.GetChannels()))
processor.IngestFloat32(block)
}
}()
n.Target.Process(processor)
}