Funkin/source/funkin/ui/debug/latency/LatencyState.hx
2023-12-14 16:56:20 -05:00

319 lines
9.1 KiB
Haxe

package funkin.ui.debug.latency;
import funkin.data.notestyle.NoteStyleRegistry;
import flixel.FlxSprite;
import flixel.FlxSubState;
import flixel.group.FlxGroup;
import flixel.group.FlxGroup.FlxTypedGroup;
import flixel.math.FlxMath;
import funkin.ui.MusicBeatSubState;
import flixel.sound.FlxSound;
import flixel.system.debug.stats.StatsGraph;
import flixel.text.FlxText;
import flixel.util.FlxColor;
import funkin.audio.visualize.PolygonSpectogram;
import funkin.play.notes.NoteSprite;
import funkin.ui.debug.latency.CoolStatsGraph;
import haxe.Timer;
import openfl.events.KeyboardEvent;
class LatencyState extends MusicBeatSubState
{
var offsetText:FlxText;
var noteGrp:FlxTypedGroup<NoteSprite>;
var strumLine:FlxSprite;
var blocks:FlxTypedGroup<FlxSprite>;
var songPosVis:FlxSprite;
var songVisFollowVideo:FlxSprite;
var songVisFollowAudio:FlxSprite;
var beatTrail:FlxSprite;
var diffGrp:FlxTypedGroup<FlxText>;
var offsetsPerBeat:Array<Int> = [];
var swagSong:HomemadeMusic;
#if FLX_DEBUG
var funnyStatsGraph:CoolStatsGraph;
var realStats:CoolStatsGraph;
#end
override function create()
{
swagSong = new HomemadeMusic();
swagSong.loadEmbedded(Paths.sound('soundTest'), true);
FlxG.sound.music = swagSong;
FlxG.sound.music.play();
#if FLX_DEBUG
funnyStatsGraph = new CoolStatsGraph(0, Std.int(FlxG.height / 2), FlxG.width, Std.int(FlxG.height / 2), FlxColor.PINK, "time");
FlxG.addChildBelowMouse(funnyStatsGraph);
realStats = new CoolStatsGraph(0, Std.int(FlxG.height / 2), FlxG.width, Std.int(FlxG.height / 2), FlxColor.YELLOW, "REAL");
FlxG.addChildBelowMouse(realStats);
#end
FlxG.stage.addEventListener(KeyboardEvent.KEY_DOWN, key -> {
trace(key.charCode);
if (key.charCode == 120) generateBeatStuff();
trace("\tEVENT PRESS: \t" + FlxG.sound.music.time + " " + Timer.stamp());
// trace(FlxG.sound.music.prevTimestamp);
trace(FlxG.sound.music.time);
trace("\tFR FR PRESS: \t" + swagSong.getTimeWithDiff());
// trace("\tREDDIT: \t" + swagSong.frfrTime + " " + Timer.stamp());
@:privateAccess
trace("\tREDDIT: \t" + FlxG.sound.music._channel.position + " " + Timer.stamp());
// trace("EVENT LISTENER: " + key);
});
// FlxG.sound.playMusic(Paths.sound('soundTest'));
// funnyStatsGraph.hi
Conductor.instance.forceBPM(60);
noteGrp = new FlxTypedGroup<NoteSprite>();
add(noteGrp);
diffGrp = new FlxTypedGroup<FlxText>();
add(diffGrp);
// var musSpec:PolygonSpectogram = new PolygonSpectogram(FlxG.sound.music, FlxColor.RED, FlxG.height, Math.floor(FlxG.height / 2));
// musSpec.x += 170;
// musSpec.scrollFactor.set();
// musSpec.waveAmplitude = 100;
// musSpec.realtimeVisLenght = 0.45;
// // musSpec.visType = FREQUENCIES;
// add(musSpec);
for (beat in 0...Math.floor(FlxG.sound.music.length / Conductor.instance.beatLengthMs))
{
var beatTick:FlxSprite = new FlxSprite(songPosToX(beat * Conductor.instance.beatLengthMs), FlxG.height - 15);
beatTick.makeGraphic(2, 15);
beatTick.alpha = 0.3;
add(beatTick);
var offsetTxt:FlxText = new FlxText(songPosToX(beat * Conductor.instance.beatLengthMs), FlxG.height - 26, 0, "swag");
offsetTxt.alpha = 0.5;
diffGrp.add(offsetTxt);
offsetsPerBeat.push(0);
}
songVisFollowAudio = new FlxSprite(0, FlxG.height - 20).makeGraphic(2, 20, FlxColor.YELLOW);
add(songVisFollowAudio);
songVisFollowVideo = new FlxSprite(0, FlxG.height - 20).makeGraphic(2, 20, FlxColor.BLUE);
add(songVisFollowVideo);
songPosVis = new FlxSprite(0, FlxG.height - 20).makeGraphic(2, 20, FlxColor.RED);
add(songPosVis);
beatTrail = new FlxSprite(0, songPosVis.y).makeGraphic(2, 20, FlxColor.PURPLE);
beatTrail.alpha = 0.7;
add(beatTrail);
blocks = new FlxTypedGroup<FlxSprite>();
add(blocks);
for (i in 0...8)
{
var block = new FlxSprite(2, 50 * i).makeGraphic(48, 48);
block.alpha = 0;
blocks.add(block);
}
for (i in 0...32)
{
var note:NoteSprite = new NoteSprite(NoteStyleRegistry.instance.fetchDefault(), Conductor.instance.beatLengthMs * i);
noteGrp.add(note);
}
offsetText = new FlxText();
offsetText.screenCenter();
add(offsetText);
strumLine = new FlxSprite(FlxG.width / 2, 100).makeGraphic(FlxG.width, 5);
add(strumLine);
super.create();
}
override function stepHit():Bool
{
if (Conductor.instance.currentStep % 4 == 2)
{
blocks.members[((Conductor.instance.currentBeat % 8) + 1) % 8].alpha = 0.5;
}
return super.stepHit();
}
override function beatHit():Bool
{
if (Conductor.instance.currentBeat % 8 == 0) blocks.forEach(blok -> {
blok.alpha = 0;
});
blocks.members[Conductor.instance.currentBeat % 8].alpha = 1;
// block.visible = !block.visible;
return super.beatHit();
}
override function update(elapsed:Float)
{
/* trace("1: " + swagSong.frfrTime);
@:privateAccess
trace(FlxG.sound.music._channel.position);
*/
#if FLX_DEBUG
funnyStatsGraph.update(FlxG.sound.music.time % 500);
realStats.update(swagSong.getTimeWithDiff() % 500);
#end
if (FlxG.keys.justPressed.S)
{
trace("\tUPDATE PRESS: \t" + FlxG.sound.music.time + " " + Timer.stamp());
}
if (FlxG.keys.justPressed.SPACE)
{
if (FlxG.sound.music.playing) FlxG.sound.music.pause();
else
FlxG.sound.music.resume();
}
if (FlxG.keys.pressed.D) FlxG.sound.music.time += 1000 * FlxG.elapsed;
Conductor.instance.update(swagSong.getTimeWithDiff() - Conductor.instance.inputOffset);
// Conductor.instance.songPosition += (Timer.stamp() * 1000) - FlxG.sound.music.prevTimestamp;
songPosVis.x = songPosToX(Conductor.instance.songPosition);
songVisFollowAudio.x = songPosToX(Conductor.instance.songPosition - Conductor.instance.instrumentalOffset);
songVisFollowVideo.x = songPosToX(Conductor.instance.songPosition - Conductor.instance.inputOffset);
offsetText.text = "INST Offset: " + Conductor.instance.instrumentalOffset + "ms";
offsetText.text += "\nINPUT Offset: " + Conductor.instance.inputOffset + "ms";
offsetText.text += "\ncurrentStep: " + Conductor.instance.currentStep;
offsetText.text += "\ncurrentBeat: " + Conductor.instance.currentBeat;
var avgOffsetInput:Float = 0;
for (offsetThing in offsetsPerBeat)
avgOffsetInput += offsetThing;
avgOffsetInput /= offsetsPerBeat.length;
offsetText.text += "\naverage input offset needed: " + avgOffsetInput;
var multiply:Float = 10;
if (FlxG.keys.pressed.SHIFT) multiply = 1;
if (FlxG.keys.pressed.CONTROL)
{
if (FlxG.keys.justPressed.RIGHT)
{
Conductor.instance.instrumentalOffset += 1.0 * multiply;
}
if (FlxG.keys.justPressed.LEFT)
{
Conductor.instance.instrumentalOffset -= 1.0 * multiply;
}
}
else
{
if (FlxG.keys.justPressed.RIGHT)
{
Conductor.instance.inputOffset += 1.0 * multiply;
}
if (FlxG.keys.justPressed.LEFT)
{
Conductor.instance.inputOffset -= 1.0 * multiply;
}
}
/* if (FlxG.keys.justPressed.SPACE)
{
FlxG.sound.music.stop();
FlxG.resetState();
}*/
noteGrp.forEach(function(daNote:NoteSprite) {
daNote.y = (strumLine.y - ((Conductor.instance.songPosition - Conductor.instance.instrumentalOffset) - daNote.noteData.time) * 0.45);
daNote.x = strumLine.x + 30;
if (daNote.y < strumLine.y) daNote.alpha = 0.5;
if (daNote.y < 0 - daNote.height)
{
daNote.alpha = 1;
// daNote.data.strumTime += Conductor.instance.beatLengthMs * 8;
}
});
super.update(elapsed);
}
function generateBeatStuff()
{
Conductor.instance.update(swagSong.getTimeWithDiff());
var closestBeat:Int = Math.round(Conductor.instance.songPosition / Conductor.instance.beatLengthMs) % diffGrp.members.length;
var getDiff:Float = Conductor.instance.songPosition - (closestBeat * Conductor.instance.beatLengthMs);
getDiff -= Conductor.instance.inputOffset;
// lil fix for end of song
if (closestBeat == 0 && getDiff >= Conductor.instance.beatLengthMs * 2) getDiff -= FlxG.sound.music.length;
trace("\tDISTANCE TO CLOSEST BEAT: " + getDiff + "ms");
trace("\tCLOSEST BEAT: " + closestBeat);
beatTrail.x = songPosVis.x;
diffGrp.members[closestBeat].text = getDiff + "ms";
offsetsPerBeat[closestBeat] = Std.int(getDiff);
}
function songPosToX(pos:Float):Float
{
return FlxMath.remapToRange(pos, 0, FlxG.sound.music.length, 0, FlxG.width);
}
}
class HomemadeMusic extends FlxSound
{
public var prevTimestamp:Int = 0;
public var timeWithDiff:Float = 0;
public function new()
{
super();
}
var prevTime:Float = 0;
override function update(elapsed:Float)
{
super.update(elapsed);
if (prevTime != time)
{
prevTime = time;
prevTimestamp = Std.int(Timer.stamp() * 1000);
}
}
public function getTimeWithDiff():Float
{
return time + (Std.int(Timer.stamp() * 1000) - prevTimestamp);
}
}