77// https://github.com/hvianna/audioMotion-analyzer/blob/master/src/audioMotion-analyzer.js#L1053
88// https://dsp.stackexchange.com/questions/6499/help-calculating-understanding-the-mfccs-mel-frequency-cepstrum-coefficients
99// https://stackoverflow.com/questions/3694918/how-to-extract-frequency-associated-with-fft-values-in-python
10- // - https://stackoverflow.com/a/27191172
11- //
10+ // - https://stackoverflow.com/a/27191172
1211package dsp
1312
1413import "math"
1514
15+ type BinMethod func (int , float64 , float64 ) float64
16+
1617type AnalyzerConfig struct {
17- SampleRate float64 // audio sample rate
18- SampleSize int // number of samples per slice
18+ SampleRate float64 // audio sample rate
19+ SampleSize int // number of samples per slice
20+ SquashLow bool // squash the low end the spectrum
21+ BinMethod BinMethod // method used for calculating bin value
1922}
2023
2124type Analyzer interface {
@@ -58,6 +61,24 @@ var frequencies = []float64{
5861 // everything else
5962}
6063
64+ // Average all the samples together
65+ func AverageSamples (count int , current , new float64 ) float64 {
66+ return current + (new / float64 (count ))
67+ }
68+
69+ // Sum all the samples together
70+ func SumSamples (count int , current , new float64 ) float64 {
71+ return current + new
72+ }
73+
74+ // Return the maximum value of all the samples
75+ func MaxSamples (count int , current , new float64 ) float64 {
76+ if current < new {
77+ return new
78+ }
79+ return current
80+ }
81+
6182func NewAnalyzer (cfg AnalyzerConfig ) Analyzer {
6283 return & analyzer {
6384 cfg : cfg ,
@@ -72,7 +93,6 @@ func (az *analyzer) BinCount() int {
7293}
7394
7495func (az * analyzer ) ProcessBin (idx int , src []complex128 ) float64 {
75- mag := 0.0
7696 bin := az .bins [idx ]
7797
7898 fftFloor , fftCeil := bin .floorFFT , bin .ceilFFT
@@ -81,16 +101,18 @@ func (az *analyzer) ProcessBin(idx int, src []complex128) float64 {
81101 }
82102
83103 src = src [fftFloor :fftCeil ]
104+ mag := 0.0
105+ count := len (src )
84106 for _ , cmplx := range src {
85107 power := math .Hypot (real (cmplx ), imag (cmplx ))
86- if mag < power {
87- mag = power
88- }
108+ mag = az .cfg .BinMethod (count , mag , power )
89109 }
90110
91- // squash the low low end a bit.
92- if f := az .freqToIdx (400.0 , math .Floor ); fftFloor < f {
93- mag *= (0.55 * (float64 (fftFloor + 1 ) / float64 (f )))
111+ if az .cfg .SquashLow {
112+ // squash the low low end a bit.
113+ if f := az .freqToIdx (400.0 , math .Floor ); fftFloor < f {
114+ mag *= (0.55 * (float64 (fftFloor + 1 ) / float64 (f )))
115+ }
94116 }
95117
96118 if mag = math .Log (mag ); mag < 0.0 {
0 commit comments