diff --git a/building/libs.xml b/building/libs.xml
index 531a07713..897cf843e 100644
--- a/building/libs.xml
+++ b/building/libs.xml
@@ -18,6 +18,7 @@
+
diff --git a/project.xml b/project.xml
index 3d6399a14..76a1d0b58 100644
--- a/project.xml
+++ b/project.xml
@@ -115,6 +115,11 @@
+
+
+
@@ -127,6 +132,8 @@
+
+
diff --git a/source/funkin/backend/assets/Paths.hx b/source/funkin/backend/assets/Paths.hx
index 5b8d8395f..5b343cac6 100644
--- a/source/funkin/backend/assets/Paths.hx
+++ b/source/funkin/backend/assets/Paths.hx
@@ -81,25 +81,76 @@ class Paths
return getPath('data/$key.ps1', library);
static public function sound(key:String, ?library:String, ?ext:String)
+ {
+ if (ext == null)
+ for (path in Flags.SOUND_EXTENSIONS) {
+ var path = 'sounds/$key.$path';
+ if (OpenFlAssets.exists(path))
+ return getPath(path, library);
+ }
+
return getPath('sounds/$key.${ext != null ? ext : Flags.SOUND_EXT}', library);
+ }
public static inline function soundRandom(key:String, min:Int, max:Int, ?library:String)
return sound(key + FlxG.random.int(min, max), library);
- inline static public function music(key:String, ?library:String, ?ext:String)
+ static public function music(key:String, ?library:String, ?ext:String)
+ {
+ if (ext == null)
+ for (path in Flags.SOUND_EXTENSIONS)
+ {
+ var path = 'music/$key.$path';
+ if (OpenFlAssets.exists(getPath(path, library)))
+ return getPath(path, library);
+ }
+
return getPath('music/$key.${ext != null ? ext : Flags.SOUND_EXT}', library);
+ }
- inline static public function voices(song:String, ?difficulty:String, ?suffix:String = "", ?ext:String) {
+ static public function voices(song:String, ?difficulty:String, ?suffix:String = "", ?ext:String) {
if (difficulty == null) difficulty = Flags.DEFAULT_DIFFICULTY;
+
+ if (ext == null)
+ for (e in Flags.SOUND_EXTENSIONS)
+ {
+ var path = 'songs/$song/song/Voices$suffix-${difficulty}.$e';
+ trace(path + " | " + OpenFlAssets.exists(getPath(path, null)));
+ if (OpenFlAssets.exists(getPath(path, null)))
+ return getPath(path, null);
+
+ path = 'songs/$song/song/Voices$suffix.$e';
+ trace(path + " | " + OpenFlAssets.exists(getPath(path, null)));
+ if (OpenFlAssets.exists(getPath(path, null)))
+ return getPath(path, null);
+ }
+
if (ext == null) ext = Flags.SOUND_EXT;
var diff = getPath('songs/$song/song/Voices$suffix-${difficulty}.${ext}', null);
+ trace(diff);
return OpenFlAssets.exists(diff) ? diff : getPath('songs/$song/song/Voices$suffix.${ext}', null);
}
- inline static public function inst(song:String, ?difficulty:String, ?suffix:String = "", ?ext:String) {
+ static public function inst(song:String, ?difficulty:String, ?suffix:String = "", ?ext:String) {
if (difficulty == null) difficulty = Flags.DEFAULT_DIFFICULTY;
+
+ if (ext == null)
+ for (e in Flags.SOUND_EXTENSIONS)
+ {
+ var path = 'songs/$song/song/Inst$suffix-${difficulty}.$e';
+ trace(path + " | " + OpenFlAssets.exists(getPath(path, null)));
+ if (OpenFlAssets.exists(getPath(path, null)))
+ return getPath(path, null);
+
+ path = 'songs/$song/song/Inst$suffix.$e';
+ trace(path + " | " + OpenFlAssets.exists(getPath(path, null)));
+ if (OpenFlAssets.exists(getPath(path, null)))
+ return getPath(path, null);
+ }
+
if (ext == null) ext = Flags.SOUND_EXT;
var diff = getPath('songs/$song/song/Inst$suffix-${difficulty}.${ext}', null);
+ trace(diff);
return OpenFlAssets.exists(diff) ? diff : getPath('songs/$song/song/Inst$suffix.${ext}', null);
}
diff --git a/source/funkin/backend/chart/ChartData.hx b/source/funkin/backend/chart/ChartData.hx
index dfb514bde..c8ca39f43 100644
--- a/source/funkin/backend/chart/ChartData.hx
+++ b/source/funkin/backend/chart/ChartData.hx
@@ -39,6 +39,8 @@ typedef ChartMetaData = {
public var ?instSuffix:String;
public var ?vocalsSuffix:String;
public var ?needsVoices:Bool;
+
+ public var ?musicExt:String;
}
typedef ChartStrumLine = {
diff --git a/source/funkin/backend/scripting/Script.hx b/source/funkin/backend/scripting/Script.hx
index 8f7ee4372..3c0a9a7b8 100644
--- a/source/funkin/backend/scripting/Script.hx
+++ b/source/funkin/backend/scripting/Script.hx
@@ -107,7 +107,7 @@ class Script extends FlxBasic implements IFlxDestroyable {
#if TRANSLATIONS_SUPPORT
"TranslationUtil" => funkin.backend.utils.TranslationUtil,
- "translate" => funkin.backend.utils.TranslationUtil.get,
+ "translate" => funkin.backend.utils.TranslationUtil.get,
#end
];
}
diff --git a/source/funkin/backend/system/Flags.hx b/source/funkin/backend/system/Flags.hx
index 1b96f7260..3438056da 100644
--- a/source/funkin/backend/system/Flags.hx
+++ b/source/funkin/backend/system/Flags.hx
@@ -56,6 +56,11 @@ class Flags {
public static var REPO_OWNER:String = "CodenameCrew";
public static var REPO_URL:String = 'https://github.com/$REPO_OWNER/$REPO_NAME';
+ public static var SOUND_EXTENSIONS:Array = [
+ #if web "mp3" #else "ogg" #end,
+ "opus"
+ ];
+
/**
* Preferred sound extension for the game's audio files.
* Currently is set to `mp3` for web targets, and `ogg` for other targets.
diff --git a/source/funkin/editors/charter/Charter.hx b/source/funkin/editors/charter/Charter.hx
index 952fdacac..1baac0a08 100644
--- a/source/funkin/editors/charter/Charter.hx
+++ b/source/funkin/editors/charter/Charter.hx
@@ -608,9 +608,9 @@ class Charter extends UIState {
Conductor.setupSong(PlayState.SONG);
noteTypes = PlayState.SONG.noteTypes;
- FlxG.sound.setMusic(FlxG.sound.load(Paths.inst(__song, __diff, PlayState.SONG.meta.instSuffix)));
- if (Assets.exists(Paths.voices(__song, __diff, PlayState.SONG.meta.vocalsSuffix)))
- vocals = FlxG.sound.load(Paths.voices(__song, __diff, PlayState.SONG.meta.vocalsSuffix));
+ FlxG.sound.setMusic(FlxG.sound.load(Paths.inst(__song, __diff, PlayState.SONG.meta.instSuffix, PlayState.SONG.meta.musicExt)));
+ if (Assets.exists(Paths.voices(__song, __diff, PlayState.SONG.meta.vocalsSuffix, PlayState.SONG.meta.musicExt)))
+ vocals = FlxG.sound.load(Paths.voices(__song, __diff, PlayState.SONG.meta.vocalsSuffix, PlayState.SONG.meta.musicExt));
else
vocals = new FlxSound();
diff --git a/source/funkin/game/PlayState.hx b/source/funkin/game/PlayState.hx
index 76752ac43..b28d9dc01 100644
--- a/source/funkin/game/PlayState.hx
+++ b/source/funkin/game/PlayState.hx
@@ -1129,11 +1129,11 @@ class PlayState extends MusicBeatState
curSong = songData.meta.name.toLowerCase();
curSongID = curSong.replace(" ", "-");
- FlxG.sound.setMusic(inst = FlxG.sound.load(Assets.getMusic(Paths.inst(SONG.meta.name, difficulty, SONG.meta.instSuffix))));
+ FlxG.sound.setMusic(inst = FlxG.sound.load(Assets.getMusic(Paths.inst(SONG.meta.name, difficulty, SONG.meta.instSuffix, SONG.meta.musicExt))));
- var vocalsPath = Paths.voices(SONG.meta.name, difficulty, SONG.meta.vocalsSuffix);
+ var vocalsPath = Paths.voices(SONG.meta.name, difficulty, SONG.meta.vocalsSuffix, SONG.meta.musicExt);
if (SONG.meta.needsVoices && Assets.exists(vocalsPath))
- vocals = FlxG.sound.load(Options.streamedVocals ? Assets.getMusic(vocalsPath) : vocalsPath);
+ vocals = FlxG.sound.load(Options.streamedVocals ? Assets.getMusic(vocalsPath) : vocalsPath, SONG.meta.musicExt);
else
vocals = new FlxSound();
diff --git a/source/funkin/menus/FreeplayState.hx b/source/funkin/menus/FreeplayState.hx
index 69fc3d8de..d82615356 100644
--- a/source/funkin/menus/FreeplayState.hx
+++ b/source/funkin/menus/FreeplayState.hx
@@ -259,7 +259,7 @@ class FreeplayState extends MusicBeatState
var dontPlaySongThisFrame = false;
autoplayElapsed += elapsed;
if (!disableAutoPlay && !songInstPlaying && (autoplayElapsed > timeUntilAutoplay)) {
- if (curPlayingInst != (curPlayingInst = Paths.inst(curSong.name, curDifficulties[curDifficulty], curSong.instSuffix))) {
+ if (curPlayingInst != (curPlayingInst = Paths.inst(curSong.name, curDifficulties[curDifficulty], curSong.instSuffix, curSong.musicExt))) {
var streamed = false;
if (Options.streamedMusic) {
var sound = Assets.getMusic(curPlayingInst, true, false);
diff --git a/source/openfl/utils/Assets.hx b/source/openfl/utils/Assets.hx
index c14b9f2c9..5ac054dcf 100644
--- a/source/openfl/utils/Assets.hx
+++ b/source/openfl/utils/Assets.hx
@@ -22,6 +22,9 @@ import lime.utils.Assets as LimeAssets;
import lime.media.AudioBuffer;
import lime.media.vorbis.VorbisFile;
#end
+#if OPUS_AUDIO_PLAYBACK
+import hxopus.Opus;
+#end
/**
The Assets class provides a cross-platform interface to access
@@ -288,13 +291,10 @@ class Assets
var sound = cache.getSound(id);
if (isValidSound(sound))
- {
return sound;
- }
}
var buffer = LimeAssets.getAudioBuffer(id, false);
-
if (buffer != null)
{
#if flash
@@ -304,12 +304,25 @@ class Assets
#end
if (useCache && cache.enabled)
- {
cache.setSound(id, sound);
- }
return sound;
}
+
+ #if OPUS_AUDIO_PLAYBACK
+ // Try to load as Opus if normal loading failed
+ var bytes = getBytes(id);
+ if (bytes != null)
+ {
+ var sound = Opus.toOpenFL(bytes);
+
+ if (useCache && cache.enabled)
+ cache.setSound(id, sound);
+
+ return sound;
+ }
+ #end
+
#end
return null;