Convert to streaming channel-based output interface

This commit is contained in:
DataHoarder 2022-01-28 22:30:58 +01:00
parent 93f409e4d9
commit 4b361ff3da
2 changed files with 50 additions and 37 deletions

View file

@ -16,7 +16,7 @@ type Gaborator struct {
audioBlockSize int
bandcenterCache []float32
firstBandCache int
fixedCoefficents [][]float32
coefficientOutputChannel chan []float32
frequencyBinTimeStepSize int
bandsPerOctave int
coefficients [][]float32
@ -32,7 +32,6 @@ func NewGaborator(blockSize int, sampleRate float64, bandsPerOctave int, minimum
frequencyBinTimeStepSize: stepSize,
bandsPerOctave: bandsPerOctave,
mostRecentCoefficentIndex: 0,
fixedCoefficents: make([][]float32, 0, 16384), //preallocate
}
g.latency = int64(C.gaborator_get_anal_support(g.pointer))
@ -118,7 +117,7 @@ func (g *Gaborator) gaborTransform(audioData []float32) {
g.mostRecentCoefficentIndex = coefficientIndex
// "copy" the oldest data to the history
// the slice can be reused thanks to the oldest being filled with zeros just after
g.fixedCoefficents = append(g.fixedCoefficents, g.coefficients[circularIndex])
g.coefficientOutputChannel <- g.coefficients[circularIndex]
// fill the oldest with zeros
g.coefficients[circularIndex] = make([]float32, len(g.coefficients[circularIndex]))
}
@ -130,44 +129,58 @@ func (g *Gaborator) gaborTransform(audioData []float32) {
}
}
func (g *Gaborator) GaborBlockTransform(source chan []float32) [][]float32 {
func (g *Gaborator) GetChannel() chan []float32 {
for {
block, more := <-source
if !more {
break
}
err := g.Process(block)
if err != nil {
log.Panic(err)
}
if g.coefficientOutputChannel == nil {
g.coefficientOutputChannel = make(chan []float32)
}
g.ProcessingFinished()
return g.coefficients
return g.coefficientOutputChannel
}
func (g *Gaborator) GaborTransform(source chan float32) [][]float32 {
func (g *Gaborator) GaborBlockTransform(source chan []float32) (channel chan []float32) {
audioData := make([]float32, 0, g.audioBlockSize)
channel = g.GetChannel()
go func() {
defer g.ProcessingFinished()
for {
f, more := <-source
if !more {
break
for {
block, more := <-source
if !more {
break
}
err := g.Process(block)
if err != nil {
log.Panic(err)
}
}
audioData = append(audioData, f)
}()
for len(audioData) >= g.audioBlockSize {
g.gaborTransform(audioData[0:g.audioBlockSize])
audioData = audioData[:0]
return channel
}
func (g *Gaborator) GaborTransform(source chan float32) (channel chan []float32) {
channel = g.GetChannel()
go func() {
defer g.ProcessingFinished()
audioData := make([]float32, 0, g.audioBlockSize)
for {
f, more := <-source
if !more {
break
}
audioData = append(audioData, f)
for len(audioData) >= g.audioBlockSize {
g.gaborTransform(audioData[0:g.audioBlockSize])
audioData = audioData[:0]
}
}
}
}()
g.ProcessingFinished()
return g.coefficients
return channel
}
func (g *Gaborator) Process(block []float32) error {
@ -182,6 +195,10 @@ func (g *Gaborator) ProcessingFinished() {
C.gaborator_release(g.pointer)
g.pointer = nil
}
if g.coefficientOutputChannel != nil {
close(g.coefficientOutputChannel)
g.coefficientOutputChannel = nil
}
}
func (g *Gaborator) GetStepSize() int {
@ -196,10 +213,6 @@ func (g *Gaborator) GetSampleRate() float64 {
return g.sampleRate
}
func (g *Gaborator) GetCoefficients() [][]float32 {
return g.fixedCoefficents
}
func (g *Gaborator) GetBandwidth() float64 {
return 1200. / float64(g.bandsPerOctave)
}

View file

@ -33,10 +33,10 @@ func TestGoborator(t *testing.T) {
}
}()
ob.GaborTransform(channel)
for i, c := range ob.GetCoefficients() {
var i = 0
for c := range ob.GaborTransform(channel) {
fmt.Printf("%d: %+F\n", i, c)
i++
}
}