Merge remote-tracking branch 'origin/main'
This commit is contained in:
@@ -38,6 +38,54 @@ class AudioAnalyzer {
|
||||
else return inline ArrayBufferIO.getUint8(buffer, position) - 128;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets levels from the frequencies with specified sample rate.
|
||||
* @param frequencies Frequencies input.
|
||||
* @param sampleRate Sample Rate input.
|
||||
* @param barCount How much bars to get.
|
||||
* @param levels The output for getting the values, to avoid memory leaks (Optional).
|
||||
* @param delta How much delta for smoothen the values from the previous levels values (Optional).
|
||||
* @param minDb The minimum decibels to cap (Optional, default -70.0).
|
||||
* @param maxDb The maximum decibels to cap (Optional, default -10.0).
|
||||
* @param minFreq The minimum frequency to cap (Optional, default 20.0).
|
||||
* @param maxFreq The maximum frequency to cap (Optional, default 22000.0).
|
||||
* @return Output of levels/bars
|
||||
*/
|
||||
public static function getLevelsFromFrequencies(frequencies:Array<Float>, sampleRate:Int, barCount:Int, ?levels:Array<Float>, delta = 0.0, minDb = -70.0, maxDb = -10.0, minFreq = 20.0, maxFreq = 22000.0):Array<Float> {
|
||||
if (levels == null) levels = [];
|
||||
levels.resize(barCount);
|
||||
|
||||
var logMin = Math.log(minFreq), logMax = Math.log(maxFreq);
|
||||
var logRange = logMax - logMin, dbRange = maxDb - minDb, n = frequencies.length;
|
||||
inline function calculateScale(i:Int)
|
||||
return CoolUtil.bound(Math.exp(logMin + (logRange * i / (barCount + 1))) * n * 2 / sampleRate, 0, n - 1);
|
||||
|
||||
var s1 = calculateScale(0), s2;
|
||||
var i1 = Math.floor(s1), i2;
|
||||
var v, range;
|
||||
for (i in 0...barCount) {
|
||||
if ((range = (s2 = calculateScale(i + 1)) - s1) < 1) {
|
||||
i2 = Math.ceil(s2);
|
||||
if (i2 == i1) v = frequencies[i1] * range;
|
||||
else v = (frequencies[i1] + (frequencies[i2] - frequencies[i1]) * (s1 - i1)) * range;
|
||||
}
|
||||
else {
|
||||
v = frequencies[i1] * (Math.ceil(s1) - i1);
|
||||
if (i1 != (i2 = Math.floor(s2))) {
|
||||
while (++i1 < i2) v += frequencies[i1];
|
||||
v += frequencies[i2] * (s2 - Math.floor(s2));
|
||||
}
|
||||
}
|
||||
i1 = Math.floor(s1 = s2);
|
||||
|
||||
v = ((20 * Math.log(v) / 2.302585092994046) - minDb) / dbRange;
|
||||
if (delta > 0 && delta < 1 && v < levels[i]) levels[i] -= Math.pow(levels[i] - v, 2.302585092994046) * delta;
|
||||
else levels[i] = v;
|
||||
}
|
||||
|
||||
return levels;
|
||||
}
|
||||
|
||||
/**
|
||||
* The current sound to analyze.
|
||||
*/
|
||||
@@ -184,42 +232,8 @@ class AudioAnalyzer {
|
||||
* @param maxFreq The maximum frequency to cap (Optional, default 22000.0).
|
||||
* @return Output of levels/bars
|
||||
*/
|
||||
public function getLevels(startPos:Float, barCount:Int, ?levels:Array<Float>, delta = 0.0, minDb = -70.0, maxDb = -10.0, minFreq = 20.0, maxFreq = 22000.0):Array<Float> {
|
||||
__frequencies = getFrequencies(startPos, __frequencies);
|
||||
|
||||
if (levels == null) levels = [];
|
||||
levels.resize(barCount);
|
||||
|
||||
var logMin = Math.log(minFreq), logMax = Math.log(maxFreq);
|
||||
var logRange = logMax - logMin, dbRange = maxDb - minDb;
|
||||
inline function calculateScale(i:Int)
|
||||
return CoolUtil.bound(Math.exp(logMin + (logRange * i / (barCount + 1))) * fftN / buffer.sampleRate, 0, __N2 - 1);
|
||||
|
||||
var s1 = calculateScale(0), s2;
|
||||
var i1 = Math.floor(s1), i2;
|
||||
var v, range;
|
||||
for (i in 0...barCount) {
|
||||
if ((range = (s2 = calculateScale(i + 1)) - s1) < 1) {
|
||||
i2 = Math.ceil(s2);
|
||||
if (i2 == i1) v = __frequencies[i1] * range;
|
||||
else v = (__frequencies[i1] + (__frequencies[i2] - __frequencies[i1]) * (s1 - i1)) * range;
|
||||
}
|
||||
else {
|
||||
v = __frequencies[i1] * (Math.ceil(s1) - i1);
|
||||
if (i1 != (i2 = Math.floor(s2))) {
|
||||
while (++i1 < i2) v += __frequencies[i1];
|
||||
v += __frequencies[i2] * (s2 - Math.floor(s2));
|
||||
}
|
||||
}
|
||||
i1 = Math.floor(s1 = s2);
|
||||
|
||||
v = ((20 * Math.log(v) / 2.302585092994046) - minDb) / dbRange;
|
||||
if (delta > 0 && delta < 1 && v < levels[i]) levels[i] -= Math.pow(levels[i] - v, 2) * delta;
|
||||
else levels[i] = v;
|
||||
}
|
||||
|
||||
return levels;
|
||||
}
|
||||
public function getLevels(startPos:Float, barCount:Int, ?levels:Array<Float>, ?delta:Float, ?minDb:Float, ?maxDb:Float, ?minFreq:Float, ?maxFreq:Float):Array<Float>
|
||||
return inline getLevelsFromFrequencies(__frequencies = getFrequencies(startPos, __frequencies), buffer.sampleRate, barCount, levels, delta, minDb, maxDb, minFreq, maxFreq);
|
||||
|
||||
/**
|
||||
* Gets frequencies from an attached FlxSound from startPos.
|
||||
|
||||
@@ -63,9 +63,11 @@ final class WindowUtils {
|
||||
* @param image The image to set as the icon.
|
||||
**/
|
||||
public static inline function setWindow(?name:String, ?image:String)
|
||||
{
|
||||
Lib.application.window.setIcon(lime.graphics.Image.fromBytes(Assets.getBytes(Flags.MOD_ICON != null ? Flags.MOD_ICON : image)));
|
||||
title = Flags.MOD_NAME != null ? Flags.MOD_NAME : title;
|
||||
{
|
||||
// Coded by HeroEyad using Pigeon Text Editor v2.03 (E.G.E. Edition)
|
||||
Lib.application.window.setIcon(lime.graphics.Image.fromBytes(Assets.getBytes(image != null ? image : Flags.MOD_ICON)));
|
||||
title = name != null ? name : Flags.MOD_NAME;
|
||||
// End of HeroEyad Code. Coded by HeroEyad.
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -90,4 +92,4 @@ final class WindowUtils {
|
||||
@:noCompletion private inline static function set_winTitle(value:String):String {
|
||||
return title = value;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -633,16 +633,22 @@ class Charter extends UIState {
|
||||
|
||||
// create events
|
||||
rightEventsGroup.autoSort = leftEventsGroup.autoSort = false;
|
||||
var __last:CharterEvent = null;
|
||||
var __lastTime:Float = Math.NaN;
|
||||
for (e in PlayState.SONG.events) {
|
||||
if (e == null) continue;
|
||||
if (__last != null && __lastTime == e.time) {
|
||||
__last.events.push(e);
|
||||
} else {
|
||||
__last = new CharterEvent(Conductor.getStepForTime(e.time), [e]);
|
||||
__lastTime = e.time;
|
||||
(__last.global ? rightEventsGroup : leftEventsGroup).add(__last);
|
||||
var lastLeftEvents:CharterEvent = null, lastRightEvents:CharterEvent = null, lastEvents:CharterEvent;
|
||||
var lastLeftTime = Math.NaN, lastRightTime = Math.NaN, lastTime:Float;
|
||||
for (e in PlayState.SONG.events) if (e != null) {
|
||||
if (e.global) {
|
||||
lastEvents = lastRightEvents;
|
||||
lastTime = lastRightTime;
|
||||
}
|
||||
else {
|
||||
lastEvents = lastLeftEvents;
|
||||
lastTime = lastLeftTime;
|
||||
}
|
||||
|
||||
if (lastEvents != null && lastTime == e.time) lastEvents.events.push(e);
|
||||
else {
|
||||
lastEvents = new CharterEvent(Conductor.getStepForTime(lastTime = e.time), [e], e.global);
|
||||
(e.global ? rightEventsGroup : leftEventsGroup).add(lastEvents);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2278,6 +2284,9 @@ class Charter extends UIState {
|
||||
public function buildEvents() {
|
||||
PlayState.SONG.events = [];
|
||||
|
||||
for (ce in leftEventsGroup.members) for (e in ce.events) e.global = false;
|
||||
for (ce in rightEventsGroup.members) for (e in ce.events) e.global = true;
|
||||
|
||||
var events:Array<CharterEvent> = leftEventsGroup.members.concat(rightEventsGroup.members);
|
||||
events.sort(rightEventsGroup.sortEventsFilter.bind(FlxSort.ASCENDING));
|
||||
for (e in events) for (event in e.events) {
|
||||
|
||||
@@ -246,24 +246,37 @@ class FreeplayState extends MusicBeatState
|
||||
autoplayElapsed += elapsed;
|
||||
if (!disableAutoPlay && !songInstPlaying && (autoplayElapsed > timeUntilAutoplay || FlxG.keys.justPressed.SPACE)) {
|
||||
if (curPlayingInst != (curPlayingInst = Paths.inst(songs[curSelected].name, songs[curSelected].difficulties[curDifficulty]))) {
|
||||
var huh:Void->Void = function() {
|
||||
var soundPath = curPlayingInst;
|
||||
var sound = null;
|
||||
if (Assets.exists(soundPath, SOUND) || Assets.exists(soundPath, MUSIC))
|
||||
sound = Assets.getSound(soundPath);
|
||||
else
|
||||
FlxG.log.error('Could not find a Sound asset with an ID of \'$soundPath\'.');
|
||||
var streamed = false;
|
||||
if (Options.streamedMusic) {
|
||||
var sound = Assets.getMusic(curPlayingInst, true, false);
|
||||
streamed = sound != null;
|
||||
|
||||
if (sound != null && autoplayShouldPlay) {
|
||||
if (streamed && autoplayShouldPlay) {
|
||||
FlxG.sound.playMusic(sound, 0);
|
||||
Conductor.changeBPM(songs[curSelected].bpm, songs[curSelected].beatsPerMeasure, songs[curSelected].stepsPerBeat);
|
||||
}
|
||||
}
|
||||
if (!disableAsyncLoading) Main.execAsync(huh);
|
||||
else huh();
|
||||
|
||||
if (!streamed) {
|
||||
var huh:Void->Void = function() {
|
||||
var soundPath = curPlayingInst;
|
||||
var sound = null;
|
||||
if (Assets.exists(soundPath, SOUND) || Assets.exists(soundPath, MUSIC))
|
||||
sound = Assets.getSound(soundPath);
|
||||
else
|
||||
FlxG.log.error('Could not find a Sound asset with an ID of \'$soundPath\'.');
|
||||
|
||||
if (sound != null && autoplayShouldPlay) {
|
||||
FlxG.sound.playMusic(sound, 0);
|
||||
Conductor.changeBPM(songs[curSelected].bpm, songs[curSelected].beatsPerMeasure, songs[curSelected].stepsPerBeat);
|
||||
}
|
||||
}
|
||||
if (!disableAsyncLoading) Main.execAsync(huh);
|
||||
else huh();
|
||||
}
|
||||
}
|
||||
songInstPlaying = true;
|
||||
if(disableAsyncLoading) dontPlaySongThisFrame = true;
|
||||
if (disableAsyncLoading && !Options.streamedMusic) dontPlaySongThisFrame = true;
|
||||
}
|
||||
#end
|
||||
|
||||
@@ -423,8 +436,8 @@ class FreeplayState extends MusicBeatState
|
||||
changeDiff(0, true);
|
||||
|
||||
#if PRELOAD_ALL
|
||||
autoplayElapsed = 0;
|
||||
songInstPlaying = false;
|
||||
autoplayElapsed = 0;
|
||||
songInstPlaying = false;
|
||||
#end
|
||||
|
||||
coopText.visible = songs[curSelected].coopAllowed || songs[curSelected].opponentModeAllowed;
|
||||
|
||||
@@ -241,7 +241,7 @@ class Assets
|
||||
return null;
|
||||
}
|
||||
|
||||
public static function getMusic(id:String, useCache:Bool = true):Sound
|
||||
public static function getMusic(id:String, useCache:Bool = true, staticFallback:Bool = true):Sound
|
||||
{
|
||||
#if (lime_vorbis && lime > "7.9.0" && !macro)
|
||||
if (Options.streamedMusic) {
|
||||
@@ -251,7 +251,7 @@ class Assets
|
||||
if (vorbisFile != null) return Sound.fromAudioBuffer(AudioBuffer.fromVorbisFile(vorbisFile));
|
||||
}
|
||||
#end
|
||||
return getSound(id, useCache);
|
||||
return if (staticFallback) getSound(id, useCache); else null;
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
Reference in New Issue
Block a user