@@ -31,18 +31,24 @@ const (
3131 SpectrumDefault = SpectrumLog
3232)
3333
34+ // misc coonstants
35+ const (
36+ MaxStreams = 2
37+ )
38+
3439// Spectrum is an audio spectrum in a buffer
3540type Spectrum struct {
36- numBins int // number of bins we look at
37- fftSize int // number of fft bins
38- sampleSize int // number of samples per slice
39- sType SpectrumType // the type of spectrum distribution
40- sampleRate float64 // audio sample rate
41- winVar float64 // window variable
42- smoothFactor float64 // smothing factor
43- fftBuf []complex128 // fft return buffer
44- bins []bin // bins for processing
45- streams []* stream // streams of data
41+ numBins int // number of bins we look at
42+ numStreams int // number of streams we process
43+ fftSize int // number of fft bins
44+ sampleSize int // number of samples per slice
45+ sType SpectrumType // the type of spectrum distribution
46+ sampleRate float64 // audio sample rate
47+ winVar float64 // window variable
48+ smoothFactor float64 // smothing factor
49+ fftBuf []complex128 // fft return buffer
50+ bins []bin // bins for processing
51+ streams [MaxStreams ]stream // streams of data
4652}
4753
4854type bin struct {
@@ -81,18 +87,15 @@ func NewSpectrum(hz float64, size int) *Spectrum {
8187
8288 var fftSize = (size / 2 ) + 1
8389
84- var sp = & Spectrum {
90+ return & Spectrum {
8591 fftSize : fftSize ,
8692 sampleSize : size ,
8793 sampleRate : hz ,
88- smoothFactor : 0.1969 ,
94+ smoothFactor : 0.5069 ,
8995 winVar : 0.5 ,
9096 fftBuf : make ([]complex128 , fftSize ),
9197 bins : make ([]bin , size + 1 ),
92- streams : make ([]* stream , 0 , 2 ),
9398 }
94-
95- return sp
9699}
97100
98101// StreamCount returns the number of streams in our buffers
@@ -101,22 +104,22 @@ func (sp *Spectrum) StreamCount() int {
101104}
102105
103106// AddStream adds an input buffer to the spectrum
104- func (sp * Spectrum ) AddStream (input []float64 ) {
105- var s = & stream {
106- input : input ,
107- buf : make ([]float64 , sp .sampleSize ),
108- pBuf : make ([]float64 , sp .sampleSize ),
109- plan : fft .NewPlan (input , sp .fftBuf ),
107+ func (sp * Spectrum ) AddStream (input ... []float64 ) {
108+
109+ for idx := range input {
110+ sp .streams [idx ].input = input [idx ]
111+ sp .streams [idx ].buf = make ([]float64 , sp .sampleSize )
112+ sp .streams [idx ].pBuf = make ([]float64 , sp .sampleSize )
113+ sp .streams [idx ].plan = fft .NewPlan (input [idx ], sp .fftBuf )
114+ sp .numStreams ++
110115 }
111-
112- sp .streams = append (sp .streams , s )
113116}
114117
115118// BinBuffers returns our bin buffers
116119func (sp * Spectrum ) BinBuffers () [][]float64 {
117- var buf = make ([][]float64 , len ( sp .streams ) )
118- for idx , stream := range sp .streams {
119- buf [idx ] = stream .buf
120+ var buf = make ([][]float64 , sp .numStreams )
121+ for idx := range sp .streams [: sp . numStreams ] {
122+ buf [idx ] = sp . streams [ idx ] .buf
120123 }
121124
122125 return buf
@@ -129,18 +132,18 @@ func (sp *Spectrum) BinCount() int {
129132
130133// Process makes numBins and dumps them in the buffer
131134func (sp * Spectrum ) Process (win window.Function ) {
132- var sf = math .Pow (10.0 , (1 - sp .smoothFactor )* (- 10 .0 ))
135+ var sf = math .Pow (10.0 , (1.0 - sp .smoothFactor )* (- 20 .0 ))
133136
134137 sf = math .Pow (sf , float64 (sp .sampleSize )/ sp .sampleRate )
135138
136- var bassCut = sp .freqToIdx (Frequencies [2 ], math .Ceil )
139+ var bassCut = sp .freqToIdx (Frequencies [2 ], math .Floor )
137140 var fBassCut = float64 (bassCut )
138141
139- for _ , stream := range sp .streams {
142+ for idx := range sp .streams {
140143
141- win (stream .input )
144+ win (sp . streams [ idx ] .input )
142145
143- stream .plan .Execute ()
146+ sp . streams [ idx ] .plan .Execute ()
144147
145148 for xB := 0 ; xB < sp .numBins ; xB ++ {
146149 var mag = 0.0
@@ -164,6 +167,7 @@ func (sp *Spectrum) Process(win window.Function) {
164167
165168 case sp .bins [xB ].floorFFT < bassCut :
166169 pow *= math .Max (0.5 , float64 (xF )/ fBassCut )
170+
167171 }
168172
169173 mag *= sp .bins [xB ].eqVal
@@ -173,9 +177,9 @@ func (sp *Spectrum) Process(win window.Function) {
173177 // time smoothing
174178
175179 mag *= (1.0 - sf )
176- mag += stream .pBuf [xB ] * sf
177- stream .pBuf [xB ] = mag
178- stream .buf [xB ] = mag
180+ mag += sp . streams [ idx ] .pBuf [xB ] * sf
181+ sp . streams [ idx ] .pBuf [xB ] = mag
182+ sp . streams [ idx ] .buf [xB ] = mag
179183
180184 // mag += stream.pBuf[xB] * sp.smoothFactor
181185 // stream.pBuf[xB] = mag * (1 - (1 / (1 + (mag * 2))))
@@ -230,25 +234,24 @@ func (sp *Spectrum) Recalculate(bins int) int {
230234// it is a best guess naive attempt right now.
231235// i will continue work on it - winter
232236func (sp * Spectrum ) distributeLog (bins int ) {
233- var lo = ( Frequencies [1 ])
234- var hi = Frequencies [4 ]
237+ var lo = Frequencies [1 ]
238+ var hi = math . Min ( sp . sampleRate / 2 , Frequencies [4 ])
235239
236- var loLog = math .Log10 (lo )
237- var hiLog = math .Log10 (hi )
240+ // var loLog = math.Log10(lo)
241+ // var hiLog = math.Log10(hi)
238242
239- var cF = (hiLog - loLog ) / float64 (bins )
240-
241- var getBinBase = func (b int ) int {
242- var vFreq = ((float64 (b ) * cF ) + loLog )
243- vFreq = math .Pow (10.0 , vFreq )
244- return sp .freqToIdx (vFreq , math .Floor )
245- }
243+ // var cF = (hiLog - loLog) / float64(bins)
244+ var cF = math .Log10 (lo / hi ) / ((1 / float64 (bins )) - 1 )
246245
247246 var cCoef = 100.0 / float64 (bins + 1 )
248247
249248 for xB := 0 ; xB <= bins ; xB ++ {
250249
251- sp .bins [xB ].floorFFT = getBinBase (xB )
250+ // var vFreq = ((float64(b) * cF) + loLog)
251+ // vFreq = math.Pow(10.0, vFreq)
252+ var vFreq = ((float64 (xB ) / float64 (bins )) * cF ) - cF
253+ vFreq = math .Pow (10.0 , vFreq ) * hi
254+ sp .bins [xB ].floorFFT = sp .freqToIdx (vFreq , math .Floor )
252255 sp .bins [xB ].eqVal = math .Log2 (float64 (xB )+ 2 ) * cCoef
253256
254257 if xB > 0 {
0 commit comments