Cleanup filters, added BlockSizeFilter
This commit is contained in:
parent
1ba15ccf52
commit
393e1d9401
|
@ -52,48 +52,84 @@ func NewBufferFilter(blockBufferSize int) BufferFilter {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func bufferFilterHelper[T audio.AllowedSourceTypes](source audio.TypedSource[T], blockBufferSize int) audio.TypedSource[T] {
|
||||||
|
outBlocks := make(chan []T, blockBufferSize)
|
||||||
|
go func() {
|
||||||
|
defer close(outBlocks)
|
||||||
|
for block := range source.GetBlocks() {
|
||||||
|
outBlocks <- block
|
||||||
|
}
|
||||||
|
}()
|
||||||
|
|
||||||
|
newSource := audio.NewSource[T](source.GetBitDepth(), source.GetSampleRate(), source.GetChannels())
|
||||||
|
close(newSource.SwapBlocks(outBlocks))
|
||||||
|
return newSource
|
||||||
|
}
|
||||||
|
|
||||||
func (f BufferFilter) Process(source audio.Source) audio.Source {
|
func (f BufferFilter) Process(source audio.Source) audio.Source {
|
||||||
if floatSource, ok := source.(audio.TypedSource[float32]); ok {
|
if floatSource, ok := source.(audio.TypedSource[float32]); ok {
|
||||||
outBlocks := make(chan []float32, f.blockBufferSize)
|
return bufferFilterHelper(floatSource, f.blockBufferSize)
|
||||||
go func() {
|
|
||||||
defer close(outBlocks)
|
|
||||||
for block := range floatSource.GetBlocks() {
|
|
||||||
outBlocks <- block
|
|
||||||
}
|
|
||||||
}()
|
|
||||||
|
|
||||||
newSource := audio.NewSource[float32](source.GetBitDepth(), source.GetSampleRate(), source.GetChannels())
|
|
||||||
close(newSource.SwapBlocks(outBlocks))
|
|
||||||
return newSource
|
|
||||||
} else if int16Source, ok := source.(audio.TypedSource[int16]); ok {
|
} else if int16Source, ok := source.(audio.TypedSource[int16]); ok {
|
||||||
outBlocks := make(chan []int16, f.blockBufferSize)
|
return bufferFilterHelper(int16Source, f.blockBufferSize)
|
||||||
go func() {
|
|
||||||
defer close(outBlocks)
|
|
||||||
for block := range int16Source.GetBlocks() {
|
|
||||||
outBlocks <- block
|
|
||||||
}
|
|
||||||
}()
|
|
||||||
|
|
||||||
newSource := audio.NewSource[int16](source.GetBitDepth(), source.GetSampleRate(), source.GetChannels())
|
|
||||||
close(newSource.SwapBlocks(outBlocks))
|
|
||||||
return newSource
|
|
||||||
} else if int32Source, ok := source.(audio.TypedSource[int32]); ok {
|
} else if int32Source, ok := source.(audio.TypedSource[int32]); ok {
|
||||||
outBlocks := make(chan []int32, f.blockBufferSize)
|
return bufferFilterHelper(int32Source, f.blockBufferSize)
|
||||||
go func() {
|
|
||||||
defer close(outBlocks)
|
|
||||||
for block := range int32Source.GetBlocks() {
|
|
||||||
outBlocks <- block
|
|
||||||
}
|
|
||||||
}()
|
|
||||||
|
|
||||||
newSource := audio.NewSource[int32](source.GetBitDepth(), source.GetSampleRate(), source.GetChannels())
|
|
||||||
close(newSource.SwapBlocks(outBlocks))
|
|
||||||
return newSource
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return source
|
return source
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type BlockSizeFilter struct {
|
||||||
|
blockSize int
|
||||||
|
}
|
||||||
|
|
||||||
|
func NewBlockSizeFilter(blockSize int) BlockSizeFilter {
|
||||||
|
return BlockSizeFilter{
|
||||||
|
blockSize: blockSize,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func blockSizeFilterHelper[T audio.AllowedSourceTypes](source audio.TypedSource[T], blockSize int) audio.TypedSource[T] {
|
||||||
|
|
||||||
|
bs := blockSize * source.GetChannels()
|
||||||
|
|
||||||
|
outSource := audio.NewSource[T](source.GetBitDepth(), source.GetSampleRate(), source.GetChannels())
|
||||||
|
go func() {
|
||||||
|
defer outSource.Close()
|
||||||
|
var buffer []T
|
||||||
|
buf := buffer
|
||||||
|
for block := range source.GetBlocks() {
|
||||||
|
buf = append(buf, block...)
|
||||||
|
for len(buf) >= bs {
|
||||||
|
outSource.IngestNative(buf[:bs], source.GetBitDepth())
|
||||||
|
buf = buf[bs:]
|
||||||
|
}
|
||||||
|
|
||||||
|
if len(buf) == 0 {
|
||||||
|
//reuse resources
|
||||||
|
buf = buffer[:0]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if len(buf) > 0 {
|
||||||
|
outSource.IngestNative(buf, source.GetBitDepth())
|
||||||
|
}
|
||||||
|
}()
|
||||||
|
|
||||||
|
return outSource
|
||||||
|
}
|
||||||
|
|
||||||
|
func (f BlockSizeFilter) Process(source audio.Source) audio.Source {
|
||||||
|
if floatSource, ok := source.(audio.TypedSource[float32]); ok {
|
||||||
|
return blockSizeFilterHelper(floatSource, f.blockSize)
|
||||||
|
} else if int16Source, ok := source.(audio.TypedSource[int16]); ok {
|
||||||
|
return blockSizeFilterHelper(int16Source, f.blockSize)
|
||||||
|
} else if int32Source, ok := source.(audio.TypedSource[int32]); ok {
|
||||||
|
return blockSizeFilterHelper(int32Source, f.blockSize)
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
type RealTimeFilter struct {
|
type RealTimeFilter struct {
|
||||||
blocksPerSecond int
|
blocksPerSecond int
|
||||||
}
|
}
|
||||||
|
@ -104,71 +140,33 @@ func NewRealTimeFilter(blocksPerSecond int) RealTimeFilter {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func realTimeFilterHelper[T audio.AllowedSourceTypes](source audio.TypedSource[T], blocksPerSecond int) audio.TypedSource[T] {
|
||||||
|
blockSize := source.GetSampleRate() / blocksPerSecond
|
||||||
|
throttler := time.Tick(time.Second / time.Duration(blocksPerSecond))
|
||||||
|
|
||||||
|
outSource := audio.NewSource[T](source.GetBitDepth(), source.GetSampleRate(), source.GetChannels())
|
||||||
|
go func() {
|
||||||
|
defer outSource.Close()
|
||||||
|
for block := range NewBlockSizeFilter(blockSize).Process(source).(audio.TypedSource[T]).GetBlocks() {
|
||||||
|
outSource.IngestNative(block, source.GetBitDepth())
|
||||||
|
<-throttler
|
||||||
|
}
|
||||||
|
}()
|
||||||
|
|
||||||
|
return outSource
|
||||||
|
}
|
||||||
|
|
||||||
func (f RealTimeFilter) Process(source audio.Source) audio.Source {
|
func (f RealTimeFilter) Process(source audio.Source) audio.Source {
|
||||||
if source.GetSampleRate()%f.blocksPerSecond != 0 {
|
if source.GetSampleRate()%f.blocksPerSecond != 0 {
|
||||||
log.Panicf("%d %% %d != 0", source.GetSampleRate(), f.blocksPerSecond)
|
log.Panicf("%d %% %d != 0", source.GetSampleRate(), f.blocksPerSecond)
|
||||||
}
|
}
|
||||||
blockSize := (source.GetSampleRate() / f.blocksPerSecond) * source.GetChannels()
|
|
||||||
throttler := time.Tick(time.Second / time.Duration(f.blocksPerSecond))
|
|
||||||
|
|
||||||
if floatSource, ok := source.(audio.TypedSource[float32]); ok {
|
if floatSource, ok := source.(audio.TypedSource[float32]); ok {
|
||||||
outSource := audio.NewSource[float32](source.GetBitDepth(), source.GetSampleRate(), source.GetChannels())
|
return realTimeFilterHelper(floatSource, f.blocksPerSecond)
|
||||||
go func() {
|
|
||||||
defer outSource.Close()
|
|
||||||
var buf []float32
|
|
||||||
for block := range floatSource.GetBlocks() {
|
|
||||||
buf = append(buf, block...)
|
|
||||||
for len(buf) >= blockSize {
|
|
||||||
outSource.IngestFloat32(buf[0:blockSize])
|
|
||||||
buf = buf[blockSize:]
|
|
||||||
<-throttler
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
outSource.IngestFloat32(buf)
|
|
||||||
}()
|
|
||||||
|
|
||||||
return outSource
|
|
||||||
} else if int16Source, ok := source.(audio.TypedSource[int16]); ok {
|
} else if int16Source, ok := source.(audio.TypedSource[int16]); ok {
|
||||||
bitDepth := source.GetBitDepth()
|
return realTimeFilterHelper(int16Source, f.blocksPerSecond)
|
||||||
if bitDepth > 16 {
|
|
||||||
bitDepth = 16
|
|
||||||
}
|
|
||||||
outSource := audio.NewSource[int16](bitDepth, source.GetSampleRate(), source.GetChannels())
|
|
||||||
go func() {
|
|
||||||
defer outSource.Close()
|
|
||||||
var buf []int16
|
|
||||||
for block := range int16Source.GetBlocks() {
|
|
||||||
buf = append(buf, block...)
|
|
||||||
for len(buf) >= blockSize {
|
|
||||||
outSource.IngestInt16(buf[0:blockSize], bitDepth)
|
|
||||||
buf = buf[blockSize:]
|
|
||||||
<-throttler
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
outSource.IngestInt16(buf, source.GetBitDepth())
|
|
||||||
}()
|
|
||||||
|
|
||||||
return outSource
|
|
||||||
} else if int32Source, ok := source.(audio.TypedSource[int32]); ok {
|
} else if int32Source, ok := source.(audio.TypedSource[int32]); ok {
|
||||||
outSource := audio.NewSource[int32](source.GetBitDepth(), source.GetSampleRate(), source.GetChannels())
|
return realTimeFilterHelper(int32Source, f.blocksPerSecond)
|
||||||
go func() {
|
|
||||||
defer outSource.Close()
|
|
||||||
var buf []int32
|
|
||||||
for block := range int32Source.GetBlocks() {
|
|
||||||
buf = append(buf, block...)
|
|
||||||
for len(buf) >= blockSize {
|
|
||||||
outSource.IngestInt32(buf[0:blockSize], source.GetBitDepth())
|
|
||||||
buf = buf[blockSize:]
|
|
||||||
<-throttler
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
outSource.IngestInt32(buf, source.GetBitDepth())
|
|
||||||
}()
|
|
||||||
|
|
||||||
return outSource
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
|
|
Loading…
Reference in a new issue