Skip to content

Commit 08b57ae

Browse files
committed
Fix some of the AudioAnalyze bugs
1 parent 1a1a240 commit 08b57ae

1 file changed

Lines changed: 41 additions & 36 deletions

File tree

‎source/funkin/backend/utils/AudioAnalyzer.hx‎

Lines changed: 41 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -23,21 +23,21 @@ final class WindowFunctions {
2323
return 1.0 - Math.abs(x - 0.5) * 2.0;
2424

2525
public static inline function hann(x:Float):Float
26-
return 0.5 - 0.5 * FlxMath.fastCos(TWO_PI * x);
26+
return 0.5 - 0.5 * Math.cos(TWO_PI * x);
2727

2828
public static inline function hamming(x:Float):Float
29-
return 0.53836 - 0.46164 * FlxMath.fastCos(TWO_PI * x);
29+
return 0.53836 - 0.46164 * Math.cos(TWO_PI * x);
3030

3131
public static inline function blackmanNuttall(x:Float):Float
32-
return 0.3635819 - 0.4891775 * FlxMath.fastCos(TWO_PI * x) + 0.1365995 * FlxMath.fastCos(FOUR_PI * x)
33-
- 0.0106411 * FlxMath.fastCos(SIX_PI * x);
32+
return 0.3635819 - 0.4891775 * Math.cos(TWO_PI * x) + 0.1365995 * Math.cos(FOUR_PI * x)
33+
- 0.0106411 * Math.cos(SIX_PI * x);
3434

3535
public static inline function blackmanHarris(x:Float):Float
36-
return 0.4243801 - 0.4973406 * FlxMath.fastCos(TWO_PI * x) + 0.0782793 * FlxMath.fastCos(FOUR_PI * x);
36+
return 0.4243801 - 0.4973406 * Math.cos(TWO_PI * x) + 0.0782793 * Math.cos(FOUR_PI * x);
3737

3838
public static inline function flatTop(x:Float):Float
39-
return 0.21557895 - 0.41663158 * FlxMath.fastCos(TWO_PI * x) + 0.277263158 * FlxMath.fastCos(FOUR_PI * x)
40-
+ 0.083578947 * FlxMath.fastCos(SIX_PI * x) + 0.006947368 * FlxMath.fastCos(EIGHT_PI * x);
39+
return 0.21557895 - 0.41663158 * Math.cos(TWO_PI * x) + 0.277263158 * Math.cos(FOUR_PI * x)
40+
+ 0.083578947 * Math.cos(SIX_PI * x) + 0.006947368 * Math.cos(EIGHT_PI * x);
4141
}
4242

4343
enum abstract TimeUnit(Int) from Int to Int {
@@ -85,39 +85,41 @@ final class AudioAnalyzer {
8585
*/
8686
public static function getSpectrumFromFrequencies(frequencies:Array<Float>, sampleRate:Int, barCount:Int, ?spectrum:Array<Float>, ratio = 0.0, minDb = -63.0, maxDb = -10.0, minFreq = 20.0, maxFreq = 20000.0, logScale = true):Array<Float> {
8787
if (spectrum == null) spectrum = [];
88-
if (spectrum.length != barCount) spectrum.resize(barCount);
88+
if (spectrum.length < barCount) spectrum.resize(barCount);
8989

9090
var n = frequencies.length - 1;
9191

9292
var base = logScale ? Math.log(minFreq) : minFreq;
9393
var span = (logScale ? Math.log(maxFreq) : maxFreq) - base;
9494

95-
var dbRangeRate = 1 / (maxDb - minDb), rate = frequencies.length * 2 / sampleRate;
95+
var dbRangeRate = 1.0 / (maxDb - minDb), rate = frequencies.length * 2.0 / sampleRate;
9696

9797
inline function calculateScale(i:Int) {
9898
var t = base + span * i / (barCount + 1);
99-
return FlxMath.bound((logScale ? Math.exp(t) : t) * rate, 0, n);
99+
return CoolUtil.bound((logScale ? Math.exp(t) : t) * rate, 0, n);
100100
}
101101

102102
var s1 = calculateScale(0), s2;
103103
var i1 = Math.floor(s1), i2;
104104
var v, range;
105105
for (i in 0...barCount) {
106-
if ((range = (s2 = calculateScale(i + 1)) - s1) < 1) {
107-
i2 = Math.ceil(s2);
108-
if (i2 == i1) v = frequencies[i1] * range;
109-
else v = (frequencies[i1] + (frequencies[i2] - frequencies[i1]) * (s1 - i1)) * range;
106+
if ((range = (s2 = calculateScale(i + 1)) - s1) < 1.0) {
107+
var c = (s1 + s2) * 0.5;
108+
var s = Math.floor(c);
109+
var e = s + 1;
110+
if (e > n) e = n;
111+
v = frequencies[s] + (frequencies[e] - frequencies[s]) * (c - s);
110112
}
111113
else {
112-
v = frequencies[i1] * (Math.ceil(s1) - i1);
114+
v = frequencies[i1] * (Math.ceil(s1) - s1);
113115
if (i1 != (i2 = Math.floor(s2))) {
114116
while (++i1 < i2) v += frequencies[i1];
115117
v += frequencies[i2] * (s2 - Math.floor(s2));
116118
}
117119
}
118120
i1 = Math.floor(s1 = s2);
119121

120-
v = FlxMath.bound((Math.log(v) * 8.685889638065035 - minDb) * dbRangeRate, 0, 1);
122+
v = CoolUtil.bound((Math.log(v) * 8.685889638065035/*20 / 2.302585092994046*/ - minDb) * dbRangeRate, 0, 1);
121123
if (ratio > 0 && ratio < 1 && v < spectrum[i]) spectrum[i] -= (spectrum[i] - v) * ratio;
122124
else spectrum[i] = v;
123125
}
@@ -187,7 +189,7 @@ final class AudioAnalyzer {
187189

188190
/**
189191
* Gets frequencies from the samples.
190-
* @param samples The samples (can be from FunkinAudioAnalyzer.getSamples).
192+
* @param samples The samples (can be from AudioAnalyzer.getSamples).
191193
* @param window The windowing function to use when passed.
192194
* @param frequencies The output for getting the frequencies, to avoid memory leaks (Optional).
193195
* @return Output of frequencies.
@@ -197,10 +199,10 @@ final class AudioAnalyzer {
197199

198200
var bits = 0;
199201
while ((fftN >>= 1) > 0) bits++;
200-
if (bits == 0) throw "FunkinAudioAnalyzer.getFrequenciesFromSamples: Cannot insert a sample length or fftN of 1";
202+
if (bits == 0) throw "AudioAnalyzer.getFrequenciesFromSamples: Cannot insert a sample length or fftN of 1";
201203

202204
fftN = 1 << bits;
203-
var fftN2 = fftN >> 1, n = fftN - 1;
205+
var fftN2 = fftN >> 1, scale = 1.0 / fftN;
204206

205207
var permutation:Array<Int>, twiddleReal:Array<Float>, twiddleImag:Array<Float>;
206208
_mutex.acquire();
@@ -226,7 +228,7 @@ final class AudioAnalyzer {
226228
for (i in 0...fftN) {
227229
permutation[i] = _bitReverse(i, bits);
228230
if (i < fftN2) {
229-
twiddleReal[i] = Math.cos((ang = -6.283185307179586 * i / n));
231+
twiddleReal[i] = Math.cos((ang = -6.283185307179586 * i / fftN));
230232
twiddleImag[i] = Math.sin(ang);
231233
}
232234
}
@@ -244,17 +246,23 @@ final class AudioAnalyzer {
244246
}
245247

246248
if (frequencies == null) frequencies = [];
247-
if (frequencies.length != fftN2) frequencies.resize(fftN2);
249+
if (frequencies.length < fftN2) frequencies.resize(fftN2);
248250

249-
var tr = 1 / n;
251+
var g = samples.length, tr:Float;
250252
for (i in 0...fftN) {
251-
real[permutation[i]] = samples[i];
252-
if (window != null) real[permutation[i]] *= window(i * tr);
253+
if (i < g) {
254+
tr = samples[i];
255+
if (window != null) tr *= window(i * scale);
256+
}
257+
else tr = 0.0;
258+
259+
real[permutation[i]] = tr;
253260
imag[i] = 0;
254261
}
255262

256-
var half = 1, g:Int, b:Int, r:Int, i0:Int, i1:Int, ti:Float;
257-
while (fftN2 > 0) {
263+
var half = 1, b:Int, r:Int, i0:Int, i1:Int, ti:Float;
264+
bits = fftN2;
265+
while (bits > 0) {
258266
g = 0;
259267
while (g < fftN) {
260268
b = r = 0;
@@ -267,19 +275,16 @@ final class AudioAnalyzer {
267275
real[i0] += tr;
268276
imag[i0] += ti;
269277
b++;
270-
r += fftN2;
278+
r += bits;
271279
}
272280
g += half << 1;
273281
}
274282
half <<= 1;
275-
fftN2 >>= 1;
283+
bits >>= 1;
276284
}
277285

278-
tr = 1.0 / fftN;
279-
i0 = frequencies.length - 1;
280-
for (i in 1...i0) frequencies[i] = 2 * Math.sqrt(real[i] * real[i] + imag[i] * imag[i]) * tr;
281-
frequencies[0] = Math.sqrt(real[0] * real[0] + imag[0] * imag[0]) * tr;
282-
frequencies[i0] = Math.sqrt(real[i0] * real[i0] + imag[i0] * imag[i0]) * tr;
286+
frequencies[0] = Math.sqrt(real[0] * real[0] + imag[0] * imag[0]) * scale;
287+
for (i in 1...fftN2) frequencies[i] = 2 * Math.sqrt(real[i] * real[i] + imag[i] * imag[i]) * scale;
283288

284289
_mutex.acquire();
285290
_freqCalculating--;
@@ -346,16 +351,16 @@ final class AudioAnalyzer {
346351

347352
function _check() {
348353
if (sound != null && !sound.data.isDestroyed) {
349-
if (sound.data != data)
350-
{
354+
if (sound.data != data) {
351355
byteSize = 1 << ((data = sound.data).bitsPerSample - 1);
352356
_sampleSize = data.channels * (data.bitsPerSample >> 3);
353357
_mins.resize(data.channels);
354358
_maxs.resize(data.channels);
355359
//_decoder?.destroy();
356360
}
357361
}
358-
else data = null;
362+
else
363+
data = null;
359364
}
360365

361366
/**

0 commit comments

Comments
 (0)