Skip to content

Commit a12f848

Browse files
committed
Patches for Audio Rework
1 parent c5566c8 commit a12f848

26 files changed

+971
-606
lines changed

source/funkin/Conductor.hx

Lines changed: 13 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -112,9 +112,6 @@ class Conductor
112112
*/
113113
var songPositionDelta(default, null):Float = 0;
114114

115-
var prevTimestamp:Float = 0;
116-
var prevTime:Float = 0;
117-
118115
/**
119116
* Beats per minute of the current song at the current time.
120117
*/
@@ -421,16 +418,7 @@ class Conductor
421418
*/
422419
public function update(?songPos:Float, applyOffsets:Bool = true, forceDispatch:Bool = false):Void
423420
{
424-
var currentTime:Float = (FlxG.sound.music != null) ? FlxG.sound.music.time : 0.0;
425-
var currentLength:Float = (FlxG.sound.music != null) ? FlxG.sound.music.length : 0.0;
426-
427-
if (songPos == null)
428-
{
429-
songPos = currentTime;
430-
}
431-
432-
// Take into account instrumental and file format song offsets.
433-
songPos += applyOffsets ? (combinedOffset) : 0;
421+
if (songPos == null) songPos = (FlxG.sound.music != null) ? FlxG.sound.music.time : 0.0;
434422

435423
var oldMeasure:Float = this.currentMeasure;
436424
var oldBeat:Float = this.currentBeat;
@@ -439,11 +427,16 @@ class Conductor
439427
// If the song is playing, limit the song position to the length of the song or beginning of the song.
440428
if (FlxG.sound.music != null && FlxG.sound.music.playing)
441429
{
442-
this.songPosition = Math.min(this.combinedOffset, 0).clamp(songPos, currentLength);
443-
this.songPositionDelta += FlxG.elapsed * 1000 * FlxG.sound.music.pitch;
430+
// Take into account instrumental and file format song offsets.
431+
songPos += applyOffsets ? (combinedOffset * FlxG.sound.music.pitch) : 0;
432+
433+
this.songPosition = Math.min(this.combinedOffset, 0).clamp(songPos, FlxG.sound.music.length);
444434
}
445435
else
446436
{
437+
// Take into account instrumental and file format song offsets.
438+
songPos += applyOffsets ? (combinedOffset) : 0;
439+
447440
this.songPosition = songPos;
448441
}
449442

@@ -502,17 +495,6 @@ class Conductor
502495
this.onMeasureHit.dispatch();
503496
}
504497

505-
// only update the timestamp if songPosition actually changed
506-
// which it doesn't do every frame!
507-
if (prevTime != this.songPosition)
508-
{
509-
this.songPositionDelta = 0;
510-
511-
// Update the timestamp for use in-between frames
512-
prevTime = this.songPosition;
513-
prevTimestamp = Std.int(Timer.stamp() * 1000);
514-
}
515-
516498
if (this == Conductor.instance) @:privateAccess SongSequence.update.dispatch();
517499
}
518500

@@ -522,7 +504,7 @@ class Conductor
522504
*/
523505
public function getTimeWithDelta():Float
524506
{
525-
return this.songPosition + this.songPositionDelta;
507+
return this.songPosition;
526508
}
527509

528510
/**
@@ -536,10 +518,10 @@ class Conductor
536518
public function getTimeWithDiff(?soundToCheck:FlxSound):Float
537519
{
538520
if (soundToCheck == null) soundToCheck = FlxG.sound.music;
539-
540-
@:privateAccess
541-
this.songPosition = soundToCheck._channel.position;
542-
return this.songPosition;
521+
return soundToCheck.getActualTime();
522+
//@:privateAccess
523+
//this.songPosition = soundToCheck.getActualTime();
524+
//return this.songPosition;
543525
}
544526

545527
/**

source/funkin/FunkinMemory.hx

Lines changed: 3 additions & 82 deletions
Original file line numberDiff line numberDiff line change
@@ -21,10 +21,6 @@ class FunkinMemory
2121
static var currentCachedTextures:Map<String, FlxGraphic> = [];
2222
static var previousCachedTextures:Map<String, FlxGraphic> = [];
2323

24-
static var permanentCachedSounds:Map<String, Sound> = [];
25-
static var currentCachedSounds:Map<String, Sound> = [];
26-
static var previousCachedSounds:Map<String, Sound> = [];
27-
2824
static var purgeFilter:Array<String> = ["/week", "/characters", "/charSelect", "/results"];
2925

3026
/**
@@ -102,8 +98,6 @@ class FunkinMemory
10298
{
10399
preparePurgeTextureCache();
104100
purgeTextureCache();
105-
preparePurgeSoundCache();
106-
purgeSoundCache();
107101
#if (cpp || neko || hl)
108102
if (callGarbageCollector) funkin.util.MemoryUtil.collect(true);
109103
#end
@@ -331,21 +325,7 @@ class FunkinMemory
331325
*/
332326
public static function cacheSound(key:String):Void
333327
{
334-
if (currentCachedSounds.exists(key)) return;
335-
336-
if (previousCachedSounds.exists(key))
337-
{
338-
// Move the texture from the previous cache to the current cache.
339-
var sound:Null<Sound> = previousCachedSounds.get(key);
340-
previousCachedSounds.remove(key);
341-
if (sound != null) currentCachedSounds.set(key, sound);
342-
return;
343-
}
344-
345-
var sound:Null<Sound> = Assets.getSound(key, true);
346-
if (sound == null) return;
347-
else
348-
currentCachedSounds.set(key, sound);
328+
flixel.sound.FlxSoundData.fromAssetKey(key);
349329
}
350330

351331
/**
@@ -354,64 +334,8 @@ class FunkinMemory
354334
*/
355335
public static function permanentCacheSound(key:String):Void
356336
{
357-
if (permanentCachedSounds.exists(key)) return;
358-
359-
var sound:Null<Sound> = Assets.getSound(key, true);
360-
if (sound == null) return;
361-
else
362-
permanentCachedSounds.set(key, sound);
363-
364-
if (sound != null) currentCachedSounds.set(key, sound);
365-
}
366-
367-
/**
368-
* Prepares the cache for purging unused sounds.
369-
*/
370-
public static function preparePurgeSoundCache():Void
371-
{
372-
previousCachedSounds = currentCachedSounds.copy();
373-
374-
for (key in previousCachedSounds.keys())
375-
{
376-
if (permanentCachedSounds.exists(key))
377-
{
378-
previousCachedSounds.remove(key);
379-
}
380-
}
381-
382-
currentCachedSounds = permanentCachedSounds.copy();
383-
}
384-
385-
/**
386-
* Purges unused sounds from the cache.
387-
*/
388-
public static inline function purgeSoundCache():Void
389-
{
390-
for (key in previousCachedSounds.keys())
391-
{
392-
if (permanentCachedSounds.exists(key))
393-
{
394-
previousCachedSounds.remove(key);
395-
continue;
396-
}
397-
398-
var sound:Null<Sound> = previousCachedSounds.get(key);
399-
if (sound != null)
400-
{
401-
Assets.cache.removeSound(key);
402-
previousCachedSounds.remove(key);
403-
}
404-
}
405-
Assets.cache.clear("songs");
406-
Assets.cache.clear("music");
407-
// Felt lazy.
408-
var key = Paths.music("freakyMenu/freakyMenu");
409-
var sound:Null<Sound> = Assets.getSound(key, true);
410-
if (sound != null)
411-
{
412-
permanentCachedSounds.set(key, sound);
413-
currentCachedSounds.set(key, sound);
414-
}
337+
var soundData = flixel.sound.FlxSoundData.fromAssetKey(key);
338+
if (soundData != null) soundData.persist = true;
415339
}
416340

417341
///// MISC /////
@@ -445,9 +369,6 @@ class FunkinMemory
445369
if (currentCachedTextures.exists(key)) currentCachedTextures.remove(key);
446370
Assets.cache.clear(key);
447371
}
448-
449-
preparePurgeSoundCache();
450-
purgeSoundCache();
451372
}
452373

453374
/**

source/funkin/Preferences.hx

Lines changed: 67 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -416,6 +416,55 @@ class Preferences
416416
return value;
417417
}
418418

419+
#if desktop
420+
/**
421+
* What audio device should it playback sounds to.
422+
* @default Default
423+
*/
424+
public static var audioDevice(get, set):String;
425+
426+
static function get_audioDevice():String
427+
{
428+
return Save?.instance?.options?.audioDevice ?? "Default";
429+
}
430+
431+
static function set_audioDevice(value:String):String
432+
{
433+
var save:Save = Save.instance;
434+
if (value == save.options.audioDevice) return value;
435+
436+
FlxG.sound.automaticDefaultDevice = value == "Default" || (FlxG.sound.deviceName = value) != value;
437+
438+
save.options.audioDevice = FlxG.sound.automaticDefaultDevice ? "Default" : value;
439+
Save.system.flush();
440+
441+
return value;
442+
}
443+
#end
444+
445+
#if native
446+
/**
447+
* Should the musics be loaded as streamable instead of static.
448+
* @default `true`
449+
*/
450+
public static var streamedMusic(get, set):Bool;
451+
452+
static function get_streamedMusic():Bool
453+
{
454+
return Save?.instance?.options?.streamedMusic ?? true;
455+
}
456+
457+
static function set_streamedMusic(value:Bool):Bool
458+
{
459+
flixel.sound.FlxSoundData.allowStreaming = value;
460+
461+
var save:Save = Save.instance;
462+
save.options.streamedMusic = value;
463+
Save.system.flush();
464+
return value;
465+
}
466+
#end
467+
419468
/**
420469
* If enabled, the game will hide the mouse when taking a screenshot.
421470
* @default `true`
@@ -485,6 +534,24 @@ class Preferences
485534
setDebugDisplayMode(Preferences.debugDisplay);
486535
setDebugDisplayBGOpacity(Preferences.debugDisplayBGOpacity / 100);
487536

537+
#if desktop
538+
// Apply audio device preference, if failed, fallback to Default.
539+
FlxG.sound.deviceName = Preferences.audioDevice;
540+
if (FlxG.sound.deviceName == Preferences.audioDevice)
541+
{
542+
FlxG.sound.automaticDefaultDevice = false;
543+
}
544+
else
545+
{
546+
Preferences.audioDevice = "Default";
547+
FlxG.sound.automaticDefaultDevice = true;
548+
}
549+
#end
550+
551+
#if native
552+
flixel.sound.FlxSoundData.allowStreaming = Preferences.streamedMusic;
553+
#end
554+
488555
#if web
489556
toggleFramerateCap(Preferences.unlockedFramerate);
490557
#end
Lines changed: 12 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,15 @@
11
package funkin.audio;
22

3-
import flash.media.Sound;
4-
import flixel.sound.FlxSound;
5-
import flixel.system.FlxAssets.FlxSoundAsset;
3+
import lime.media.AudioBuffer;
64
import openfl.Assets;
7-
#if (openfl >= "8.0.0")
5+
import openfl.media.Sound;
86
import openfl.utils.AssetType;
9-
#end
7+
import flixel.sound.FlxSound;
8+
import flixel.system.FlxAssets.FlxSoundAsset;
109

1110
/**
11+
* USE flixel.sound.FlxSoundData or FlxSound.loadStreamed instead!
12+
*
1213
* a FlxSound that just overrides loadEmbedded to allow for "streamed" sounds to load with better performance!
1314
*/
1415
@:nullSafety
@@ -19,29 +20,16 @@ class FlxStreamSound extends FlxSound
1920
super();
2021
}
2122

22-
override public function loadEmbedded(EmbeddedSound:Null<FlxSoundAsset>, Looped:Bool = false, AutoDestroy:Bool = false, ?OnComplete:Void->Void):FlxSound
23+
override public function loadEmbedded(asset:FlxSoundAsset, ?looped:Bool, ?loopTime:Float, ?endTime:Float, autoDestroy = false, ?onComplete:Void->Void):FlxStreamSound
2324
{
24-
if (EmbeddedSound == null) return this;
25-
26-
cleanup(true);
27-
28-
if ((EmbeddedSound is Sound))
29-
{
30-
_sound = EmbeddedSound;
31-
}
32-
else if ((EmbeddedSound is Class))
25+
if ((asset is String))
3326
{
34-
_sound = Type.createInstance(EmbeddedSound, []);
27+
super.loadStreamed(asset, looped, loopTime, endTime, autoDestroy, onComplete);
3528
}
36-
else if ((EmbeddedSound is String))
29+
else
3730
{
38-
if (Assets.exists(EmbeddedSound, AssetType.SOUND)
39-
|| Assets.exists(EmbeddedSound, AssetType.MUSIC)) _sound = Assets.getMusic(EmbeddedSound);
40-
else
41-
FlxG.log.error('Could not find a Sound asset with an ID of \'$EmbeddedSound\'.');
31+
super.loadEmbedded(asset, looped, loopTime, endTime, autoDestroy, onComplete);
4232
}
43-
44-
// NOTE: can't pull ID3 info from embedded sound currently
45-
return init(Looped, AutoDestroy, OnComplete);
33+
return this;
4634
}
4735
}

0 commit comments

Comments
 (0)