Data copy/slice optimizations
This commit is contained in:
parent
481f5df794
commit
93f409e4d9
26
goborator.go
26
goborator.go
|
@ -16,7 +16,6 @@ type Gaborator struct {
|
||||||
audioBlockSize int
|
audioBlockSize int
|
||||||
bandcenterCache []float32
|
bandcenterCache []float32
|
||||||
firstBandCache int
|
firstBandCache int
|
||||||
audioDataToTransform []float32
|
|
||||||
fixedCoefficents [][]float32
|
fixedCoefficents [][]float32
|
||||||
frequencyBinTimeStepSize int
|
frequencyBinTimeStepSize int
|
||||||
bandsPerOctave int
|
bandsPerOctave int
|
||||||
|
@ -30,10 +29,10 @@ func NewGaborator(blockSize int, sampleRate float64, bandsPerOctave int, minimum
|
||||||
pointer: unsafe.Pointer(C.gaborator_initialize(C.double(sampleRate), C.int(bandsPerOctave), C.double(minimumFrequency), C.double(referenceFrequency), C.double(maximumFrequency))),
|
pointer: unsafe.Pointer(C.gaborator_initialize(C.double(sampleRate), C.int(bandsPerOctave), C.double(minimumFrequency), C.double(referenceFrequency), C.double(maximumFrequency))),
|
||||||
sampleRate: sampleRate,
|
sampleRate: sampleRate,
|
||||||
audioBlockSize: blockSize,
|
audioBlockSize: blockSize,
|
||||||
audioDataToTransform: make([]float32, blockSize),
|
|
||||||
frequencyBinTimeStepSize: stepSize,
|
frequencyBinTimeStepSize: stepSize,
|
||||||
bandsPerOctave: bandsPerOctave,
|
bandsPerOctave: bandsPerOctave,
|
||||||
mostRecentCoefficentIndex: 0,
|
mostRecentCoefficentIndex: 0,
|
||||||
|
fixedCoefficents: make([][]float32, 0, 16384), //preallocate
|
||||||
}
|
}
|
||||||
|
|
||||||
g.latency = int64(C.gaborator_get_anal_support(g.pointer))
|
g.latency = int64(C.gaborator_get_anal_support(g.pointer))
|
||||||
|
@ -101,7 +100,7 @@ func (g *Gaborator) gaborTransform(audioData []float32) {
|
||||||
for i := 0; i < len(analysisResult); i += 3 {
|
for i := 0; i < len(analysisResult); i += 3 {
|
||||||
band := int(analysisResult[i])
|
band := int(analysisResult[i])
|
||||||
audioSample := int(analysisResult[i+1])
|
audioSample := int(analysisResult[i+1])
|
||||||
coefficient := analysisResult[i+2]
|
coefficient := float32(analysisResult[i+2])
|
||||||
|
|
||||||
coefficientIndex := audioSample/g.frequencyBinTimeStepSize - g.coefficientIndexOffset
|
coefficientIndex := audioSample/g.frequencyBinTimeStepSize - g.coefficientIndexOffset
|
||||||
bandIndex := band - g.firstBandCache
|
bandIndex := band - g.firstBandCache
|
||||||
|
@ -117,14 +116,11 @@ func (g *Gaborator) gaborTransform(audioData []float32) {
|
||||||
if coefficientIndex > g.mostRecentCoefficentIndex && coefficientIndex > len(g.coefficients) {
|
if coefficientIndex > g.mostRecentCoefficentIndex && coefficientIndex > len(g.coefficients) {
|
||||||
// keep the new maximum
|
// keep the new maximum
|
||||||
g.mostRecentCoefficentIndex = coefficientIndex
|
g.mostRecentCoefficentIndex = coefficientIndex
|
||||||
// copy the oldest data to the history
|
// "copy" the oldest data to the history
|
||||||
g.fixedCoefficents = append(g.fixedCoefficents, make([]float32, len(g.coefficients[circularIndex])))
|
// the slice can be reused thanks to the oldest being filled with zeros just after
|
||||||
copy(g.fixedCoefficents[len(g.fixedCoefficents)-1], g.coefficients[circularIndex])
|
g.fixedCoefficents = append(g.fixedCoefficents, g.coefficients[circularIndex])
|
||||||
|
|
||||||
// fill the oldest with zeros
|
// fill the oldest with zeros
|
||||||
for j := range g.coefficients[circularIndex] {
|
g.coefficients[circularIndex] = make([]float32, len(g.coefficients[circularIndex]))
|
||||||
g.coefficients[circularIndex][j] = 0.
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
// due to reduction in precision (from audio sample accuracy to steps) multiple
|
// due to reduction in precision (from audio sample accuracy to steps) multiple
|
||||||
// magnitudes could be placed in the same stepIndex, bandIndex pair.
|
// magnitudes could be placed in the same stepIndex, bandIndex pair.
|
||||||
|
@ -212,18 +208,12 @@ func (g *Gaborator) GetLatency() int64 {
|
||||||
return g.latency
|
return g.latency
|
||||||
}
|
}
|
||||||
|
|
||||||
func (g *Gaborator) analyze(block []float32) []float32 {
|
func (g *Gaborator) analyze(block []float32) []C.float {
|
||||||
//log.Printf("analyze block len %d", len(block))
|
//log.Printf("analyze block len %d", len(block))
|
||||||
C.gaborator_analyze(g.pointer, (*C.float)(&block[0]), C.int(len(block)))
|
C.gaborator_analyze(g.pointer, (*C.float)(&block[0]), C.int(len(block)))
|
||||||
cSize := uintptr(C.gaborator_get_array_length(g.pointer))
|
cSize := uintptr(C.gaborator_get_array_length(g.pointer))
|
||||||
|
|
||||||
//log.Print(cSize)
|
//log.Print(cSize)
|
||||||
ptr := (*C.float)(C.gaborator_get_array(g.pointer))
|
ptr := (*C.float)(C.gaborator_get_array(g.pointer))
|
||||||
|
return unsafe.Slice(ptr, cSize)
|
||||||
result := make([]float32, cSize)
|
|
||||||
for i, v := range unsafe.Slice(ptr, cSize) {
|
|
||||||
result[i] = float32(v)
|
|
||||||
}
|
|
||||||
|
|
||||||
return result
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
package goborator
|
package goborator
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"encoding/binary"
|
||||||
"fmt"
|
"fmt"
|
||||||
"os"
|
"os"
|
||||||
"testing"
|
"testing"
|
||||||
|
@ -15,8 +16,27 @@ func TestGoborator(t *testing.T) {
|
||||||
t.Error(err)
|
t.Error(err)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
ob.GaborTransform(file)
|
|
||||||
|
channel := make(chan float32)
|
||||||
|
|
||||||
|
go func() {
|
||||||
|
defer close(channel)
|
||||||
|
defer file.Close()
|
||||||
|
|
||||||
|
var f float32
|
||||||
|
for {
|
||||||
|
err = binary.Read(file, binary.LittleEndian, &f)
|
||||||
|
if err != nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
channel <- f
|
||||||
|
}
|
||||||
|
}()
|
||||||
|
|
||||||
|
ob.GaborTransform(channel)
|
||||||
|
|
||||||
for i, c := range ob.GetCoefficients() {
|
for i, c := range ob.GetCoefficients() {
|
||||||
fmt.Printf("%d: %+F\n", i, c)
|
fmt.Printf("%d: %+F\n", i, c)
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue