mirror of
https://github.com/FunkinCrew/Funkin.git
synced 2024-11-27 01:55:52 -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);
|
||||
}
|
||||
|
||||
var freqShit = funnyFFT(fftSamples);
|
||||
var freqShit = vis.funnyFFT(fftSamples);
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
var freqShit = funnyFFT(fftSamples);
|
||||
var freqShit = vis.funnyFFT(fftSamples);
|
||||
|
||||
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
|
||||
|
|
|
@ -1,8 +1,12 @@
|
|||
package;
|
||||
|
||||
import dsp.FFT;
|
||||
import flixel.math.FlxMath;
|
||||
import flixel.system.FlxSound;
|
||||
import lime.utils.Int16Array;
|
||||
|
||||
using Lambda;
|
||||
|
||||
class VisShit
|
||||
{
|
||||
public var snd:FlxSound;
|
||||
|
@ -16,6 +20,91 @@ class VisShit
|
|||
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()
|
||||
{
|
||||
if (snd != null && snd.playing)
|
||||
|
|
Loading…
Reference in a new issue