Skip to content

Commit 39ddb20

Browse files
committed
i think you will like this one
1 parent c27614d commit 39ddb20

File tree

6 files changed

+165
-130
lines changed

6 files changed

+165
-130
lines changed

config.go

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -20,8 +20,8 @@ type Config struct {
2020
HiCutFreq float64
2121
// SmoothFactor factor of smooth
2222
SmoothFactor float64
23-
// Gamma factor of distribution
24-
Gamma float64
23+
// WinVar factor of distribution
24+
WinVar float64
2525
// BaseThick number of cells wide/high the base is
2626
BaseThick int
2727
// BarWidth is the width of bars, in columns
@@ -43,7 +43,7 @@ func NewZeroConfig() Config {
4343
return Config{
4444
SampleRate: 44100,
4545
SmoothFactor: 65.5,
46-
Gamma: 2.0,
46+
WinVar: 0.5,
4747
BaseThick: 1,
4848
BarWidth: 2,
4949
SpaceWidth: 1,
@@ -55,6 +55,11 @@ func NewZeroConfig() Config {
5555
}
5656

5757
func sanitizeConfig(cfg *Config) error {
58+
switch {
59+
case cfg.WinVar > 1.0:
60+
cfg.WinVar = 1.0
61+
default:
62+
}
5863

5964
switch {
6065
case cfg.SmoothFactor > 100.0:

dsp/spectrum.go

Lines changed: 101 additions & 90 deletions
Original file line numberDiff line numberDiff line change
@@ -10,25 +10,22 @@ import (
1010

1111
// Spectrum is an audio spectrum in a buffer
1212
type Spectrum struct {
13-
numBins int
14-
numStreams int
13+
numBins int
1514

1615
fftSize int
1716

1817
sampleSize int
1918
sampleRate float64
2019

21-
gamma float64
20+
winVar float64
2221

23-
smoothFact float64
24-
smoothResp float64
22+
smoothFactor float64
2523

2624
bins []bin
2725

2826
fftBuf []complex128
2927

30-
streams []*stream
31-
streamBufs [][]float64
28+
streams []*stream
3229
}
3330

3431
type bin struct {
@@ -46,6 +43,23 @@ type stream struct {
4643
plan *fft.Plan
4744
}
4845

46+
// Frequencies are the dividing frequencies
47+
var Frequencies = []float64{
48+
// sub sub bass
49+
20.0,
50+
// sub bass
51+
60.0,
52+
// bass
53+
250.0,
54+
// midrange
55+
4000.0,
56+
// treble
57+
12000.0,
58+
// brilliance
59+
22050.0,
60+
// everything else
61+
}
62+
4963
// SpectrumType is the type of calculation we run
5064
type SpectrumType int
5165

@@ -73,32 +87,63 @@ func NewSpectrum(hz float64, size int) *Spectrum {
7387
var fftSize = (size / 2) + 1
7488

7589
var sp = &Spectrum{
76-
numBins: size,
77-
fftSize: fftSize,
78-
sampleSize: size,
79-
sampleRate: hz,
80-
smoothFact: 0.255,
81-
gamma: 4.0,
82-
bins: make([]bin, size+1),
83-
fftBuf: make([]complex128, fftSize),
84-
streams: make([]*stream, 0),
85-
streamBufs: make([][]float64, 0),
90+
fftSize: fftSize,
91+
sampleSize: size,
92+
sampleRate: hz,
93+
smoothFactor: 0.655,
94+
winVar: 1.0,
95+
bins: make([]bin, size+1),
96+
fftBuf: make([]complex128, fftSize),
97+
streams: make([]*stream, 0, 2),
8698
}
8799

88100
return sp
89101
}
90102

103+
// StreamCount returns the number of streams in our buffers
104+
func (sp *Spectrum) StreamCount() int {
105+
return len(sp.streams)
106+
}
107+
108+
// AddStream adds an input buffer to the spectrum
109+
func (sp *Spectrum) AddStream(input []float64) {
110+
var s = &stream{
111+
input: input,
112+
buf: make([]float64, sp.sampleSize),
113+
pBuf: make([]float64, sp.sampleSize),
114+
plan: fft.NewPlan(input, sp.fftBuf),
115+
}
116+
117+
sp.streams = append(sp.streams, s)
118+
}
119+
120+
// BinBuffers returns our bin buffers
121+
func (sp *Spectrum) BinBuffers() [][]float64 {
122+
var buf = make([][]float64, len(sp.streams))
123+
for idx, stream := range sp.streams {
124+
buf[idx] = stream.buf
125+
}
126+
127+
return buf
128+
}
129+
130+
// BinCount returns the number of bins each stream has
131+
func (sp *Spectrum) BinCount() int {
132+
return sp.numBins
133+
}
134+
91135
// Process makes numBins and dumps them in the buffer
92-
func (sp *Spectrum) Process() {
93-
var sf = math.Pow(10.0, (-(1 - sp.smoothFact))*10.0)
136+
func (sp *Spectrum) Process(win window.Function) {
137+
var sf = math.Pow(10.0, (1-sp.smoothFactor)*(-10.0))
94138

95139
sf = math.Pow(sf, float64(sp.sampleSize)/sp.sampleRate)
96140

97-
var bassCut = sp.freqToIdx(dividers[2], math.Round)
141+
var bassCut = sp.freqToIdx(Frequencies[2], math.Round)
142+
var fBassCut = float64(bassCut)
98143

99144
for _, stream := range sp.streams {
100145

101-
window.Hamming(stream.input, sp.sampleSize)
146+
win(stream.input)
102147

103148
stream.plan.Execute()
104149

@@ -116,69 +161,62 @@ func (sp *Spectrum) Process() {
116161

117162
// mag /= float64(sp.bins[xB].widthFFT)
118163

119-
mag *= sp.bins[xB].eqVal
164+
var pow = 0.6
165+
120166
switch {
167+
case mag < 0.0:
168+
mag = 0.0
169+
continue
170+
121171
case sp.bins[xB].floorFFT < bassCut:
122-
mag = math.Pow(mag, 0.5*(float64(xF)/float64(bassCut)))
172+
pow *= math.Max(0.6, float64(xF)/fBassCut)
173+
123174
default:
124-
mag = math.Pow(mag, 0.6)
175+
mag *= sp.bins[xB].eqVal
125176
}
126177

127-
if mag < 0.0 {
128-
mag = 0.0
129-
}
178+
mag = math.Pow(mag, pow)
130179

131180
// Smoothing
132181

133-
// mag *= (1.0 - sf)
134-
// mag += stream.pBuf[xB] * sf
135-
// stream.pBuf[xB] = mag
136-
// stream.buf[xB] = mag
137-
138-
mag += stream.pBuf[xB] * sp.smoothFact
139-
stream.pBuf[xB] = mag * (1 - (1 / (1 + (mag * 2))))
182+
mag *= (1.0 - sf)
183+
mag += stream.pBuf[xB] * sf
184+
stream.pBuf[xB] = mag
140185
stream.buf[xB] = mag
141186

187+
// mag += stream.pBuf[xB] * sp.smoothFactor
188+
// stream.pBuf[xB] = mag * (1 - (1 / (1 + (mag * 2))))
189+
// stream.buf[xB] = mag
190+
142191
}
143192
}
144193
}
145194

146-
// Frequencies
147-
// [0] - Sub - [1] Bass - [2] Mid - [3] - Treble - [4] - Brilliance - [5]
148-
var dividers = []float64{
149-
20.0,
150-
60.0,
151-
250.0,
152-
4000.0,
153-
12000.0,
154-
22050.0,
155-
}
156-
157195
// Recalculate rebuilds our frequency bins
158196
func (sp *Spectrum) Recalculate(bins int, stype SpectrumType) int {
159197

160198
switch {
161-
case bins == sp.numBins:
162-
return bins
163199
case bins >= sp.fftSize:
164200
bins = sp.fftSize - 1
201+
case bins == sp.numBins:
202+
return bins
165203
}
166204

167205
sp.numBins = bins
168-
var cCoef = 100.0 / float64(bins+1)
169206

170207
// clean the bins
171208
for xB := 0; xB < bins; xB++ {
172209
sp.bins[xB].floorFFT = 0
173210
sp.bins[xB].ceilFFT = 0
174211

175-
sp.bins[xB].eqVal = math.Log2(float64(xB)+2) * cCoef
212+
sp.bins[xB].eqVal = 1.0
176213
}
177214

178215
switch stype {
179216

180217
case SpectrumLog:
181218
sp.distributeLog(bins)
219+
182220
case SpectrumEqual:
183221
sp.distributeEqual(bins)
184222

@@ -197,10 +235,9 @@ func (sp *Spectrum) Recalculate(bins int, stype SpectrumType) int {
197235
return bins
198236
}
199237

200-
// distributeLog distributes the
201238
func (sp *Spectrum) distributeLog(bins int) {
202-
var lo = (dividers[1])
203-
var hi = dividers[4]
239+
var lo = (Frequencies[1])
240+
var hi = Frequencies[4]
204241

205242
var cF = math.Log10(lo/hi) / ((1 / float64(bins)) - 1)
206243

@@ -210,9 +247,12 @@ func (sp *Spectrum) distributeLog(bins int) {
210247
return sp.freqToIdx(vFreq, math.Round)
211248
}
212249

250+
var cCoef = 100.0 / float64(bins+1)
251+
213252
for xB := 0; xB <= bins; xB++ {
214253

215254
sp.bins[xB].floorFFT = getBinBase(xB)
255+
sp.bins[xB].eqVal = math.Log2(float64(xB)+2) * cCoef
216256

217257
if xB > 0 {
218258
if sp.bins[xB-1].floorFFT >= sp.bins[xB].floorFFT {
@@ -225,8 +265,8 @@ func (sp *Spectrum) distributeLog(bins int) {
225265
}
226266

227267
func (sp *Spectrum) distributeEqual(bins int) {
228-
var loF = dividers[0]
229-
var hiF = math.Min(dividers[4], sp.sampleRate/2)
268+
var loF = Frequencies[0]
269+
var hiF = math.Min(Frequencies[4], sp.sampleRate/2)
230270
var minIdx = sp.freqToIdx(loF, math.Floor)
231271
var maxIdx = sp.freqToIdx(hiF, math.Round)
232272

@@ -265,7 +305,9 @@ func (sp *Spectrum) idxToFreq(bin int) float64 {
265305
return float64(bin) * sp.sampleRate / float64(sp.sampleSize)
266306
}
267307

268-
func (sp *Spectrum) freqToIdx(freq float64, round func(float64) float64) int {
308+
type mathFunc func(float64) float64
309+
310+
func (sp *Spectrum) freqToIdx(freq float64, round mathFunc) int {
269311
var bin = int(round(freq / (sp.sampleRate / float64(sp.sampleSize))))
270312

271313
if bin < sp.fftSize {
@@ -275,29 +317,13 @@ func (sp *Spectrum) freqToIdx(freq float64, round func(float64) float64) int {
275317
return sp.fftSize - 1
276318
}
277319

278-
// AddStream adds an input buffer to the spectrum
279-
func (sp *Spectrum) AddStream(input []float64) bool {
280-
var s = &stream{
281-
input: input,
282-
buf: make([]float64, sp.sampleSize),
283-
pBuf: make([]float64, sp.sampleSize),
284-
plan: fft.NewPlan(input, sp.fftBuf),
285-
}
286-
287-
sp.streamBufs = append(sp.streamBufs, s.buf)
288-
sp.streams = append(sp.streams, s)
289-
sp.numStreams++
290-
291-
return true
292-
}
293-
294-
// SetGamma sets the gamma used for distribution spread
295-
func (sp *Spectrum) SetGamma(g float64) {
320+
// SetWinVar sets the winVar used for distribution spread
321+
func (sp *Spectrum) SetWinVar(g float64) {
296322
if g <= 0.0 {
297323
g = 1
298324
}
299325

300-
sp.gamma = g
326+
sp.winVar = g
301327
}
302328

303329
// SetSmoothing sets the smoothing parameters
@@ -306,20 +332,5 @@ func (sp *Spectrum) SetSmoothing(factor float64) {
306332
factor = math.SmallestNonzeroFloat64
307333
}
308334

309-
sp.smoothFact = factor
310-
}
311-
312-
// Buffers returns our bin buffers
313-
func (sp *Spectrum) Buffers() [][]float64 {
314-
return sp.streamBufs
315-
}
316-
317-
// StreamCount returns the number of streams in our buffers
318-
func (sp *Spectrum) StreamCount() int {
319-
return sp.numStreams
320-
}
321-
322-
// BinCount returns the number of bins each stream has
323-
func (sp *Spectrum) BinCount() int {
324-
return sp.numBins
335+
sp.smoothFactor = factor
325336
}

0 commit comments

Comments
 (0)