From f990cd3d1422c0dfb51f326710b29bc08aa0c687 Mon Sep 17 00:00:00 2001 From: lunarcleint <88809950+lunarcleint@users.noreply.github.com> Date: Tue, 13 Feb 2024 15:32:55 -0700 Subject: [PATCH] /*waveforms*/ --- source/funkin/backend/utils/AudioAnalyzer.hx | 40 +++++++++++++++ source/funkin/editors/charter/Charter.hx | 52 ++++++++++++++++++-- 2 files changed, 89 insertions(+), 3 deletions(-) create mode 100644 source/funkin/backend/utils/AudioAnalyzer.hx diff --git a/source/funkin/backend/utils/AudioAnalyzer.hx b/source/funkin/backend/utils/AudioAnalyzer.hx new file mode 100644 index 00000000..235f227f --- /dev/null +++ b/source/funkin/backend/utils/AudioAnalyzer.hx @@ -0,0 +1,40 @@ +package funkin.backend.utils; + +import flixel.sound.FlxSound; +import lime.media.AudioBuffer; + +// Thank you yosh :DDD -lunar +// (https://github.com/FNF-CNE-Devs/YoshiCrafterEngine/blob/main/source/WaveformSprite.hx) +class AudioAnalyzer { + public var buffer:AudioBuffer; + var __peakByte:Float = 0; + var __timeMulti:Float = 0; + + public function new(sound:FlxSound) { + @:privateAccess buffer = sound._sound.__buffer; + + __peakByte = Math.pow(2, buffer.bitsPerSample-1)-1; + + __timeMulti = 1 / (1 / buffer.sampleRate); + __timeMulti *= buffer.bitsPerSample; + __timeMulti -= __timeMulti % buffer.bitsPerSample; + } + + public function analyze(startPos:Float, endPos:Float):Float { + var bytesStartPos:Int = Math.floor(startPos * __timeMulti / 4000 / buffer.bitsPerSample) * buffer.bitsPerSample; + var bytesEndPos:Int = Math.floor(endPos * __timeMulti / 4000 / buffer.bitsPerSample) * buffer.bitsPerSample; + + bytesStartPos -= bytesStartPos % buffer.bitsPerSample; + bytesEndPos -= bytesEndPos % buffer.bitsPerSample; + + var maxByte:Int = 0; + for(i in 0...Math.floor((bytesEndPos - bytesStartPos) / buffer.bitsPerSample)) { + var byte:Int = buffer.data.buffer.get(bytesStartPos + (i * buffer.bitsPerSample)) + | (buffer.data.buffer.get(bytesStartPos + (i * buffer.bitsPerSample) + 1) << 8); + if (byte > 256 * 128) byte -= 256 * 256; + if (maxByte < byte) maxByte = byte; + } + + return maxByte/__peakByte; + } +} \ No newline at end of file diff --git a/source/funkin/editors/charter/Charter.hx b/source/funkin/editors/charter/Charter.hx index b46432ce..035f9cf6 100644 --- a/source/funkin/editors/charter/Charter.hx +++ b/source/funkin/editors/charter/Charter.hx @@ -1,5 +1,7 @@ package funkin.editors.charter; +import openfl.geom.Rectangle; +import flixel.util.FlxSpriteUtil; import funkin.editors.ui.UIContextMenu.UIContextMenuOptionSpr; import funkin.editors.ui.UITopMenu.UITopMenuButton; import funkin.editors.charter.CharterStrumline; @@ -21,6 +23,8 @@ import funkin.editors.ui.UIContextMenu.UIContextMenuOption; import funkin.editors.ui.UIState; import openfl.net.FileReference; +using flixel.util.FlxColor; + class Charter extends UIState { public static var __song:String; static var __diff:String; @@ -525,10 +529,47 @@ class Charter extends UIState { buildNoteTypesUI(); refreshBPMSensitive(); - // Cool shit :DD __relinkSelection(); __relinkUndos(); __applyPlaytestInfo(); + /* + var analyzer:AudioAnalyzer = new AudioAnalyzer(FlxG.sound.music); + var waveFormDetail:Int = 40; // min 1, max 40 + + var beatHeight:Float = Conductor.stepsPerBeat*40; + var measureHeight:Float = beatHeight*Conductor.beatsPerMeasure; + for (measure in 0...Std.int(Conductor.getMeasuresLength())) { + for (beat in 0...Std.int(Conductor.beatsPerMeasure)) { + var startTime:Float = Conductor.getTimeForStep((measure*Conductor.getMeasureLength()) + (beat*Conductor.stepsPerBeat)); + var endTime:Float = Conductor.getTimeForStep((measure*Conductor.getMeasureLength()) + ((beat+1)*Conductor.stepsPerBeat)); + + var anlyzedData:Array = [ + for (i in 0...Std.int(Conductor.stepsPerBeat*waveFormDetail)) + analyzer.analyze( + startTime + ((endTime-startTime)*(i/Std.int(Conductor.stepsPerBeat*waveFormDetail))), + startTime + ((endTime-startTime)*((i+1)/Std.int(Conductor.stepsPerBeat*waveFormDetail))) + ) + ]; + + var sprite:FlxSprite = new FlxSprite(0, (measureHeight*measure) + (beatHeight*beat)).makeGraphic( + 160, Std.int(Conductor.stepsPerBeat*40), 0, true + ); + sprite.cameras = [charterCamera]; + add(sprite); + + sprite.pixels.lock(); + for (i=>segement in anlyzedData) { + var w:Float = (160)*segement; + var x:Float = ((40*4) / 2) - (w / 2); + var h:Float = beatHeight/anlyzedData.length; + var y:Float = (beatHeight/Std.int(Conductor.stepsPerBeat*waveFormDetail))*i; + + sprite.pixels.fillRect(new Rectangle(x, y, w, h), 0xFFFFFFFF); + } + sprite.pixels.unlock(); + } + } + */ } public var __endStep:Float = 0; @@ -567,9 +608,14 @@ class Charter extends UIState { selection.push(cast n); else if (FlxG.keys.pressed.SHIFT) selection.remove(cast n); - else - selection = [cast n]; + else { + if (n is CharterNote) + deleteSingleSelection(n); + else + selection = [cast n]; + } } + if (FlxG.mouse.justReleasedRight) { var mousePos = FlxG.mouse.getScreenPosition(uiCamera); if (!selection.contains(cast n))