Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
32 changes: 31 additions & 1 deletion flixel/sound/FlxSound.hx
Original file line number Diff line number Diff line change
Expand Up @@ -370,7 +370,37 @@ class FlxSound extends FlxBasic
// NOTE: can't pull ID3 info from embedded sound currently
return init(Looped, AutoDestroy, OnComplete);
}


/**
* Loads a streamed sound from the provided file path.
* This does not load sounds from web locations. Use `loadFromURL()` for that, instead.
*
* Audio streaming may not be supported for some targets or files. If audio streaming is
* not supported, the default sound loading behavior will be used as a fallback.
*
* **Note:** If the `FLX_DEFAULT_SOUND_EXT` flag is enabled, you may omit the file extension
*
* @param path The ID or asset path to the sound asset.
* @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 loadStreamed(path:String, looped:Bool = false, autoDestroy:Bool = false, ?onComplete:Void->Void):FlxSound
{
cleanup(true);

if (FlxG.assets.exists(path, MUSIC))
_sound = FlxG.assets.getMusicUnsafe(path);
else
FlxG.log.error('Could not find a Music asset with an ID of \'$path\'.');

// NOTE: can't pull ID3 info from embedded sound currently
return init(looped, autoDestroy, onComplete);
}

/**
* One of the main setup functions for sounds, this function loads a sound from a URL.
*
Expand Down
105 changes: 99 additions & 6 deletions flixel/system/frontEnds/AssetFrontEnd.hx
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,11 @@ import openfl.utils.AssetCache;
import openfl.utils.Future;
import openfl.text.Font;

#if lime_vorbis
import lime.media.vorbis.VorbisFile;
import lime.media.AudioBuffer;
#end

using StringTools;

/**
Expand Down Expand Up @@ -123,7 +128,7 @@ class AssetFrontEnd
// Check cache
case IMAGE if (canUseCache && Assets.cache.hasBitmapData(id)):
Assets.cache.getBitmapData(id);
case SOUND if (canUseCache && Assets.cache.hasSound(id)):
case SOUND, MUSIC if (canUseCache && Assets.cache.hasSound(id)):
Assets.cache.getSound(id);
case FONT if (canUseCache && Assets.cache.hasFont(id)):
Assets.cache.getFont(id);
Expand All @@ -139,6 +144,24 @@ class AssetFrontEnd
if (canUseCache)
Assets.cache.setSound(id, sound);
sound;
case MUSIC:
var sound:Sound;
#if lime_vorbis
final vorbisFile = VorbisFile.fromFile(getPath(id));
if (vorbisFile != null)
{
final buffer = AudioBuffer.fromVorbisFile(buffer);
sound = Sound.fromAudioBuffer(buffer);
}
else
#end
{
// can't stream this sound, fall back to default behavior
sound = Sound.fromFile(getPath(id));
if (canUseCache)
Assets.cache.setSound(id, sound);
}
sound;
case FONT:
final font = Font.fromFile(getPath(id));
if (canUseCache)
Expand All @@ -159,6 +182,7 @@ class AssetFrontEnd
case BINARY: Assets.getBytes(id);
case IMAGE: Assets.getBitmapData(id, useCache);
case SOUND: Assets.getSound(id, useCache);
case MUSIC: Assets.getMusic(id, useCache);
case FONT: Assets.getFont(id, useCache);
}
}
Expand Down Expand Up @@ -224,6 +248,7 @@ class AssetFrontEnd
case BINARY: Assets.loadBytes(id);
case IMAGE: Assets.loadBitmapData(id, useCache);
case SOUND: Assets.loadSound(id, useCache);
case MUSIC: Assets.loadMusic(id, useCache);
case FONT: Assets.loadFont(id, useCache);
}
}
Expand All @@ -239,7 +264,7 @@ class AssetFrontEnd
{
#if FLX_DEFAULT_SOUND_EXT
// add file extension
if (type == SOUND)
if (type == SOUND || type == MUSIC)
id = addSoundExt(id);
#end

Expand Down Expand Up @@ -267,7 +292,7 @@ class AssetFrontEnd
{
#if FLX_DEFAULT_SOUND_EXT
// add file extension
if (type == SOUND)
if (type == SOUND || type == MUSIC)
id = addSoundExt(id);
#end

Expand Down Expand Up @@ -341,12 +366,27 @@ 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
{
return cast getAssetUnsafe(addSoundExtIf(id), SOUND, useCache);
}

/**
* Gets an instance of a streamed sound. Unlike its "safe" counterpart, there is no log on missing assets
*
* Audio streaming may not be supported for some targets or files. If audio streaming is
* not supported, a `SOUND` asset will be returned instead.
*
* @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: Does not return a `FlxSound`
*/
public inline function getMusicUnsafe(id:String, useCache = true):Sound
{
return cast getAssetUnsafe(addSoundExtIf(id), MUSIC, useCache);
}

/**
* Gets an instance of a sound, logs when the asset is not found.
Expand All @@ -356,25 +396,59 @@ 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
{
return cast getAsset(addSoundExtIf(id), SOUND, useCache, logStyle);
}

/**
* Gets an instance of a streamed sound, logs when the asset is not found.
*
* Audio streaming may not be supported for some targets or files. If audio streaming is
* not supported, a `SOUND` asset will be returned instead.
*
* **Note:** If the `FLX_DEFAULT_SOUND_EXT` flag is enabled, you may omit the file extension
*
* @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: Does not return a `FlxSound`
*/
public inline function getMusic(id:String, useCache = true, ?logStyle:LogStyle):Sound
{
return cast getAsset(addSoundExtIf(id), MUSIC, useCache, logStyle);
}

/**
* Gets an instance of a sound, logs when the asset is not found
*
* @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
{
return getSound(addSoundExt(id), useCache, logStyle);
}

/**
* Gets an instance of a streamed sound, logs when the asset is not found
*
* Audio streaming may not be supported for some targets or files. If audio streaming is
* not supported, a `SOUND` asset will be returned instead.
*
* @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: Does not return a `FlxSound`
*/
public inline function getMusicAddExt(id:String, useCache = true, ?logStyle:LogStyle):Sound
{
return getMusic(addSoundExt(id), useCache, logStyle);
}

inline function addSoundExtIf(id:String)
{
Expand Down Expand Up @@ -557,6 +631,21 @@ class AssetFrontEnd
{
return cast loadAsset(id, SOUND, useCache);
}

/**
* Loads a streamed sound asset asynchronously
*
* Audio streaming may not be supported for some targets or files. If audio streaming is
* not supported, a `SOUND` asset will be returned instead.
*
* @param id The ID or asset path for the asset
* @param useCache Whether to allow use of the asset cache (if one exists)
* @return Returns a `Future` which allows listeners to be added via methods like `onComplete`
*/
public inline function loadMusic(id:String, useCache = true):Future<Sound>
{
return cast loadAsset(id, MUSIC, useCache);
}

/**
* Loads a text asset asynchronously
Expand Down Expand Up @@ -672,6 +761,9 @@ enum abstract FlxAssetType(String)

/** Audio assets, such as *.ogg or *.wav files */
var SOUND = "sound";

/** Streamed audio assets, such as *.ogg or *.wav files */
var MUSIC = "music";

/** Text assets */
var TEXT = "text";
Expand All @@ -684,6 +776,7 @@ enum abstract FlxAssetType(String)
case FONT: AssetType.FONT;
case IMAGE: AssetType.IMAGE;
case SOUND: AssetType.SOUND;
case MUSIC: AssetType.MUSIC;
case TEXT: AssetType.TEXT;
}
}
Expand Down