diff --git a/goborator.go b/goborator.go index 187cc41..be9ca3c 100644 --- a/goborator.go +++ b/goborator.go @@ -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) } diff --git a/goborator_test.go b/goborator_test.go index b1f8a6b..605e981 100644 --- a/goborator_test.go +++ b/goborator_test.go @@ -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++ } }