diff --git a/flixel/sound/FlxSound.hx b/flixel/sound/FlxSound.hx index 168c52000a..e3b43c644d 100644 --- a/flixel/sound/FlxSound.hx +++ b/flixel/sound/FlxSound.hx @@ -333,56 +333,67 @@ class FlxSound extends FlxBasic } /** - * One of the main setup functions for sounds, this function loads a sound from an embedded MP3. - * + * Loads a sound from the provided sound asset. + * The asset can be an OpenFL Sound instance, embedded sound, file path or byte array. + * * **Note:** If the `FLX_DEFAULT_SOUND_EXT` flag is enabled, you may omit the file extension - * - * @param EmbeddedSound An embedded Class object representing an MP3 file. - * @param Looped Whether or not this sound should loop endlessly. - * @param AutoDestroy Whether or not this FlxSound instance should be destroyed when the sound finishes playing. - * Default value is false, but `FlxG.sound.play()` and `FlxG.sound.stream()` will set it to true by default. - * @param OnComplete Called when the sound finished playing - * @return This FlxSound instance (nice for chaining stuff together, if you're into that). + * + * @param sound The sound asset to load. + * @param looped Whether or not this sound should loop endlessly. + * @param autoDestroy Whether or not this FlxSound instance should be destroyed when the sound finishes playing. + * @param onComplete Called when the sound finishes playing. + * @return This FlxSound instance (nice for chaining stuff together, if you're into that). + * + * @since 6.2.0 */ - public function loadEmbedded(EmbeddedSound:FlxSoundAsset, Looped:Bool = false, AutoDestroy:Bool = false, ?OnComplete:Void->Void):FlxSound + public function load(sound:FlxSoundAsset, looped:Bool = false, autoDestroy:Bool = false, ?onComplete:Void->Void):FlxSound { - if (EmbeddedSound == null) + if (sound == null) return this; cleanup(true); - if ((EmbeddedSound is Sound)) + if ((sound is Sound)) { - _sound = EmbeddedSound; + _sound = sound; } - else if ((EmbeddedSound is Class)) + else if ((sound is Class)) { - _sound = Type.createInstance(EmbeddedSound, []); + _sound = Type.createInstance(sound, []); } - else if ((EmbeddedSound is String)) + else if ((sound is String)) { - if (FlxG.assets.exists(EmbeddedSound, SOUND)) - _sound = FlxG.assets.getSoundUnsafe(EmbeddedSound); + if (FlxG.assets.exists(sound, SOUND)) + _sound = FlxG.assets.getSoundUnsafe(sound); else - FlxG.log.error('Could not find a Sound asset with an ID of \'$EmbeddedSound\'.'); + FlxG.log.error('Could not find a Sound asset with an ID of \'$sound\'.'); + } + else if ((sound is ByteArrayData)) + { + var bytes:ByteArray = cast sound; + + _sound = new Sound(); + _sound.addEventListener(Event.ID3, gotID3); + _sound.loadCompressedDataFromByteArray(bytes, bytes.length); } // NOTE: can't pull ID3 info from embedded sound currently - return init(Looped, AutoDestroy, OnComplete); + return init(looped, autoDestroy, onComplete); } - + /** - * One of the main setup functions for sounds, this function loads a sound from a URL. - * - * @param SoundURL A string representing the URL of the MP3 file you want to play. - * @param Looped Whether or not this sound should loop endlessly. - * @param AutoDestroy Whether or not this FlxSound instance should be destroyed when the sound finishes playing. - * Default value is false, but `FlxG.sound.play()` and `FlxG.sound.stream()` will set it to true by default. - * @param OnComplete Called when the sound finished playing - * @param OnLoad Called when the sound finished loading. - * @return This FlxSound instance (nice for chaining stuff together, if you're into that). + * Loads a sound from the provided URL. + * + * @param soundURL A string representing the URL of the sound you want to play. + * @param looped Whether or not this sound should loop endlessly. + * @param autoDestroy Whether or not this FlxSound instance should be destroyed when the sound finishes playing. + * @param onComplete Called when the sound finishes playing. + * @param onLoad Called when the sound finishes loading. + * @return This FlxSound instance (nice for chaining stuff together, if you're into that). + * + * @since 6.2.0 */ - public function loadStream(SoundURL:String, Looped:Bool = false, AutoDestroy:Bool = false, ?OnComplete:Void->Void, ?OnLoad:Void->Void):FlxSound + public function loadFromURL(soundURL:String, looped:Bool = false, autoDestroy:Bool = false, ?onComplete:Void->Void, ?onLoad:Void->Void):FlxSound { cleanup(true); @@ -396,15 +407,50 @@ class FlxSound extends FlxBasic if (_sound == e.target) { _length = _sound.length; - if (OnLoad != null) - OnLoad(); + if (onLoad != null) + onLoad(); } } // Use a weak reference so this can be garbage collected if destroyed before loading. _sound.addEventListener(Event.COMPLETE, loadCallback, false, 0, true); - _sound.load(new URLRequest(SoundURL)); + _sound.load(new URLRequest(soundURL)); - return init(Looped, AutoDestroy, OnComplete); + return init(looped, autoDestroy, onComplete); + } + + /** + * One of the main setup functions for sounds, this function loads a sound from an embedded MP3. + * + * **Note:** If the `FLX_DEFAULT_SOUND_EXT` flag is enabled, you may omit the file extension + * + * @param EmbeddedSound An embedded Class object representing an MP3 file. + * @param Looped Whether or not this sound should loop endlessly. + * @param AutoDestroy Whether or not this FlxSound instance should be destroyed when the sound finishes playing. + * Default value is false, but `FlxG.sound.play()` and `FlxG.sound.loadFromURL()` will set it to true by default. + * @param OnComplete Called when the sound finished playing + * @return This FlxSound instance (nice for chaining stuff together, if you're into that). + */ + @:deprecated("loadEmbedded() is deprecated, use load() instead.") + public function loadEmbedded(EmbeddedSound:FlxSoundAsset, Looped:Bool = false, AutoDestroy:Bool = false, ?OnComplete:Void->Void):FlxSound + { + return load(EmbeddedSound, Looped, AutoDestroy, OnComplete); + } + + /** + * One of the main setup functions for sounds, this function loads a sound from a URL. + * + * @param SoundURL A string representing the URL of the MP3 file you want to play. + * @param Looped Whether or not this sound should loop endlessly. + * @param AutoDestroy Whether or not this FlxSound instance should be destroyed when the sound finishes playing. + * Default value is false, but `FlxG.sound.play()` and `FlxG.sound.loadFromURL()` will set it to true by default. + * @param OnComplete Called when the sound finished playing + * @param OnLoad Called when the sound finished loading. + * @return This FlxSound instance (nice for chaining stuff together, if you're into that). + */ + @:deprecated("loadStream() is deprecated, use loadFromURL() instead.") + public function loadStream(SoundURL:String, Looped:Bool = false, AutoDestroy:Bool = false, ?OnComplete:Void->Void, ?OnLoad:Void->Void):FlxSound + { + return loadFromURL(SoundURL, Looped, AutoDestroy, OnComplete, OnLoad); } /** @@ -413,18 +459,13 @@ class FlxSound extends FlxBasic * @param Bytes A ByteArray object. * @param Looped Whether or not this sound should loop endlessly. * @param AutoDestroy Whether or not this FlxSound instance should be destroyed when the sound finishes playing. - * Default value is false, but `FlxG.sound.play()` and `FlxG.sound.stream()` will set it to true by default. + * Default value is false, but `FlxG.sound.play()` and `FlxG.sound.loadFromURL()` will set it to true by default. * @return This FlxSound instance (nice for chaining stuff together, if you're into that). */ + @:deprecated("loadByteArray() is deprecated, use load() instead.") public function loadByteArray(Bytes:ByteArray, Looped:Bool = false, AutoDestroy:Bool = false, ?OnComplete:Void->Void):FlxSound { - cleanup(true); - - _sound = new Sound(); - _sound.addEventListener(Event.ID3, gotID3); - _sound.loadCompressedDataFromByteArray(Bytes, Bytes.length); - - return init(Looped, AutoDestroy, OnComplete); + return load(Bytes, Looped, AutoDestroy, OnComplete); } function init(Looped:Bool = false, AutoDestroy:Bool = false, ?OnComplete:Void->Void):FlxSound diff --git a/flixel/system/FlxAssets.hx b/flixel/system/FlxAssets.hx index 93c256537a..9486f40167 100644 --- a/flixel/system/FlxAssets.hx +++ b/flixel/system/FlxAssets.hx @@ -35,7 +35,7 @@ class VirtualInputData extends #if nme ByteArray #else ByteArrayData #end {} typedef FlxTexturePackerJsonAsset = FlxJsonAsset; typedef FlxAsepriteJsonAsset = FlxJsonAsset; -typedef FlxSoundAsset = OneOfThree>; +typedef FlxSoundAsset = OneOfFour, ByteArray>; typedef FlxGraphicAsset = OneOfThree; typedef FlxTilemapGraphicAsset = OneOfFour; typedef FlxBitmapFontGraphicAsset = OneOfFour; diff --git a/flixel/system/frontEnds/AssetFrontEnd.hx b/flixel/system/frontEnds/AssetFrontEnd.hx index 47fe7fe95d..be882385fe 100644 --- a/flixel/system/frontEnds/AssetFrontEnd.hx +++ b/flixel/system/frontEnds/AssetFrontEnd.hx @@ -341,7 +341,7 @@ class AssetFrontEnd * * @param id The ID or asset path for the sound * @param useCache Whether to allow use of the asset cache (if one exists) - * @return A new `Sound` object Note: Dos not return a `FlxSound` + * @return A new `Sound` object Note: Does not return a `FlxSound` */ public inline function getSoundUnsafe(id:String, useCache = true):Sound { @@ -356,7 +356,7 @@ class AssetFrontEnd * @param id The ID or asset path for the sound * @param useCache Whether to allow use of the asset cache (if one exists) * @param logStyle How to log, if the asset is not found. Uses `LogStyle.ERROR` by default - * @return A new `Sound` object Note: Dos not return a `FlxSound` + * @return A new `Sound` object Note: Does not return a `FlxSound` */ public inline function getSound(id:String, useCache = true, ?logStyle:LogStyle):Sound { @@ -369,7 +369,7 @@ class AssetFrontEnd * @param id The ID or asset path for the sound * @param useCache Whether to allow use of the asset cache (if one exists) * @param logStyle How to log, if the asset is not found. Uses `LogStyle.ERROR` by default - * @return A new `Sound` object Note: Dos not return a `FlxSound` + * @return A new `Sound` object Note: Does not return a `FlxSound` */ public inline function getSoundAddExt(id:String, useCache = true, ?logStyle:LogStyle):Sound { @@ -387,7 +387,8 @@ class AssetFrontEnd inline function addSoundExt(id:String) { - if (!id.endsWith(".mp3") && !id.endsWith(".ogg") && !id.endsWith(".wav")) + final needsExt = Path.extension(id).length == 0; + if (needsExt) return id + defaultSoundExtension; return id; diff --git a/flixel/system/frontEnds/SoundFrontEnd.hx b/flixel/system/frontEnds/SoundFrontEnd.hx index fcefac22f5..1d1acce241 100644 --- a/flixel/system/frontEnds/SoundFrontEnd.hx +++ b/flixel/system/frontEnds/SoundFrontEnd.hx @@ -86,7 +86,7 @@ class SoundFrontEnd public var defaultMusicGroup:FlxSoundGroup = new FlxSoundGroup(); /** - * The group sounds in load() / play() / stream() are added to unless specified otherwise. + * The group sounds in load() / loadFromURL() / play() are added to unless specified otherwise. */ public var defaultSoundGroup:FlxSoundGroup = new FlxSoundGroup(); @@ -124,7 +124,7 @@ class SoundFrontEnd music.stop(); } - music.loadEmbedded(embeddedMusic, looped); + music.load(embeddedMusic, looped); music.volume = volume; music.persist = true; group.add(music); @@ -161,7 +161,7 @@ class SoundFrontEnd if (embeddedSound != null) { - sound.loadEmbedded(embeddedSound, looped, autoDestroy, onComplete); + sound.load(embeddedSound, looped, autoDestroy, onComplete); loadHelper(sound, volume, group, autoPlay); // Call OnlLoad() because the sound already loaded if (onLoad != null && sound._sound != null) @@ -182,7 +182,7 @@ class SoundFrontEnd } } - sound.loadStream(url, looped, autoDestroy, onComplete, loadCallback); + sound.loadFromURL(url, looped, autoDestroy, onComplete, loadCallback); loadHelper(sound, volume, group); } @@ -251,7 +251,7 @@ class SoundFrontEnd { embeddedSound = cache(embeddedSound); } - var sound = list.recycle(FlxSound).loadEmbedded(embeddedSound, looped, autoDestroy, onComplete); + var sound = list.recycle(FlxSound).load(embeddedSound, looped, autoDestroy, onComplete); return loadHelper(sound, volume, group, true); } @@ -269,12 +269,33 @@ class SoundFrontEnd * @param onLoad Called when the sound finished loading. * @return A FlxSound object. */ - public function stream(url:String, volume = 1.0, looped = false, ?group:FlxSoundGroup, autoDestroy = true, ?onComplete:Void->Void, + public function loadFromURL(url:String, volume = 1.0, looped = false, ?group:FlxSoundGroup, autoDestroy = true, ?onComplete:Void->Void, ?onLoad:Void->Void):FlxSound { return load(null, volume, looped, group, autoDestroy, true, url, onComplete, onLoad); } + /** + * Plays a sound from a URL. Tries to recycle a cached sound first. + * NOTE: Just calls FlxG.sound.load() with AutoPlay == true. + * + * @param url Load a sound from an external web resource instead. + * @param volume How loud to play it (0 to 1). + * @param looped Whether to loop this sound. + * @param group The group to add this sound to. + * @param autoDestroy Whether to destroy this sound when it finishes playing. + * Leave this value set to "false" if you want to re-use this FlxSound instance. + * @param onComplete Called when the sound finished playing + * @param onLoad Called when the sound finished loading. + * @return A FlxSound object. + */ + @:deprecated("FlxG.sound.stream() is deprecated, use FlxG.sound.loadFromURL() instead") + public function stream(url:String, volume = 1.0, looped = false, ?group:FlxSoundGroup, autoDestroy = true, ?onComplete:Void->Void, + ?onLoad:Void->Void):FlxSound + { + return loadFromURL(url, volume, looped, group, autoDestroy, onComplete, onLoad); + } + /** * Pause all sounds currently playing. */ diff --git a/tests/unit/src/flixel/sound/FlxSoundTest.hx b/tests/unit/src/flixel/sound/FlxSoundTest.hx index 9a8ea01f9c..a43e729940 100644 --- a/tests/unit/src/flixel/sound/FlxSoundTest.hx +++ b/tests/unit/src/flixel/sound/FlxSoundTest.hx @@ -3,10 +3,10 @@ package flixel.sound; class FlxSoundTest { @Test // #1511 - function testLoadEmbeddedInvalidSoundPathNoCrash() + function testLoadInvalidSoundPathNoCrash() { var sound = new FlxSound(); - sound.loadEmbedded("assets/invalid"); + sound.load("assets/invalid"); sound.play(); } }