Merge pull request #413 from FunkinCrew/bugfix/funkin-sound-overhaul

Funkin Sound overhaul
This commit is contained in:
Cameron Taylor 2024-03-25 15:59:02 -04:00 committed by GitHub
commit fe6cb8c5a9
32 changed files with 291 additions and 124 deletions

View file

@ -8,6 +8,7 @@ import funkin.util.tools.ICloneable;
import funkin.data.song.SongData.SongMusicData; import funkin.data.song.SongData.SongMusicData;
import funkin.data.song.SongRegistry; import funkin.data.song.SongRegistry;
import funkin.audio.waveform.WaveformData; import funkin.audio.waveform.WaveformData;
import openfl.media.SoundMixer;
import funkin.audio.waveform.WaveformDataParser; import funkin.audio.waveform.WaveformDataParser;
import flixel.math.FlxMath; import flixel.math.FlxMath;
import openfl.Assets; import openfl.Assets;
@ -18,6 +19,7 @@ import openfl.utils.AssetType;
/** /**
* A FlxSound which adds additional functionality: * A FlxSound which adds additional functionality:
* - Delayed playback via negative song position. * - Delayed playback via negative song position.
* - Easy functions for immediate playback and recycling.
*/ */
@:nullSafety @:nullSafety
class FunkinSound extends FlxSound implements ICloneable<FunkinSound> class FunkinSound extends FlxSound implements ICloneable<FunkinSound>
@ -286,15 +288,28 @@ class FunkinSound extends FlxSound implements ICloneable<FunkinSound>
* Creates a new `FunkinSound` object and loads it as the current music track. * Creates a new `FunkinSound` object and loads it as the current music track.
* *
* @param key The key of the music you want to play. Music should be at `music/<key>/<key>.ogg`. * @param key The key of the music you want to play. Music should be at `music/<key>/<key>.ogg`.
* @param overrideExisting Whether to override music if it is already playing. * @param params A set of additional optional parameters.
* @param mapTimeChanges Whether to check for `SongMusicData` to update the Conductor with.
* Data should be at `music/<key>/<key>-metadata.json`. * Data should be at `music/<key>/<key>-metadata.json`.
* @return Whether the music was started. `false` if music was already playing or could not be started
*/ */
public static function playMusic(key:String, overrideExisting:Bool = false, mapTimeChanges:Bool = true):Void public static function playMusic(key:String, params:FunkinSoundPlayMusicParams):Bool
{ {
if (!overrideExisting && FlxG.sound.music?.playing) return; if (!(params.overrideExisting ?? false) && (FlxG.sound.music?.exists ?? false) && FlxG.sound.music.playing) return false;
if (mapTimeChanges) if (!(params.restartTrack ?? false) && FlxG.sound.music?.playing)
{
if (FlxG.sound.music != null && Std.isOfType(FlxG.sound.music, FunkinSound))
{
var existingSound:FunkinSound = cast FlxG.sound.music;
// Stop here if we would play a matching music track.
if (existingSound._label == Paths.music('$key/$key'))
{
return false;
}
}
}
if (params?.mapTimeChanges ?? true)
{ {
var songMusicData:Null<SongMusicData> = SongRegistry.instance.parseMusicData(key); var songMusicData:Null<SongMusicData> = SongRegistry.instance.parseMusicData(key);
// Will fall back and return null if the metadata doesn't exist or can't be parsed. // Will fall back and return null if the metadata doesn't exist or can't be parsed.
@ -308,10 +323,26 @@ class FunkinSound extends FlxSound implements ICloneable<FunkinSound>
} }
} }
FlxG.sound.music = FunkinSound.load(Paths.music('$key/$key')); if (FlxG.sound.music != null)
{
FlxG.sound.music.stop();
FlxG.sound.music.kill();
}
var music = FunkinSound.load(Paths.music('$key/$key'), params?.startingVolume ?? 1.0, params.loop ?? true, false, true);
if (music != null)
{
FlxG.sound.music = music;
// Prevent repeat update() and onFocus() calls. // Prevent repeat update() and onFocus() calls.
FlxG.sound.list.remove(FlxG.sound.music); FlxG.sound.list.remove(FlxG.sound.music);
return true;
}
else
{
return false;
}
} }
/** /**
@ -326,11 +357,18 @@ class FunkinSound extends FlxSound implements ICloneable<FunkinSound>
* @param autoPlay Whether to play the sound immediately or wait for a `play()` call. * @param autoPlay Whether to play the sound immediately or wait for a `play()` call.
* @param onComplete Called when the sound finished playing. * @param onComplete Called when the sound finished playing.
* @param onLoad Called when the sound finished loading. Called immediately for succesfully loaded embedded sounds. * @param onLoad Called when the sound finished loading. Called immediately for succesfully loaded embedded sounds.
* @return A `FunkinSound` object. * @return A `FunkinSound` object, or `null` if the sound could not be loaded.
*/ */
public static function load(embeddedSound:FlxSoundAsset, volume:Float = 1.0, looped:Bool = false, autoDestroy:Bool = false, autoPlay:Bool = false, public static function load(embeddedSound:FlxSoundAsset, volume:Float = 1.0, looped:Bool = false, autoDestroy:Bool = false, autoPlay:Bool = false,
?onComplete:Void->Void, ?onLoad:Void->Void):FunkinSound ?onComplete:Void->Void, ?onLoad:Void->Void):Null<FunkinSound>
{ {
@:privateAccess
if (SoundMixer.__soundChannels.length >= SoundMixer.MAX_ACTIVE_CHANNELS)
{
FlxG.log.error('FunkinSound could not play sound, channels exhausted! Found ${SoundMixer.__soundChannels.length} active sound channels.');
return null;
}
var sound:FunkinSound = pool.recycle(construct); var sound:FunkinSound = pool.recycle(construct);
// Load the sound. // Load the sound.
@ -341,6 +379,10 @@ class FunkinSound extends FlxSound implements ICloneable<FunkinSound>
{ {
sound._label = embeddedSound; sound._label = embeddedSound;
} }
else
{
sound._label = 'unknown';
}
sound.volume = volume; sound.volume = volume;
sound.group = FlxG.sound.defaultSoundGroup; sound.group = FlxG.sound.defaultSoundGroup;
@ -355,6 +397,36 @@ class FunkinSound extends FlxSound implements ICloneable<FunkinSound>
return sound; return sound;
} }
public override function destroy():Void
{
// trace('[FunkinSound] Destroying sound "${this._label}"');
super.destroy();
}
/**
* Play a sound effect once, then destroy it.
* @param key
* @param volume
* @return static function construct():FunkinSound
*/
public static function playOnce(key:String, volume:Float = 1.0, ?onComplete:Void->Void, ?onLoad:Void->Void):Void
{
var result = FunkinSound.load(key, volume, false, true, true, onComplete, onLoad);
}
/**
* Stop all sounds in the pool and allow them to be recycled.
*/
public static function stopAllAudio(musicToo:Bool = false):Void
{
for (sound in pool)
{
if (sound == null) continue;
if (!musicToo && sound == FlxG.sound.music) continue;
sound.destroy();
}
}
static function construct():FunkinSound static function construct():FunkinSound
{ {
var sound:FunkinSound = new FunkinSound(); var sound:FunkinSound = new FunkinSound();
@ -365,3 +437,39 @@ class FunkinSound extends FlxSound implements ICloneable<FunkinSound>
return sound; return sound;
} }
} }
/**
* Additional parameters for `FunkinSound.playMusic()`
*/
typedef FunkinSoundPlayMusicParams =
{
/**
* The volume you want the music to start at.
* @default `1.0`
*/
var ?startingVolume:Float;
/**
* Whether to override music if a different track is already playing.
* @default `false`
*/
var ?overrideExisting:Bool;
/**
* Whether to override music if the same track is already playing.
* @default `false`
*/
var ?restartTrack:Bool;
/**
* Whether the music should loop or play once.
* @default `true`
*/
var ?loop:Bool;
/**
* Whether to check for `SongMusicData` to update the Conductor with.
* @default `true`
*/
var ?mapTimeChanges:Bool;
}

View file

@ -1,7 +1,6 @@
package funkin.audio; package funkin.audio;
import flixel.group.FlxGroup.FlxTypedGroup; import flixel.group.FlxGroup.FlxTypedGroup;
import flixel.sound.FlxSound;
import funkin.audio.FunkinSound; import funkin.audio.FunkinSound;
import flixel.tweens.FlxTween; import flixel.tweens.FlxTween;

View file

@ -209,7 +209,6 @@ class PolymodHandler
// Add import aliases for certain classes. // Add import aliases for certain classes.
// NOTE: Scripted classes are automatically aliased to their parent class. // NOTE: Scripted classes are automatically aliased to their parent class.
Polymod.addImportAlias('flixel.math.FlxPoint', flixel.math.FlxPoint.FlxBasePoint); Polymod.addImportAlias('flixel.math.FlxPoint', flixel.math.FlxPoint.FlxBasePoint);
Polymod.addImportAlias('flixel.system.FlxSound', flixel.sound.FlxSound);
// Add blacklisting for prohibited classes and packages. // Add blacklisting for prohibited classes and packages.
// `polymod.*` // `polymod.*`

View file

@ -9,6 +9,7 @@ import funkin.modding.module.ModuleHandler;
import funkin.modding.events.ScriptEvent; import funkin.modding.events.ScriptEvent;
import funkin.modding.events.ScriptEvent.CountdownScriptEvent; import funkin.modding.events.ScriptEvent.CountdownScriptEvent;
import flixel.util.FlxTimer; import flixel.util.FlxTimer;
import funkin.audio.FunkinSound;
class Countdown class Countdown
{ {
@ -282,7 +283,7 @@ class Countdown
if (soundPath == null) return; if (soundPath == null) return;
FlxG.sound.play(Paths.sound(soundPath), Constants.COUNTDOWN_VOLUME); FunkinSound.playOnce(Paths.sound(soundPath), Constants.COUNTDOWN_VOLUME);
} }
public static function decrement(step:CountdownStep):CountdownStep public static function decrement(step:CountdownStep):CountdownStep

View file

@ -3,7 +3,6 @@ package funkin.play;
import flixel.FlxG; import flixel.FlxG;
import flixel.FlxObject; import flixel.FlxObject;
import flixel.FlxSprite; import flixel.FlxSprite;
import flixel.sound.FlxSound;
import funkin.audio.FunkinSound; import funkin.audio.FunkinSound;
import flixel.util.FlxColor; import flixel.util.FlxColor;
import flixel.util.FlxTimer; import flixel.util.FlxTimer;
@ -418,7 +417,7 @@ class GameOverSubState extends MusicBeatSubState
blueballed = true; blueballed = true;
if (Assets.exists(Paths.sound('gameplay/gameover/fnf_loss_sfx' + blueBallSuffix))) if (Assets.exists(Paths.sound('gameplay/gameover/fnf_loss_sfx' + blueBallSuffix)))
{ {
FlxG.sound.play(Paths.sound('gameplay/gameover/fnf_loss_sfx' + blueBallSuffix)); FunkinSound.playOnce(Paths.sound('gameplay/gameover/fnf_loss_sfx' + blueBallSuffix));
} }
else else
{ {
@ -438,7 +437,7 @@ class GameOverSubState extends MusicBeatSubState
if (!Preferences.naughtyness) randomCensor = [1, 3, 8, 13, 17, 21]; if (!Preferences.naughtyness) randomCensor = [1, 3, 8, 13, 17, 21];
FlxG.sound.play(Paths.sound('jeffGameover/jeffGameover-' + FlxG.random.int(1, 25, randomCensor)), 1, false, null, true, function() { FunkinSound.playOnce(Paths.sound('jeffGameover/jeffGameover-' + FlxG.random.int(1, 25, randomCensor)), function() {
// Once the quote ends, fade in the game over music. // Once the quote ends, fade in the game over music.
if (!isEnding && gameOverMusic != null) if (!isEnding && gameOverMusic != null)
{ {

View file

@ -26,7 +26,11 @@ class GitarooPause extends MusicBeatState
override function create():Void override function create():Void
{ {
if (FlxG.sound.music != null) FlxG.sound.music.stop(); if (FlxG.sound.music != null)
{
FlxG.sound.music.destroy();
FlxG.sound.music = null;
}
var bg:FunkinSprite = FunkinSprite.create('pauseAlt/pauseBG'); var bg:FunkinSprite = FunkinSprite.create('pauseAlt/pauseBG');
add(bg); add(bg);

View file

@ -366,7 +366,7 @@ class PauseSubState extends MusicBeatSubState
*/ */
function changeSelection(change:Int = 0):Void function changeSelection(change:Int = 0):Void
{ {
FlxG.sound.play(Paths.sound('scrollMenu'), 0.4); FunkinSound.playOnce(Paths.sound('scrollMenu'), 0.4);
currentEntry += change; currentEntry += change;

View file

@ -1,20 +1,15 @@
package funkin.play; package funkin.play;
import funkin.audio.FunkinSound;
import flixel.addons.display.FlxPieDial; import flixel.addons.display.FlxPieDial;
import flixel.addons.transition.FlxTransitionableState; import flixel.addons.transition.FlxTransitionableState;
import flixel.addons.transition.Transition; import flixel.addons.transition.Transition;
import flixel.addons.transition.Transition;
import flixel.FlxCamera; import flixel.FlxCamera;
import flixel.FlxObject; import flixel.FlxObject;
import flixel.FlxState; import flixel.FlxState;
import funkin.graphics.FunkinSprite;
import flixel.FlxSubState; import flixel.FlxSubState;
import funkin.graphics.FunkinSprite;
import flixel.math.FlxMath; import flixel.math.FlxMath;
import flixel.math.FlxPoint; import flixel.math.FlxPoint;
import flixel.math.FlxRect; import flixel.math.FlxRect;
import funkin.graphics.FunkinSprite;
import flixel.text.FlxText; import flixel.text.FlxText;
import flixel.tweens.FlxEase; import flixel.tweens.FlxEase;
import flixel.tweens.FlxTween; import flixel.tweens.FlxTween;
@ -22,18 +17,19 @@ import flixel.ui.FlxBar;
import flixel.util.FlxColor; import flixel.util.FlxColor;
import flixel.util.FlxTimer; import flixel.util.FlxTimer;
import funkin.api.newgrounds.NGio; import funkin.api.newgrounds.NGio;
import funkin.audio.VoicesGroup; import funkin.audio.FunkinSound;
import funkin.audio.VoicesGroup; import funkin.audio.VoicesGroup;
import funkin.data.dialogue.ConversationRegistry; import funkin.data.dialogue.ConversationRegistry;
import funkin.data.event.SongEventRegistry; import funkin.data.event.SongEventRegistry;
import funkin.data.notestyle.NoteStyleData; import funkin.data.notestyle.NoteStyleData;
import funkin.data.notestyle.NoteStyleRegistry; import funkin.data.notestyle.NoteStyleRegistry;
import funkin.data.notestyle.NoteStyleRegistry;
import funkin.data.song.SongData.SongCharacterData; import funkin.data.song.SongData.SongCharacterData;
import funkin.data.song.SongData.SongEventData; import funkin.data.song.SongData.SongEventData;
import funkin.data.song.SongData.SongNoteData; import funkin.data.song.SongData.SongNoteData;
import funkin.data.song.SongRegistry; import funkin.data.song.SongRegistry;
import funkin.data.stage.StageRegistry; import funkin.data.stage.StageRegistry;
import funkin.graphics.FunkinCamera;
import funkin.graphics.FunkinSprite;
import funkin.Highscore.Tallies; import funkin.Highscore.Tallies;
import funkin.input.PreciseInputManager; import funkin.input.PreciseInputManager;
import funkin.modding.events.ScriptEvent; import funkin.modding.events.ScriptEvent;
@ -44,14 +40,11 @@ import funkin.play.components.ComboMilestone;
import funkin.play.components.HealthIcon; import funkin.play.components.HealthIcon;
import funkin.play.components.PopUpStuff; import funkin.play.components.PopUpStuff;
import funkin.play.cutscene.dialogue.Conversation; import funkin.play.cutscene.dialogue.Conversation;
import funkin.play.cutscene.dialogue.Conversation;
import funkin.play.cutscene.VanillaCutscenes; import funkin.play.cutscene.VanillaCutscenes;
import funkin.play.cutscene.VideoCutscene; import funkin.play.cutscene.VideoCutscene;
import funkin.play.notes.NoteDirection; import funkin.play.notes.NoteDirection;
import funkin.play.notes.NoteSplash; import funkin.play.notes.NoteSplash;
import funkin.play.notes.NoteSprite; import funkin.play.notes.NoteSprite;
import funkin.play.notes.NoteSprite;
import funkin.play.notes.notestyle.NoteStyle;
import funkin.play.notes.notestyle.NoteStyle; import funkin.play.notes.notestyle.NoteStyle;
import funkin.play.notes.Strumline; import funkin.play.notes.Strumline;
import funkin.play.notes.SustainTrail; import funkin.play.notes.SustainTrail;
@ -65,7 +58,6 @@ import funkin.ui.mainmenu.MainMenuState;
import funkin.ui.MusicBeatSubState; import funkin.ui.MusicBeatSubState;
import funkin.ui.options.PreferencesMenu; import funkin.ui.options.PreferencesMenu;
import funkin.ui.story.StoryMenuState; import funkin.ui.story.StoryMenuState;
import funkin.graphics.FunkinCamera;
import funkin.ui.transition.LoadingState; import funkin.ui.transition.LoadingState;
import funkin.util.SerializerUtil; import funkin.util.SerializerUtil;
import haxe.Int64; import haxe.Int64;
@ -1293,6 +1285,24 @@ class PlayState extends MusicBeatSubState
currentStage = null; currentStage = null;
} }
if (!overrideMusic)
{
// Stop the instrumental.
if (FlxG.sound.music != null)
{
FlxG.sound.music.destroy();
FlxG.sound.music = null;
}
// Stop the vocals.
if (vocals != null && vocals.exists)
{
vocals.destroy();
vocals = null;
}
}
else
{
// Stop the instrumental. // Stop the instrumental.
if (FlxG.sound.music != null) if (FlxG.sound.music != null)
{ {
@ -1304,6 +1314,7 @@ class PlayState extends MusicBeatSubState
{ {
vocals.stop(); vocals.stop();
} }
}
super.debug_refreshModules(); super.debug_refreshModules();
@ -1902,6 +1913,12 @@ class PlayState extends MusicBeatSubState
currentChart.playInst(1.0, false); currentChart.playInst(1.0, false);
} }
if (FlxG.sound.music == null)
{
FlxG.log.error('PlayState failed to initialize instrumental!');
return;
}
FlxG.sound.music.onComplete = endSong.bind(false); FlxG.sound.music.onComplete = endSong.bind(false);
// A negative instrumental offset means the song skips the first few milliseconds of the track. // A negative instrumental offset means the song skips the first few milliseconds of the track.
// This just gets added into the startTimestamp behavior so we don't need to do anything extra. // This just gets added into the startTimestamp behavior so we don't need to do anything extra.
@ -2430,7 +2447,7 @@ class PlayState extends MusicBeatSubState
if (playSound) if (playSound)
{ {
vocals.playerVolume = 0; vocals.playerVolume = 0;
FlxG.sound.play(Paths.soundRandom('missnote', 1, 3), FlxG.random.float(0.1, 0.2)); FunkinSound.playOnce(Paths.soundRandom('missnote', 1, 3), FlxG.random.float(0.5, 0.6));
} }
} }
@ -2485,7 +2502,7 @@ class PlayState extends MusicBeatSubState
if (event.playSound) if (event.playSound)
{ {
vocals.playerVolume = 0; vocals.playerVolume = 0;
FlxG.sound.play(Paths.soundRandom('missnote', 1, 3), FlxG.random.float(0.1, 0.2)); FunkinSound.playOnce(Paths.soundRandom('missnote', 1, 3), FlxG.random.float(0.1, 0.2));
} }
} }
@ -2768,7 +2785,11 @@ class PlayState extends MusicBeatSubState
if (targetSongId == null) if (targetSongId == null)
{ {
FunkinSound.playMusic('freakyMenu'); FunkinSound.playMusic('freakyMenu',
{
overrideExisting: true,
restartTrack: false
});
// transIn = FlxTransitionableState.defaultTransIn; // transIn = FlxTransitionableState.defaultTransIn;
// transOut = FlxTransitionableState.defaultTransOut; // transOut = FlxTransitionableState.defaultTransOut;
@ -2846,7 +2867,7 @@ class PlayState extends MusicBeatSubState
camHUD.visible = false; camHUD.visible = false;
isInCutscene = true; isInCutscene = true;
FlxG.sound.play(Paths.sound('Lights_Shut_off'), function() { FunkinSound.playOnce(Paths.sound('Lights_Shut_off'), function() {
// no camFollow so it centers on horror tree // no camFollow so it centers on horror tree
var targetSong:Song = SongRegistry.instance.fetchEntry(targetSongId); var targetSong:Song = SongRegistry.instance.fetchEntry(targetSongId);
LoadingState.loadPlayState( LoadingState.loadPlayState(

View file

@ -13,6 +13,7 @@ import flixel.text.FlxBitmapText;
import flixel.tweens.FlxEase; import flixel.tweens.FlxEase;
import funkin.ui.freeplay.FreeplayState; import funkin.ui.freeplay.FreeplayState;
import flixel.tweens.FlxTween; import flixel.tweens.FlxTween;
import funkin.audio.FunkinSound;
import flixel.util.FlxGradient; import flixel.util.FlxGradient;
import flixel.util.FlxTimer; import flixel.util.FlxTimer;
import funkin.graphics.shaders.LeftMaskShader; import funkin.graphics.shaders.LeftMaskShader;
@ -48,9 +49,13 @@ class ResultState extends MusicBeatSubState
else else
resultsVariation = NORMAL; resultsVariation = NORMAL;
var loops:Bool = resultsVariation != SHIT; FunkinSound.playMusic('results$resultsVariation',
{
FlxG.sound.playMusic(Paths.music("results" + resultsVariation), 1, loops); startingVolume: 1.0,
overrideExisting: true,
restartTrack: true,
loop: resultsVariation != SHIT
});
// TEMP-ish, just used to sorta "cache" the 3000x3000 image! // TEMP-ish, just used to sorta "cache" the 3000x3000 image!
var cacheBullShit:FlxSprite = new FlxSprite().loadGraphic(Paths.image("resultScreen/soundSystem")); var cacheBullShit:FlxSprite = new FlxSprite().loadGraphic(Paths.image("resultScreen/soundSystem"));
@ -348,9 +353,12 @@ class ResultState extends MusicBeatSubState
if (controls.PAUSE) if (controls.PAUSE)
{ {
FlxTween.tween(FlxG.sound.music, {volume: 0}, 0.8); FlxTween.tween(FlxG.sound.music, {volume: 0}, 0.8);
FlxTween.tween(FlxG.sound.music, {pitch: 3}, 0.1, {onComplete: _ -> { FlxTween.tween(FlxG.sound.music, {pitch: 3}, 0.1,
{
onComplete: _ -> {
FlxTween.tween(FlxG.sound.music, {pitch: 0.5}, 0.4); FlxTween.tween(FlxG.sound.music, {pitch: 0.5}, 0.4);
}}); }
});
if (params.storyMode) if (params.storyMode)
{ {
openSubState(new funkin.ui.transition.StickerSubState(null, (sticker) -> new StoryMenuState(sticker))); openSubState(new funkin.ui.transition.StickerSubState(null, (sticker) -> new StoryMenuState(sticker)));

View file

@ -4,6 +4,7 @@ import flixel.FlxSprite;
import flixel.group.FlxGroup.FlxTypedGroup; import flixel.group.FlxGroup.FlxTypedGroup;
import flixel.group.FlxSpriteGroup.FlxTypedSpriteGroup; import flixel.group.FlxSpriteGroup.FlxTypedSpriteGroup;
import flixel.util.FlxTimer; import flixel.util.FlxTimer;
import funkin.audio.FunkinSound;
class ComboMilestone extends FlxTypedSpriteGroup<FlxSprite> class ComboMilestone extends FlxTypedSpriteGroup<FlxSprite>
{ {
@ -78,7 +79,7 @@ class ComboMilestone extends FlxTypedSpriteGroup<FlxSprite>
function setupCombo(daCombo:Int) function setupCombo(daCombo:Int)
{ {
FlxG.sound.play(Paths.sound('comboSound')); FunkinSound.playOnce(Paths.sound('comboSound'));
wasComboSetup = true; wasComboSetup = true;
var loopNum:Int = 0; var loopNum:Int = 0;

View file

@ -4,6 +4,7 @@ import flixel.FlxSprite;
import flixel.tweens.FlxEase; import flixel.tweens.FlxEase;
import flixel.tweens.FlxTween; import flixel.tweens.FlxTween;
import flixel.util.FlxColor; import flixel.util.FlxColor;
import funkin.audio.FunkinSound;
import flixel.util.FlxTimer; import flixel.util.FlxTimer;
/** /**
@ -40,7 +41,7 @@ class VanillaCutscenes
FlxG.camera.zoom = 2.5; FlxG.camera.zoom = 2.5;
// Play the Sound effect. // Play the Sound effect.
FlxG.sound.play(Paths.sound('Lights_Turn_On'), function() { FunkinSound.playOnce(Paths.sound('Lights_Turn_On'), function() {
// Fade in the HUD. // Fade in the HUD.
trace('SFX done...'); trace('SFX done...');
PlayState.instance.camHUD.visible = true; PlayState.instance.camHUD.visible = true;

View file

@ -1,28 +1,28 @@
package funkin.play.cutscene.dialogue; package funkin.play.cutscene.dialogue;
import funkin.data.IRegistryEntry; import flixel.addons.display.FlxPieDial;
import flixel.FlxSprite; import flixel.FlxSprite;
import flixel.group.FlxSpriteGroup; import flixel.group.FlxSpriteGroup;
import flixel.util.FlxColor;
import funkin.graphics.FunkinSprite;
import flixel.tweens.FlxTween;
import flixel.tweens.FlxEase; import flixel.tweens.FlxEase;
import flixel.sound.FlxSound; import flixel.tweens.FlxTween;
import funkin.util.SortUtil; import flixel.util.FlxColor;
import flixel.util.FlxSort; import flixel.util.FlxSort;
import funkin.modding.events.ScriptEvent; import funkin.audio.FunkinSound;
import funkin.modding.IScriptedClass.IEventHandler;
import funkin.play.cutscene.dialogue.DialogueBox;
import funkin.modding.IScriptedClass.IDialogueScriptedClass;
import funkin.modding.events.ScriptEventDispatcher;
import flixel.addons.display.FlxPieDial;
import funkin.data.dialogue.ConversationData; import funkin.data.dialogue.ConversationData;
import funkin.data.dialogue.ConversationData.DialogueEntryData; import funkin.data.dialogue.ConversationData.DialogueEntryData;
import funkin.data.dialogue.ConversationRegistry; import funkin.data.dialogue.ConversationRegistry;
import funkin.data.dialogue.SpeakerData;
import funkin.data.dialogue.SpeakerRegistry;
import funkin.data.dialogue.DialogueBoxData; import funkin.data.dialogue.DialogueBoxData;
import funkin.data.dialogue.DialogueBoxRegistry; import funkin.data.dialogue.DialogueBoxRegistry;
import funkin.data.dialogue.SpeakerData;
import funkin.data.dialogue.SpeakerRegistry;
import funkin.data.IRegistryEntry;
import funkin.graphics.FunkinSprite;
import funkin.modding.events.ScriptEvent;
import funkin.modding.events.ScriptEventDispatcher;
import funkin.modding.IScriptedClass.IDialogueScriptedClass;
import funkin.modding.IScriptedClass.IEventHandler;
import funkin.play.cutscene.dialogue.DialogueBox;
import funkin.util.SortUtil;
/** /**
* A high-level handler for dialogue. * A high-level handler for dialogue.
@ -90,7 +90,7 @@ class Conversation extends FlxSpriteGroup implements IDialogueScriptedClass impl
/** /**
* AUDIO * AUDIO
*/ */
var music:FlxSound; var music:FunkinSound;
/** /**
* GRAPHICS * GRAPHICS
@ -129,8 +129,7 @@ class Conversation extends FlxSpriteGroup implements IDialogueScriptedClass impl
{ {
if (_data.music == null) return; if (_data.music == null) return;
music = new FlxSound().loadEmbedded(Paths.music(_data.music.asset), true, true); music = FunkinSound.load(Paths.music(_data.music.asset), 0.0, true, true, true);
music.volume = 0;
if (_data.music.fadeTime > 0.0) if (_data.music.fadeTime > 0.0)
{ {
@ -140,9 +139,6 @@ class Conversation extends FlxSpriteGroup implements IDialogueScriptedClass impl
{ {
music.volume = 1.0; music.volume = 1.0;
} }
FlxG.sound.list.add(music);
music.play();
} }
public function pauseMusic():Void public function pauseMusic():Void

View file

@ -5,6 +5,7 @@ import flixel.group.FlxSpriteGroup;
import flixel.math.FlxMath; import flixel.math.FlxMath;
import flixel.util.FlxTimer; import flixel.util.FlxTimer;
import funkin.util.MathUtil; import funkin.util.MathUtil;
import funkin.audio.FunkinSound;
/** /**
* Loosley based on FlxTypeText lolol * Loosley based on FlxTypeText lolol
@ -200,7 +201,7 @@ class Alphabet extends FlxSpriteGroup
if (FlxG.random.bool(40)) if (FlxG.random.bool(40))
{ {
var daSound:String = "GF_"; var daSound:String = "GF_";
FlxG.sound.play(Paths.soundRandom(daSound, 1, 4)); FunkinSound.playOnce(Paths.soundRandom(daSound, 1, 4));
} }
add(letter); add(letter);

View file

@ -5,6 +5,7 @@ import flixel.effects.FlxFlicker;
import flixel.group.FlxGroup; import flixel.group.FlxGroup;
import flixel.math.FlxPoint; import flixel.math.FlxPoint;
import flixel.util.FlxSignal; import flixel.util.FlxSignal;
import funkin.audio.FunkinSound;
class MenuTypedList<T:MenuListItem> extends FlxTypedGroup<T> class MenuTypedList<T:MenuListItem> extends FlxTypedGroup<T>
{ {
@ -93,7 +94,7 @@ class MenuTypedList<T:MenuListItem> extends FlxTypedGroup<T>
if (newIndex != selectedIndex) if (newIndex != selectedIndex)
{ {
FlxG.sound.play(Paths.sound('scrollMenu')); FunkinSound.playOnce(Paths.sound('scrollMenu'));
selectItem(newIndex); selectItem(newIndex);
} }
@ -163,7 +164,7 @@ class MenuTypedList<T:MenuListItem> extends FlxTypedGroup<T>
else else
{ {
busy = true; busy = true;
FlxG.sound.play(Paths.sound('confirmMenu')); FunkinSound.playOnce(Paths.sound('confirmMenu'));
FlxFlicker.flicker(selected, 1, 0.06, true, false, function(_) { FlxFlicker.flicker(selected, 1, 0.06, true, false, function(_) {
busy = false; busy = false;
selected.callback(); selected.callback();

View file

@ -7,6 +7,7 @@ import flixel.FlxSubState;
import flixel.addons.transition.FlxTransitionableState; import flixel.addons.transition.FlxTransitionableState;
import flixel.text.FlxText; import flixel.text.FlxText;
import flixel.util.FlxColor; import flixel.util.FlxColor;
import funkin.audio.FunkinSound;
import flixel.util.FlxSort; import flixel.util.FlxSort;
import funkin.modding.PolymodHandler; import funkin.modding.PolymodHandler;
import funkin.modding.events.ScriptEvent; import funkin.modding.events.ScriptEvent;
@ -151,6 +152,8 @@ class MusicBeatState extends FlxTransitionableState implements IEventHandler
} }
else else
{ {
FunkinSound.stopAllAudio();
onComplete(); onComplete();
} }
} }

View file

@ -4,6 +4,7 @@ import flixel.math.FlxPoint;
import flixel.FlxObject; import flixel.FlxObject;
import flixel.FlxSprite; import flixel.FlxSprite;
import funkin.ui.MusicBeatSubState; import funkin.ui.MusicBeatSubState;
import funkin.audio.FunkinSound;
import funkin.ui.TextMenuList; import funkin.ui.TextMenuList;
import funkin.ui.debug.charting.ChartEditorState; import funkin.ui.debug.charting.ChartEditorState;
import funkin.ui.MusicBeatSubState; import funkin.ui.MusicBeatSubState;
@ -71,7 +72,7 @@ class DebugMenuSubState extends MusicBeatSubState
if (controls.BACK) if (controls.BACK)
{ {
FlxG.sound.play(Paths.sound('cancelMenu')); FunkinSound.playOnce(Paths.sound('cancelMenu'));
exitDebugMenu(); exitDebugMenu();
} }
} }

View file

@ -12,7 +12,6 @@ import flixel.graphics.frames.FlxAtlasFrames;
import flixel.graphics.frames.FlxFrame; import flixel.graphics.frames.FlxFrame;
import flixel.group.FlxGroup; import flixel.group.FlxGroup;
import flixel.math.FlxPoint; import flixel.math.FlxPoint;
import flixel.sound.FlxSound;
import flixel.text.FlxText; import flixel.text.FlxText;
import flixel.util.FlxColor; import flixel.util.FlxColor;
import funkin.util.MouseUtil; import funkin.util.MouseUtil;
@ -179,7 +178,7 @@ class DebugBoundingState extends FlxState
var objShit = js.html.URL.createObjectURL(swagList.item(0)); var objShit = js.html.URL.createObjectURL(swagList.item(0));
trace(objShit); trace(objShit);
var funnysound = new FlxSound().loadStream('https://cdn.discordapp.com/attachments/767500676166451231/817821618251759666/Flutter.mp3', false, false, var funnysound = new FunkinSound().loadStream('https://cdn.discordapp.com/attachments/767500676166451231/817821618251759666/Flutter.mp3', false, false,
null, function() { null, function() {
trace('LOADED SHIT??'); trace('LOADED SHIT??');
}); });

View file

@ -15,7 +15,6 @@ import flixel.input.mouse.FlxMouseEvent;
import flixel.math.FlxMath; import flixel.math.FlxMath;
import flixel.math.FlxPoint; import flixel.math.FlxPoint;
import flixel.math.FlxRect; import flixel.math.FlxRect;
import flixel.sound.FlxSound;
import flixel.system.debug.log.LogStyle; import flixel.system.debug.log.LogStyle;
import flixel.system.FlxAssets.FlxSoundAsset; import flixel.system.FlxAssets.FlxSoundAsset;
import flixel.text.FlxText; import flixel.text.FlxText;
@ -1091,7 +1090,7 @@ class ChartEditorState extends UIState // UIState derives from MusicBeatState
* The chill audio track that plays in the chart editor. * The chill audio track that plays in the chart editor.
* Plays when the main music is NOT being played. * Plays when the main music is NOT being played.
*/ */
var welcomeMusic:FlxSound = new FlxSound(); var welcomeMusic:FunkinSound = new FunkinSound();
/** /**
* The audio track for the instrumental. * The audio track for the instrumental.
@ -3888,8 +3887,8 @@ class ChartEditorState extends UIState // UIState derives from MusicBeatState
function handleCursor():Void function handleCursor():Void
{ {
// Mouse sounds // Mouse sounds
if (FlxG.mouse.justPressed) FlxG.sound.play(Paths.sound("chartingSounds/ClickDown")); if (FlxG.mouse.justPressed) FunkinSound.playOnce(Paths.sound("chartingSounds/ClickDown"));
if (FlxG.mouse.justReleased) FlxG.sound.play(Paths.sound("chartingSounds/ClickUp")); if (FlxG.mouse.justReleased) FunkinSound.playOnce(Paths.sound("chartingSounds/ClickUp"));
// Note: If a menu is open in HaxeUI, don't handle cursor behavior. // Note: If a menu is open in HaxeUI, don't handle cursor behavior.
var shouldHandleCursor:Bool = !(isHaxeUIFocused || playbarHeadDragging || isHaxeUIDialogOpen) var shouldHandleCursor:Bool = !(isHaxeUIFocused || playbarHeadDragging || isHaxeUIDialogOpen)

View file

@ -1,7 +1,6 @@
package funkin.ui.debug.charting.handlers; package funkin.ui.debug.charting.handlers;
import flixel.system.FlxAssets.FlxSoundAsset; import flixel.system.FlxAssets.FlxSoundAsset;
import flixel.sound.FlxSound;
import funkin.audio.VoicesGroup; import funkin.audio.VoicesGroup;
import funkin.audio.FunkinSound; import funkin.audio.FunkinSound;
import funkin.play.character.BaseCharacter.CharacterType; import funkin.play.character.BaseCharacter.CharacterType;
@ -302,7 +301,8 @@ class ChartEditorAudioHandler
trace('WARN: Failed to play sound $path, asset not found.'); trace('WARN: Failed to play sound $path, asset not found.');
return; return;
} }
var snd:FunkinSound = FunkinSound.load(asset); var snd:Null<FunkinSound> = FunkinSound.load(asset);
if (snd == null) return;
snd.autoDestroy = true; snd.autoDestroy = true;
snd.play(true); snd.play(true);
snd.volume = volume; snd.volume = volume;

View file

@ -71,8 +71,6 @@ class LatencyState extends MusicBeatSubState
// trace("EVENT LISTENER: " + key); // trace("EVENT LISTENER: " + key);
}); });
// FlxG.sound.playMusic(Paths.sound('soundTest'));
// funnyStatsGraph.hi // funnyStatsGraph.hi
Conductor.instance.forceBPM(60); Conductor.instance.forceBPM(60);
@ -242,13 +240,6 @@ class LatencyState extends MusicBeatSubState
} }
} }
/* if (FlxG.keys.justPressed.SPACE)
{
FlxG.sound.music.stop();
FlxG.resetState();
}*/
noteGrp.forEach(function(daNote:NoteSprite) { noteGrp.forEach(function(daNote:NoteSprite) {
daNote.y = (strumLine.y - ((Conductor.instance.songPosition - Conductor.instance.instrumentalOffset) - daNote.noteData.time) * 0.45); daNote.y = (strumLine.y - ((Conductor.instance.songPosition - Conductor.instance.instrumentalOffset) - daNote.noteData.time) * 0.45);
daNote.x = strumLine.x + 30; daNote.x = strumLine.x + 30;

View file

@ -37,8 +37,6 @@ class StageBuilderState extends MusicBeatState
FlxG.mouse.visible = true; FlxG.mouse.visible = true;
// var alsoSnd:FlxSound = new FlxSound();
// snd = new Sound(); // snd = new Sound();
// var swagBytes:ByteArray = new ByteArray(8192); // var swagBytes:ByteArray = new ByteArray(8192);

View file

@ -4,8 +4,8 @@ import flixel.FlxSprite;
import flixel.util.FlxSignal; import flixel.util.FlxSignal;
import funkin.util.assets.FlxAnimationUtil; import funkin.util.assets.FlxAnimationUtil;
import funkin.graphics.adobeanimate.FlxAtlasSprite; import funkin.graphics.adobeanimate.FlxAtlasSprite;
import flixel.sound.FlxSound;
import flixel.util.FlxTimer; import flixel.util.FlxTimer;
import funkin.audio.FunkinSound;
import funkin.audio.FlxStreamSound; import funkin.audio.FlxStreamSound;
class DJBoyfriend extends FlxAtlasSprite class DJBoyfriend extends FlxAtlasSprite
@ -178,7 +178,7 @@ class DJBoyfriend extends FlxAtlasSprite
if (cartoonSnd == null) if (cartoonSnd == null)
{ {
// tv is OFF, but getting turned on // tv is OFF, but getting turned on
FlxG.sound.play(Paths.sound('tv_on')); FunkinSound.playOnce(Paths.sound('tv_on'));
cartoonSnd = new FlxStreamSound(); cartoonSnd = new FlxStreamSound();
FlxG.sound.defaultSoundGroup.add(cartoonSnd); FlxG.sound.defaultSoundGroup.add(cartoonSnd);
@ -187,7 +187,7 @@ class DJBoyfriend extends FlxAtlasSprite
{ {
// plays it smidge after the click // plays it smidge after the click
new FlxTimer().start(0.1, function(_) { new FlxTimer().start(0.1, function(_) {
FlxG.sound.play(Paths.sound('channel_switch')); FunkinSound.playOnce(Paths.sound('channel_switch'));
}); });
} }
// cartoonSnd.loadEmbedded(Paths.sound("cartoons/peck")); // cartoonSnd.loadEmbedded(Paths.sound("cartoons/peck"));

View file

@ -174,7 +174,11 @@ class FreeplayState extends MusicBeatSubState
isDebug = true; isDebug = true;
#end #end
FunkinSound.playMusic('freakyMenu'); FunkinSound.playMusic('freakyMenu',
{
overrideExisting: true,
restartTrack: false
});
// Add a null entry that represents the RANDOM option // Add a null entry that represents the RANDOM option
songs.push(null); songs.push(null);
@ -867,7 +871,7 @@ class FreeplayState extends MusicBeatSubState
FlxTimer.globalManager.clear(); FlxTimer.globalManager.clear();
dj.onIntroDone.removeAll(); dj.onIntroDone.removeAll();
FlxG.sound.play(Paths.sound('cancelMenu')); FunkinSound.playOnce(Paths.sound('cancelMenu'));
var longestTimer:Float = 0; var longestTimer:Float = 0;
@ -1058,7 +1062,7 @@ class FreeplayState extends MusicBeatSubState
trace('No songs available!'); trace('No songs available!');
busy = false; busy = false;
letterSort.inputEnabled = true; letterSort.inputEnabled = true;
FlxG.sound.play(Paths.sound('cancelMenu')); FunkinSound.playOnce(Paths.sound('cancelMenu'));
return; return;
} }
@ -1091,7 +1095,7 @@ class FreeplayState extends MusicBeatSubState
PlayStatePlaylist.campaignId = cap.songData.levelId; PlayStatePlaylist.campaignId = cap.songData.levelId;
// Visual and audio effects. // Visual and audio effects.
FlxG.sound.play(Paths.sound('confirmMenu')); FunkinSound.playOnce(Paths.sound('confirmMenu'));
dj.confirm(); dj.confirm();
new FlxTimer().start(1, function(tmr:FlxTimer) { new FlxTimer().start(1, function(tmr:FlxTimer) {
@ -1133,8 +1137,7 @@ class FreeplayState extends MusicBeatSubState
function changeSelection(change:Int = 0):Void function changeSelection(change:Int = 0):Void
{ {
FlxG.sound.play(Paths.sound('scrollMenu'), 0.4); FunkinSound.playOnce(Paths.sound('scrollMenu'), 0.4);
// FlxG.sound.playMusic(Paths.inst(songs[curSelected].songName));
var prevSelected:Int = curSelected; var prevSelected:Int = curSelected;
@ -1177,15 +1180,25 @@ class FreeplayState extends MusicBeatSubState
{ {
if (curSelected == 0) if (curSelected == 0)
{ {
FlxG.sound.playMusic(Paths.music('freeplay/freeplayRandom'), 0); FunkinSound.playMusic('freeplayRandom',
{
startingVolume: 0.0,
overrideExisting: true,
restartTrack: true
});
FlxG.sound.music.fadeIn(2, 0, 0.8); FlxG.sound.music.fadeIn(2, 0, 0.8);
} }
else else
{ {
// TODO: Stream the instrumental of the selected song? // TODO: Stream the instrumental of the selected song?
if (prevSelected == 0) var didReplace:Bool = FunkinSound.playMusic('freakyMenu',
{
startingVolume: 0.0,
overrideExisting: true,
restartTrack: false
});
if (didReplace)
{ {
FunkinSound.playMusic('freakyMenu');
FlxG.sound.music.fadeIn(2, 0, 0.8); FlxG.sound.music.fadeIn(2, 0, 0.8);
} }
} }

View file

@ -155,7 +155,11 @@ class MainMenuState extends MusicBeatState
function playMenuMusic():Void function playMenuMusic():Void
{ {
FunkinSound.playMusic('freakyMenu'); FunkinSound.playMusic('freakyMenu',
{
overrideExisting: true,
restartTrack: false
});
} }
function resetCamStuff() function resetCamStuff()
@ -321,7 +325,7 @@ class MainMenuState extends MusicBeatState
if (controls.BACK && menuItems.enabled && !menuItems.busy) if (controls.BACK && menuItems.enabled && !menuItems.busy)
{ {
FlxG.sound.play(Paths.sound('cancelMenu')); FunkinSound.playOnce(Paths.sound('cancelMenu'));
FlxG.switchState(() -> new TitleState()); FlxG.switchState(() -> new TitleState());
} }
} }

View file

@ -5,9 +5,11 @@ import flixel.FlxSubState;
import flixel.addons.transition.FlxTransitionableState; import flixel.addons.transition.FlxTransitionableState;
import flixel.group.FlxGroup; import flixel.group.FlxGroup;
import flixel.util.FlxSignal; import flixel.util.FlxSignal;
import funkin.audio.FunkinSound;
import funkin.ui.mainmenu.MainMenuState; import funkin.ui.mainmenu.MainMenuState;
import funkin.ui.MusicBeatState; import funkin.ui.MusicBeatState;
import funkin.util.WindowUtil; import funkin.util.WindowUtil;
import funkin.audio.FunkinSound;
import funkin.input.Controls; import funkin.input.Controls;
class OptionsState extends MusicBeatState class OptionsState extends MusicBeatState
@ -143,7 +145,7 @@ class Page extends FlxGroup
{ {
if (canExit && controls.BACK) if (canExit && controls.BACK)
{ {
FlxG.sound.play(Paths.sound('cancelMenu')); FunkinSound.playOnce(Paths.sound('cancelMenu'));
exit(); exit();
} }
} }

View file

@ -231,7 +231,11 @@ class StoryMenuState extends MusicBeatState
function playMenuMusic():Void function playMenuMusic():Void
{ {
FunkinSound.playMusic('freakyMenu'); FunkinSound.playMusic('freakyMenu',
{
overrideExisting: true,
restartTrack: false
});
} }
function updateData():Void function updateData():Void
@ -382,7 +386,7 @@ class StoryMenuState extends MusicBeatState
if (controls.BACK && !exitingMenu && !selectedLevel) if (controls.BACK && !exitingMenu && !selectedLevel)
{ {
FlxG.sound.play(Paths.sound('cancelMenu')); FunkinSound.playOnce(Paths.sound('cancelMenu'));
exitingMenu = true; exitingMenu = true;
FlxG.switchState(() -> new MainMenuState()); FlxG.switchState(() -> new MainMenuState());
} }
@ -511,7 +515,7 @@ class StoryMenuState extends MusicBeatState
{ {
if (!currentLevel.isUnlocked()) if (!currentLevel.isUnlocked())
{ {
FlxG.sound.play(Paths.sound('cancelMenu')); FunkinSound.playOnce(Paths.sound('cancelMenu'));
return; return;
} }
@ -519,7 +523,7 @@ class StoryMenuState extends MusicBeatState
selectedLevel = true; selectedLevel = true;
FlxG.sound.play(Paths.sound('confirmMenu')); FunkinSound.playOnce(Paths.sound('confirmMenu'));
currentLevelTitle.isFlashing = true; currentLevelTitle.isFlashing = true;

View file

@ -22,7 +22,11 @@ class AttractState extends MusicBeatState
public override function create():Void public override function create():Void
{ {
// Pause existing music. // Pause existing music.
FlxG.sound.music.stop(); if (FlxG.sound.music != null)
{
FlxG.sound.music.destroy();
FlxG.sound.music = null;
}
#if html5 #if html5
playVideoHTML5(ATTRACT_VIDEO_PATH); playVideoHTML5(ATTRACT_VIDEO_PATH);

View file

@ -222,10 +222,14 @@ class TitleState extends MusicBeatState
{ {
var shouldFadeIn = (FlxG.sound.music == null); var shouldFadeIn = (FlxG.sound.music == null);
// Load music. Includes logic to handle BPM changes. // Load music. Includes logic to handle BPM changes.
FunkinSound.playMusic('freakyMenu', false, true); FunkinSound.playMusic('freakyMenu',
FlxG.sound.music.volume = 0; {
startingVolume: 0.0,
overrideExisting: true,
restartTrack: true
});
// Fade from 0.0 to 0.7 over 4 seconds // Fade from 0.0 to 0.7 over 4 seconds
if (shouldFadeIn) FlxG.sound.music.fadeIn(4, 0, 0.7); if (shouldFadeIn) FlxG.sound.music.fadeIn(4.0, 0.0, 0.7);
} }
function getIntroTextShit():Array<Array<String>> function getIntroTextShit():Array<Array<String>>
@ -323,7 +327,7 @@ class TitleState extends MusicBeatState
if (Date.now().getDay() == 5) NGio.unlockMedal(61034); if (Date.now().getDay() == 5) NGio.unlockMedal(61034);
titleText.animation.play('press'); titleText.animation.play('press');
FlxG.camera.flash(FlxColor.WHITE, 1); FlxG.camera.flash(FlxColor.WHITE, 1);
FlxG.sound.play(Paths.sound('confirmMenu'), 0.7); FunkinSound.playOnce(Paths.sound('confirmMenu'), 0.7);
transitioning = true; transitioning = true;
var targetState:NextState = () -> new MainMenuState(); var targetState:NextState = () -> new MainMenuState();
@ -338,7 +342,7 @@ class TitleState extends MusicBeatState
// ngSpr?? // ngSpr??
FlxG.switchState(targetState); FlxG.switchState(targetState);
}); });
// FlxG.sound.play(Paths.music('titleShoot'), 0.7); // FunkinSound.playOnce(Paths.music('titleShoot'), 0.7);
} }
if (pressedEnter && !skippedIntro && initialized) skipIntro(); if (pressedEnter && !skippedIntro && initialized) skipIntro();
@ -385,14 +389,12 @@ class TitleState extends MusicBeatState
{ {
cheatActive = true; cheatActive = true;
FlxG.sound.playMusic(Paths.music('tutorialTitle'), 1);
var spec:SpectogramSprite = new SpectogramSprite(FlxG.sound.music); var spec:SpectogramSprite = new SpectogramSprite(FlxG.sound.music);
add(spec); add(spec);
Conductor.instance.forceBPM(190); Conductor.instance.forceBPM(190);
FlxG.camera.flash(FlxColor.WHITE, 1); FlxG.camera.flash(FlxColor.WHITE, 1);
FlxG.sound.play(Paths.sound('confirmMenu'), 0.7); FunkinSound.playOnce(Paths.sound('confirmMenu'), 0.7);
} }
function createCoolText(textArray:Array<String>) function createCoolText(textArray:Array<String>)

View file

@ -171,7 +171,12 @@ class LoadingState extends MusicBeatState
function onLoad():Void function onLoad():Void
{ {
if (stopMusic && FlxG.sound.music != null) FlxG.sound.music.stop(); // Stop the instrumental.
if (stopMusic && FlxG.sound.music != null)
{
FlxG.sound.music.destroy();
FlxG.sound.music = null;
}
FlxG.switchState(target); FlxG.switchState(target);
} }
@ -200,7 +205,8 @@ class LoadingState extends MusicBeatState
// All assets preloaded, switch directly to play state (defualt on other targets). // All assets preloaded, switch directly to play state (defualt on other targets).
if (shouldStopMusic && FlxG.sound.music != null) if (shouldStopMusic && FlxG.sound.music != null)
{ {
FlxG.sound.music.stop(); FlxG.sound.music.destroy();
FlxG.sound.music = null;
} }
// Load and cache the song's charts. // Load and cache the song's charts.

View file

@ -18,6 +18,7 @@ import flixel.addons.transition.FlxTransitionableState;
import openfl.display.BitmapData; import openfl.display.BitmapData;
import funkin.ui.freeplay.FreeplayState; import funkin.ui.freeplay.FreeplayState;
import openfl.geom.Matrix; import openfl.geom.Matrix;
import funkin.audio.FunkinSound;
import openfl.display.Sprite; import openfl.display.Sprite;
import openfl.display.Bitmap; import openfl.display.Bitmap;
import flixel.FlxState; import flixel.FlxState;
@ -137,7 +138,7 @@ class StickerSubState extends MusicBeatSubState
new FlxTimer().start(sticker.timing, _ -> { new FlxTimer().start(sticker.timing, _ -> {
sticker.visible = false; sticker.visible = false;
var daSound:String = FlxG.random.getObject(sounds); var daSound:String = FlxG.random.getObject(sounds);
FlxG.sound.play(Paths.sound(daSound)); FunkinSound.playOnce(Paths.sound(daSound));
if (grpStickers == null || ind == grpStickers.members.length - 1) if (grpStickers == null || ind == grpStickers.members.length - 1)
{ {
@ -227,7 +228,7 @@ class StickerSubState extends MusicBeatSubState
sticker.visible = true; sticker.visible = true;
var daSound:String = FlxG.random.getObject(sounds); var daSound:String = FlxG.random.getObject(sounds);
FlxG.sound.play(Paths.sound(daSound)); FunkinSound.playOnce(Paths.sound(daSound));
var frameTimer:Int = FlxG.random.int(0, 2); var frameTimer:Int = FlxG.random.int(0, 2);

View file

@ -19,6 +19,7 @@ class MathUtil
* *
* @return The interpolated value. * @return The interpolated value.
*/ */
@:deprecated('Use smoothLerp instead')
public static function coolLerp(base:Float, target:Float, ratio:Float):Float public static function coolLerp(base:Float, target:Float, ratio:Float):Float
{ {
return base + cameraLerp(ratio) * (target - base); return base + cameraLerp(ratio) * (target - base);

View file

@ -174,7 +174,7 @@ class ScreenshotPlugin extends FlxBasic
FlxTween.tween(flashSpr, {alpha: 0}, 0.15, {ease: FlxEase.quadOut, onComplete: _ -> FlxG.stage.removeChild(flashSpr)}); FlxTween.tween(flashSpr, {alpha: 0}, 0.15, {ease: FlxEase.quadOut, onComplete: _ -> FlxG.stage.removeChild(flashSpr)});
// Play a sound (auto-play is true). // Play a sound (auto-play is true).
FunkinSound.load(Paths.sound('screenshot'), 1.0, false, true, true); FunkinSound.playOnce(Paths.sound('screenshot'), 1.0);
} }
static final PREVIEW_INITIAL_DELAY = 0.25; // How long before the preview starts fading in. static final PREVIEW_INITIAL_DELAY = 0.25; // How long before the preview starts fading in.