Skip to content

Commit d206f68

Browse files
committed
make the analyzer more configurable
1 parent 9b9c9f0 commit d206f68

File tree

2 files changed

+37
-12
lines changed

2 files changed

+37
-12
lines changed

cmd/catnip/main.go

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -62,12 +62,15 @@ func catnip(cfg *config) error {
6262
Analyzer: dsp.NewAnalyzer(dsp.AnalyzerConfig{
6363
SampleRate: cfg.sampleRate,
6464
SampleSize: cfg.sampleSize,
65+
SquashLow: true,
66+
BinMethod: dsp.MaxSamples,
6567
}),
6668
Output: display,
6769
Smoother: dsp.NewSmoother(dsp.SmootherConfig{
6870
SampleSize: cfg.sampleSize,
6971
ChannelCount: cfg.channelCount,
70-
SmoothingFactor: cfg.smoothFactor}),
72+
SmoothingFactor: cfg.smoothFactor,
73+
}),
7174
Windower: window.Lanczos,
7275
}
7376

dsp/analyzer.go

Lines changed: 33 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -7,15 +7,18 @@
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
1211
package dsp
1312

1413
import "math"
1514

15+
type BinMethod func(int, float64, float64) float64
16+
1617
type 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

2124
type 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+
6182
func NewAnalyzer(cfg AnalyzerConfig) Analyzer {
6283
return &analyzer{
6384
cfg: cfg,
@@ -72,7 +93,6 @@ func (az *analyzer) BinCount() int {
7293
}
7394

7495
func (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

Comments
 (0)