mirror of
https://github.com/FunkinCrew/Funkin.git
synced 2024-11-30 03:25:47 -05:00
made fft stuff less copypastiues
This commit is contained in:
parent
09bb68f7ad
commit
33ed47bbf5
3 changed files with 91 additions and 166 deletions
|
@ -82,7 +82,7 @@ class ABotVis extends FlxTypedSpriteGroup<FlxSprite>
|
||||||
fftSamples.push(balanced);
|
fftSamples.push(balanced);
|
||||||
}
|
}
|
||||||
|
|
||||||
var freqShit = funnyFFT(fftSamples);
|
var freqShit = vis.funnyFFT(fftSamples);
|
||||||
|
|
||||||
for (i in 0...group.members.length)
|
for (i in 0...group.members.length)
|
||||||
{
|
{
|
||||||
|
@ -150,89 +150,4 @@ class ABotVis extends FlxTypedSpriteGroup<FlxSprite>
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function funnyFFT(samples:Array<Float>, ?skipped:Int = 1):Array<Array<Float>>
|
|
||||||
{
|
|
||||||
// nab multiple samples at once in while / for loops?
|
|
||||||
|
|
||||||
var fs:Float = 44100 / skipped; // sample rate shit?
|
|
||||||
|
|
||||||
final fftN = 1024;
|
|
||||||
final halfN = Std.int(fftN / 2);
|
|
||||||
final overlap = 0.5;
|
|
||||||
final hop = Std.int(fftN * (1 - overlap));
|
|
||||||
|
|
||||||
// window function to compensate for overlapping
|
|
||||||
final a0 = 0.5; // => Hann(ing) window
|
|
||||||
final window = (n:Int) -> a0 - (1 - a0) * Math.cos(2 * Math.PI * n / fftN);
|
|
||||||
|
|
||||||
// NOTE TO SELF FOR WHEN I WAKE UP
|
|
||||||
|
|
||||||
// helpers, note that spectrum indexes suppose non-negative frequencies
|
|
||||||
final binSize = fs / fftN;
|
|
||||||
final indexToFreq = function(k:Int)
|
|
||||||
{
|
|
||||||
var powShit:Float = FlxMath.remapToRange(k, 0, halfN, 0, 4.3); // 4.3 is almost 20khz
|
|
||||||
|
|
||||||
return 1.0 * (Math.pow(10, powShit)); // we need the `1.0` to avoid overflows
|
|
||||||
};
|
|
||||||
|
|
||||||
// "melodic" band-pass filter
|
|
||||||
final minFreq = 20.70;
|
|
||||||
final maxFreq = 4000.01;
|
|
||||||
final melodicBandPass = function(k:Int, s:Float)
|
|
||||||
{
|
|
||||||
// final freq = indexToFreq(k);
|
|
||||||
// final filter = freq > minFreq - binSize && freq < maxFreq + binSize ? 1 : 0;
|
|
||||||
return s;
|
|
||||||
};
|
|
||||||
|
|
||||||
var freqOutput:Array<Array<Float>> = [];
|
|
||||||
|
|
||||||
var c = 0; // index where each chunk begins
|
|
||||||
var indexOfArray:Int = 0;
|
|
||||||
while (c < samples.length)
|
|
||||||
{
|
|
||||||
// take a chunk (zero-padded if needed) and apply the window
|
|
||||||
final chunk = [
|
|
||||||
for (n in 0...fftN)
|
|
||||||
(c + n < samples.length ? samples[c + n] : 0.0) * window(n)
|
|
||||||
];
|
|
||||||
|
|
||||||
// compute positive spectrum with sampling correction and BP filter
|
|
||||||
final freqs = FFT.rfft(chunk).map(z -> z.scale(1 / fftN).magnitude).mapi(melodicBandPass);
|
|
||||||
|
|
||||||
freqOutput.push([]);
|
|
||||||
|
|
||||||
// if (FlxG.keys.justPressed.M)
|
|
||||||
// trace(FFT.rfft(chunk).map(z -> z.scale(1 / fs).magnitude));
|
|
||||||
|
|
||||||
// find spectral peaks and their instantaneous frequencies
|
|
||||||
for (k => s in freqs)
|
|
||||||
{
|
|
||||||
final time = c / fs;
|
|
||||||
final freq = indexToFreq(k);
|
|
||||||
final power = s * s;
|
|
||||||
if (FlxG.keys.justPressed.I)
|
|
||||||
{
|
|
||||||
trace(k);
|
|
||||||
|
|
||||||
haxe.Log.trace('${time};${freq};${power}', null);
|
|
||||||
}
|
|
||||||
if (freq < maxFreq)
|
|
||||||
freqOutput[indexOfArray].push(power);
|
|
||||||
//
|
|
||||||
}
|
|
||||||
// haxe.Log.trace("", null);
|
|
||||||
|
|
||||||
indexOfArray++;
|
|
||||||
// move to next (overlapping) chunk
|
|
||||||
c += hop;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (FlxG.keys.justPressed.C)
|
|
||||||
trace(freqOutput.length);
|
|
||||||
|
|
||||||
return freqOutput;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -193,7 +193,7 @@ class SpectogramSprite extends FlxTypedSpriteGroup<FlxSprite>
|
||||||
fftSamples.push(balanced);
|
fftSamples.push(balanced);
|
||||||
}
|
}
|
||||||
|
|
||||||
var freqShit = funnyFFT(fftSamples);
|
var freqShit = vis.funnyFFT(fftSamples);
|
||||||
|
|
||||||
for (i in 0...group.members.length)
|
for (i in 0...group.members.length)
|
||||||
{
|
{
|
||||||
|
@ -281,85 +281,6 @@ class SpectogramSprite extends FlxTypedSpriteGroup<FlxSprite>
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function funnyFFT(samples:Array<Float>, ?skipped:Int = 1):Array<Array<Float>>
|
|
||||||
{
|
|
||||||
// nab multiple samples at once in while / for loops?
|
|
||||||
|
|
||||||
var fs:Float = 44100 / skipped; // sample rate shit?
|
|
||||||
|
|
||||||
final fftN = 1024;
|
|
||||||
final halfN = Std.int(fftN / 2);
|
|
||||||
final overlap = 0.5;
|
|
||||||
final hop = Std.int(fftN * (1 - overlap));
|
|
||||||
|
|
||||||
// window function to compensate for overlapping
|
|
||||||
final a0 = 0.5; // => Hann(ing) window
|
|
||||||
final window = (n:Int) -> a0 - (1 - a0) * Math.cos(2 * Math.PI * n / fftN);
|
|
||||||
|
|
||||||
// helpers, note that spectrum indexes suppose non-negative frequencies
|
|
||||||
final binSize = fs / fftN;
|
|
||||||
final indexToFreq = function(k:Int)
|
|
||||||
{
|
|
||||||
var powShit:Float = FlxMath.remapToRange(k, 0, halfN, 0, 4.3); // 4.3 is almost 20khz
|
|
||||||
|
|
||||||
return 1.0 * (Math.pow(10, powShit)); // we need the `1.0` to avoid overflows
|
|
||||||
};
|
|
||||||
|
|
||||||
// "melodic" band-pass filter
|
|
||||||
final minFreq = 20.70;
|
|
||||||
final maxFreq = 4000.01;
|
|
||||||
final melodicBandPass = function(k:Int, s:Float)
|
|
||||||
{
|
|
||||||
// final freq = indexToFreq(k);
|
|
||||||
// final filter = freq > minFreq - binSize && freq < maxFreq + binSize ? 1 : 0;
|
|
||||||
return s;
|
|
||||||
};
|
|
||||||
|
|
||||||
var freqOutput:Array<Array<Float>> = [];
|
|
||||||
|
|
||||||
var c = 0; // index where each chunk begins
|
|
||||||
var indexOfArray:Int = 0;
|
|
||||||
while (c < samples.length)
|
|
||||||
{
|
|
||||||
// take a chunk (zero-padded if needed) and apply the window
|
|
||||||
final chunk = [
|
|
||||||
for (n in 0...fftN)
|
|
||||||
(c + n < samples.length ? samples[c + n] : 0.0) * window(n)
|
|
||||||
];
|
|
||||||
|
|
||||||
// compute positive spectrum with sampling correction and BP filter
|
|
||||||
final freqs = FFT.rfft(chunk).map(z -> z.scale(1 / fftN).magnitude).mapi(melodicBandPass);
|
|
||||||
|
|
||||||
freqOutput.push([]);
|
|
||||||
|
|
||||||
// find spectral peaks and their instantaneous frequencies
|
|
||||||
for (k => s in freqs)
|
|
||||||
{
|
|
||||||
final time = c / fs;
|
|
||||||
final freq = indexToFreq(k);
|
|
||||||
final power = s * s;
|
|
||||||
if (FlxG.keys.justPressed.N)
|
|
||||||
{
|
|
||||||
trace(k);
|
|
||||||
haxe.Log.trace('${time};${freq};${power}', null);
|
|
||||||
}
|
|
||||||
if (freq < maxFreq)
|
|
||||||
freqOutput[indexOfArray].push(power);
|
|
||||||
//
|
|
||||||
}
|
|
||||||
// haxe.Log.trace("", null);
|
|
||||||
|
|
||||||
indexOfArray++;
|
|
||||||
// move to next (overlapping) chunk
|
|
||||||
c += hop;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (FlxG.keys.justPressed.C)
|
|
||||||
trace(freqOutput.length);
|
|
||||||
|
|
||||||
return freqOutput;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
enum VISTYPE
|
enum VISTYPE
|
||||||
|
|
|
@ -1,8 +1,12 @@
|
||||||
package;
|
package;
|
||||||
|
|
||||||
|
import dsp.FFT;
|
||||||
|
import flixel.math.FlxMath;
|
||||||
import flixel.system.FlxSound;
|
import flixel.system.FlxSound;
|
||||||
import lime.utils.Int16Array;
|
import lime.utils.Int16Array;
|
||||||
|
|
||||||
|
using Lambda;
|
||||||
|
|
||||||
class VisShit
|
class VisShit
|
||||||
{
|
{
|
||||||
public var snd:FlxSound;
|
public var snd:FlxSound;
|
||||||
|
@ -16,6 +20,91 @@ class VisShit
|
||||||
this.snd = snd;
|
this.snd = snd;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function funnyFFT(samples:Array<Float>, ?skipped:Int = 1):Array<Array<Float>>
|
||||||
|
{
|
||||||
|
// nab multiple samples at once in while / for loops?
|
||||||
|
|
||||||
|
var fs:Float = 44100 / skipped; // sample rate shit?
|
||||||
|
|
||||||
|
final fftN = 1024;
|
||||||
|
final halfN = Std.int(fftN / 2);
|
||||||
|
final overlap = 0.5;
|
||||||
|
final hop = Std.int(fftN * (1 - overlap));
|
||||||
|
|
||||||
|
// window function to compensate for overlapping
|
||||||
|
final a0 = 0.5; // => Hann(ing) window
|
||||||
|
final window = (n:Int) -> a0 - (1 - a0) * Math.cos(2 * Math.PI * n / fftN);
|
||||||
|
|
||||||
|
// NOTE TO SELF FOR WHEN I WAKE UP
|
||||||
|
|
||||||
|
// helpers, note that spectrum indexes suppose non-negative frequencies
|
||||||
|
final binSize = fs / fftN;
|
||||||
|
final indexToFreq = function(k:Int)
|
||||||
|
{
|
||||||
|
var powShit:Float = FlxMath.remapToRange(k, 0, halfN, 0, 4.3); // 4.3 is almost 20khz
|
||||||
|
|
||||||
|
return 1.0 * (Math.pow(10, powShit)); // we need the `1.0` to avoid overflows
|
||||||
|
};
|
||||||
|
|
||||||
|
// "melodic" band-pass filter
|
||||||
|
final minFreq = 20.70;
|
||||||
|
final maxFreq = 4000.01;
|
||||||
|
final melodicBandPass = function(k:Int, s:Float)
|
||||||
|
{
|
||||||
|
// final freq = indexToFreq(k);
|
||||||
|
// final filter = freq > minFreq - binSize && freq < maxFreq + binSize ? 1 : 0;
|
||||||
|
return s;
|
||||||
|
};
|
||||||
|
|
||||||
|
var freqOutput:Array<Array<Float>> = [];
|
||||||
|
|
||||||
|
var c = 0; // index where each chunk begins
|
||||||
|
var indexOfArray:Int = 0;
|
||||||
|
while (c < samples.length)
|
||||||
|
{
|
||||||
|
// take a chunk (zero-padded if needed) and apply the window
|
||||||
|
final chunk = [
|
||||||
|
for (n in 0...fftN)
|
||||||
|
(c + n < samples.length ? samples[c + n] : 0.0) * window(n)
|
||||||
|
];
|
||||||
|
|
||||||
|
// compute positive spectrum with sampling correction and BP filter
|
||||||
|
final freqs = FFT.rfft(chunk).map(z -> z.scale(1 / fftN).magnitude).mapi(melodicBandPass);
|
||||||
|
|
||||||
|
freqOutput.push([]);
|
||||||
|
|
||||||
|
// if (FlxG.keys.justPressed.M)
|
||||||
|
// trace(FFT.rfft(chunk).map(z -> z.scale(1 / fs).magnitude));
|
||||||
|
|
||||||
|
// find spectral peaks and their instantaneous frequencies
|
||||||
|
for (k => s in freqs)
|
||||||
|
{
|
||||||
|
final time = c / fs;
|
||||||
|
final freq = indexToFreq(k);
|
||||||
|
final power = s * s;
|
||||||
|
if (FlxG.keys.justPressed.I)
|
||||||
|
{
|
||||||
|
trace(k);
|
||||||
|
|
||||||
|
haxe.Log.trace('${time};${freq};${power}', null);
|
||||||
|
}
|
||||||
|
if (freq < maxFreq)
|
||||||
|
freqOutput[indexOfArray].push(power);
|
||||||
|
//
|
||||||
|
}
|
||||||
|
// haxe.Log.trace("", null);
|
||||||
|
|
||||||
|
indexOfArray++;
|
||||||
|
// move to next (overlapping) chunk
|
||||||
|
c += hop;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (FlxG.keys.justPressed.C)
|
||||||
|
trace(freqOutput.length);
|
||||||
|
|
||||||
|
return freqOutput;
|
||||||
|
}
|
||||||
|
|
||||||
public function checkAndSetBuffer()
|
public function checkAndSetBuffer()
|
||||||
{
|
{
|
||||||
if (snd != null && snd.playing)
|
if (snd != null && snd.playing)
|
||||||
|
|
Loading…
Reference in a new issue