crossbrowdy
Version:
A Multimedia JavaScript framework to create real cross-platform and hybrid game engines, games, emulators, multimedia libraries and apps.
713 lines (621 loc) • 114 kB
JavaScript
/**
* @file Audio sprites pool management. Contains the {@link CB_AudioFileSpritesPool} class.
* @author Joan Alba Maldonado <workindalian@gmail.com>
* @license Creative Commons Attribution 4.0 International. See more at {@link https://crossbrowdy.com/about#what_is_the_crossbrowdy_copyright_and_license}.
*/
/**
* Object whose property names the identifiers of each sprite (a case-sensitive string) and their value is a {@link CB_AudioFileSprites.DATA_OBJECT} object.
* @example
* {
* "sprites_group_id_1" : CB_AudioFileSprites.DATA_OBJECT,
* "sprites_group_id_2" : CB_AudioFileSprites.DATA_OBJECT,
* "sprites_group_id_3" : CB_AudioFileSprites.DATA_OBJECT,
* ...
* }
* @memberof CB_AudioFileSpritesPool
* @typedef {Object} CB_AudioFileSpritesPool.SPRITES_GROUPS_OBJECT
* @property {CB_AudioFileSprites.DATA_OBJECT} spritesGroupId - Being the name of each property the unique identifier of a sprites group which will use a future internally-created {@link CB_AudioFileSprites} object, the value will always be the {@link CB_AudioFileSprites.DATA_OBJECT} that the {@link CB_AudioFileSprites} object will use to be created (received by its constructor). Some of the missing properties ("preferredAPIs", "preferredFormats", "minimumAudioFiles", "maximumAudioFiles", "minimumAudioFilesFree", "newAudioFilesWhenNeeded", "retries", "checkManually", "checkManuallyOnNeededCreated", "checkManuallyOnPlayingFailed", "checkManuallyOnCheckingFailed" and "disableAutoLoad") will use the value set on the properties of the main {@link CB_AudioFileSpritesPool.DATA_OBJECT} object (if any) used by the {@link CB_AudioFileSpritesPool} object. If a function in the "onError" parameter is given, it will always be wrapped so the main error function set on the {@link CB_AudioFileSpritesPool#onError} parameter will always be called (if any) through the {@link CB_AudioFileSpritesPool#errorFunction} method.
*/
/**
* Object with the desired data and options for the audio sprites. It is almost identical to the {@link CB_AudioFileSprites.DATA_OBJECT} but adding a "spritesGroups" property.
* @memberof CB_AudioFileSpritesPool
* @typedef {Object} CB_AudioFileSpritesPool.DATA_OBJECT
* @property {CB_AudioFileSpritesPool.SPRITES_GROUPS_OBJECT} [spritesGroups] - Object with the desired sprites groups, containing the {@link CB_AudioFileSprites.DATA_OBJECT} objects which will be used to create the {@link CB_AudioFileSprites} objects internally. Each group will have a {@link CB_AudioFileSprites} object. It will be used as the first parameter to call the {@link CB_AudioFileSpritesPool#insertSpritesGroups} method internally. Some of the missing properties ("preferredAPIs", "preferredFormats", "minimumAudioFiles", "maximumAudioFiles", "minimumAudioFilesFree", "newAudioFilesWhenNeeded", "retries", "checkManually", "checkManuallyOnNeededCreated", "checkManuallyOnPlayingFailed", "checkManuallyOnCheckingFailed" and "disableAutoLoad") of the {@link CB_AudioFileSprites.DATA_OBJECT} objects given will use the value set on the other properties of this object (if any).
* @property {string} [id=""] - Desired identifier for the object. If a valid value is given, this will be added to the {@link CB_AudioFileSpritesPool#id} property.
* @property {array} [preferredAPIs={@link CB_Configuration.CrossBase.CB_AudioFileCache_PREFERRED_AUDIO_APIS}] - Array of strings with the preferred audio API or audio APIs, in order of preference. Possible audio APIs are "WAAPI" ([HTML5 Web Audio API]{@link https://developer.mozilla.org/en-US/docs/Web/API/Web_Audio_API}), "SM2" ([SoundManager 2]{@link http://schillmania.com/projects/soundmanager2/}), "ACMP" ([Apache Cordova Media Plugin]{@link https://github.com/apache/cordova-plugin-media}) or "AAPI" ([HTML5 Audio API]{@link https://developer.mozilla.org/en-US/docs/Web/HTML/Element/audio}). It will try to calculate and use the best one for the current client. If a valid value is given, this will be added to the {@link CB_AudioFileSpritesPool#preferredAPIs} property. If the {@link CB_AudioFileSprites.DATA_OBJECT} object (defined in the {@link CB_AudioFileSpritesPool.SPRITES_GROUPS_OBJECT} object set in the "spritesGroups") of a certain sprites group does not contain the "preferredAPIs" property, it will use the value of this property instead when creating its {@link CB_AudioFileSprites} object internally.
* @property {array} [preferredFormats={@link CB_Configuration.CrossBase.CB_AudioFileCache_PREFERRED_AUDIO_FORMATS}] - Array of strings with the preferred audio format or audio formats (they can include just the format as 'audio/ogg' or also the codec as for example 'audio/ogg; codecs="vorbis"'), in order of preference. It will try to calculate and use the best one for the current client. If a valid value is given, this will be added to the {@link CB_AudioFileSpritesPool#preferredFormats} property. If the {@link CB_AudioFileSprites.DATA_OBJECT} object (defined in the {@link CB_AudioFileSpritesPool.SPRITES_GROUPS_OBJECT} object set in the "spritesGroups") of a certain sprites group does not contain the "preferredFormats" property, it will use the value of this property instead when creating its {@link CB_AudioFileSprites} object internally.
* @property {integer} [minimumAudioFiles={@link CB_AudioFileCache.minimumAudioFiles_DEFAULT}] - Minimum {@link CB_AudioFile} objects to create internally. It must be an integer being 1 the minimum. If a valid value is given, this will be added to the {@link CB_AudioFileSpritesPool#minimumAudioFiles} property. If the {@link CB_AudioFileSprites.DATA_OBJECT} object (defined in the {@link CB_AudioFileSpritesPool.SPRITES_GROUPS_OBJECT} object set in the "spritesGroups") of a certain sprites group does not contain the "minimumAudioFiles" property, it will use the value of this property instead when creating its {@link CB_AudioFileSprites} object internally.
* @property {integer} [maximumAudioFiles={@link CB_AudioFileCache.maximumAudioFiles_DEFAULT}] - Maximum {@link CB_AudioFile} objects that are to be created internally. If it is set to null, there will not be a maximum (it will be unlimited). If an integer is provided, it must be the same number or greater than the value set in the {@link CB_AudioFileCache#minimumAudioFiles} property (also provided by the "minimumAudioFiles" of this object), allowing 1 minimum. If a valid value is given, this will be added to the {@link CB_AudioFileSpritesPool#maximumAudioFiles} property. If the {@link CB_AudioFileSprites.DATA_OBJECT} object (defined in the {@link CB_AudioFileSpritesPool.SPRITES_GROUPS_OBJECT} object set in the "spritesGroups") of a certain sprites group does not contain the "maximumAudioFiles" property, it will use the value of this property instead when creating its {@link CB_AudioFileSprites} object internally.
* @property {integer} [minimumAudioFilesFree=parseInt({@link CB_AudioFileCache#minimumAudioFiles} * 0.25 + 0.5)] - New {@link CB_AudioFile} objects will be created internally when the number of free {@link CB_AudioFile} objects reaches this limit. If provided, it must be an integer being 0 (zero) the minimum. It will end using a 25% of the {@link CB_AudioFileSpritesPool#minimumAudioFiles} by default, rounded to ceil, allowing 0 (zero) minimum. If a valid value is given, this will be added to the {@link CB_AudioFileSpritesPool#minimumAudioFilesFree} property. If the {@link CB_AudioFileSprites.DATA_OBJECT} object (defined in the {@link CB_AudioFileSpritesPool.SPRITES_GROUPS_OBJECT} object set in the "spritesGroups") of a certain sprites group does not contain the "minimumAudioFilesFree" property, it will use the value of this property instead when creating its {@link CB_AudioFileSprites} object internally.
* @property {integer} [newAudioFilesWhenNeeded=Math.min(parseInt({@link CB_AudioFileCache#minimumAudioFiles} * 0.1 + 0.5), 1)] - Number of new {@link CB_AudioFile} objects to create internally when the minimum limit of free {@link CB_AudioFile} objects ({@link CB_AudioFileSpritesPool#minimumAudioFilesFree}) is reached. If provided, it must be an integer being 0 (zero) the minimum. It will end using a 10% of the {@link CB_AudioFileSpritesPool#minimumAudioFiles} by default, rounded to ceil, allowing 1 minimum. If a valid value is given, this will be added to the {@link CB_AudioFileSpritesPool#newAudioFilesWhenNeeded} property. If the {@link CB_AudioFileSprites.DATA_OBJECT} object (defined in the {@link CB_AudioFileSpritesPool.SPRITES_GROUPS_OBJECT} object set in the "spritesGroups") of a certain sprites group does not contain the "newAudioFilesWhenNeeded" property, it will use the value of this property instead when creating its {@link CB_AudioFileSprites} object internally.
* @property {integer} [retries={@link CB_AudioFileCache.retries_DEFAULT}] - Number of retries to try to load a {@link CB_AudioFile} object internally before trying to load the next possible one internally (if any). It must be an integer being 0 the minimum. If a valid value is given, this will be added to the {@link CB_AudioFileSpritesPool#retries} property. If the {@link CB_AudioFileSprites.DATA_OBJECT} object (defined in the {@link CB_AudioFileSpritesPool.SPRITES_GROUPS_OBJECT} object set in the "spritesGroups") of a certain sprites group does not contain the "retries" property, it will use the value of this property instead when creating its {@link CB_AudioFileSprites} object internally.
* @property {boolean} [checkManually={@link CB_AudioFileCache.checkManually_DEFAULT}] - Tells whether the {@link CB_AudioFile} objects must be checked automatically or not (manually) by default. If a valid value is given, this will be added to the {@link CB_AudioFileSpritesPool#checkManually} property. If the {@link CB_AudioFileSprites.DATA_OBJECT} object (defined in the {@link CB_AudioFileSpritesPool.SPRITES_GROUPS_OBJECT} object set in the "spritesGroups") of a certain sprites group does not contain the "checkManually" property, it will use the value of this property instead when creating its {@link CB_AudioFileSprites} object internally.
* @property {boolean} [checkManuallyOnNeededCreated={@link CB_AudioFileCache.checkManuallyOnNeededCreated_DEFAULT}] - Tells whether the {@link CB_AudioFile} objects must be checked automatically or not (manually) when creates a new {@link CB_AudioFile} object needed. If a valid value is given, this will be added to the {@link CB_AudioFileSpritesPool#checkManuallyOnNeededCreated} property. If the {@link CB_AudioFileSprites.DATA_OBJECT} object (defined in the {@link CB_AudioFileSpritesPool.SPRITES_GROUPS_OBJECT} object set in the "spritesGroups") of a certain sprites group does not contain the "checkManuallyOnNeededCreated" property, it will use the value of this property instead when creating its {@link CB_AudioFileSprites} object internally.
* @property {boolean} [checkManuallyOnPlayingFailed={@link CB_AudioFileCache.checkManuallyOnPlayingFailed_DEFAULT}] - Tells whether the {@link CB_AudioFile} objects must be checked automatically or not (manually) when playing one has failed and tries to reload it. If a valid value is given, this will be added to the {@link CB_AudioFileSpritesPool#checkManuallyOnPlayingFailed} property. If the {@link CB_AudioFileSprites.DATA_OBJECT} object (defined in the {@link CB_AudioFileSpritesPool.SPRITES_GROUPS_OBJECT} object set in the "spritesGroups") of a certain sprites group does not contain the "checkManuallyOnPlayingFailed" property, it will use the value of this property instead when creating its {@link CB_AudioFileSprites} object internally.
* @property {boolean} [checkManuallyOnCheckingFailed={@link CB_AudioFileCache.checkManuallyOnCheckingFailed_DEFAULT}] - Tells whether the {@link CB_AudioFile} objects must be checked automatically or not (manually) when checking one has failed and tries to reload it. If a valid value is given, this will be added to the {@link CB_AudioFileSpritesPool#checkManuallyOnCheckingFailed} property. If the {@link CB_AudioFileSprites.DATA_OBJECT} object (defined in the {@link CB_AudioFileSpritesPool.SPRITES_GROUPS_OBJECT} object set in the "spritesGroups") of a certain sprites group does not contain the "checkManuallyOnCheckingFailed" property, it will use the value of this property instead when creating its {@link CB_AudioFileSprites} object internally.
* @property {function} [onLoad] - Desired function to be called once the pool has been loaded. The first and unique parameter will be an integer with the {@link CB_AudioFile} objects that still need to be checked, if any, being "this" the current {@link CB_AudioFileSpritesPool} object. If a valid value is given, this will be added to the {@link CB_AudioFileSpritesPool#onLoad} property.
* @property {function} [onError] - Desired function to be called when any kind of error happens. The first and unique parameter will be a string with the error description (if it could be determined), being "this" the current {@link CB_AudioFileSpritesPool} object. If a valid value is given, this will be added to the {@link CB_AudioFileSpritesPool#onError} property. If a function is set, it will always be called through the {@link CB_AudioFileSpritesPool#errorFunction} method whenever the "onError" event of an internally-created {@link CB_AudioFileSprites} object is fired.
* @property {boolean} [disableAutoLoad=false] - If set to true, it will not create automatically the {@link CB_AudioFile} objects by calling the {@link CB_AudioFileCache#createAudioFiles} method internally. Internal usage only recommended. If the {@link CB_AudioFileSprites.DATA_OBJECT} object (defined in the {@link CB_AudioFileSpritesPool.SPRITES_GROUPS_OBJECT} object set in the "spritesGroups") of a certain sprites group does not contain the "disableAutoLoad" property, it will use the value of this property instead when creating its {@link CB_AudioFileSprites} object internally.
*/
/**
* The constructor is recommended to be called through a user-driven event (as onClick, onTouch, etc.), as some clients may need this at least the first time in order to be able to play the audio.
* @class
* @classdesc Class to manage many audio sprites stored in different groups, each with one {@link CB_AudioFileSprites} object (used internally).
* @param {CB_AudioFileSpritesPool.DATA_OBJECT} [dataObject] - Object with the desired data and options for the groups of audio sprites. Each group will have a {@link CB_AudioFileSprites} object. Some of its properties ("preferredAPIs", "preferredFormats", "minimumAudioFiles", "maximumAudioFiles", "minimumAudioFilesFree", "newAudioFilesWhenNeeded", "retries", "checkManually", "checkManuallyOnNeededCreated", "checkManuallyOnPlayingFailed", "checkManuallyOnCheckingFailed" and "disableAutoLoad") will be used as the default value to create internally the {@link CB_AudioFileSprites} objects when the value is not given in the {@link CB_AudioFileSpritesPool.SPRITES_GROUPS_OBJECT} object (set as the value of the {@link CB_AudioFileSpritesPool.DATA_OBJECT#spritesGroups} property).
* @returns {CB_AudioFileSpritesPool} Returns a new {@link CB_AudioFileSpritesPool} object.
* @todo Do not allow to create one object with an "id" which has already been used (unless the value is undefined, null...).
* @todo Method getCopy and static method filterProperties (similar to the ones from {@link CB_GraphicSprites} and {@link CB_GraphicSpritesScene}).
*/
var CB_AudioFileSpritesPool = function(dataObject)
{
//Creates an instance of this object and returns it in the case that it is being called from an unexpected context:
if (this === window || !(this instanceof CB_AudioFileSpritesPool)) { return new CB_AudioFileSpritesPool(dataObject); }
//Properties and variables:
/**
* Stores the identifier for the audio file sprites pool object.
* @var
* @readonly
* @type {string}
* @default
*/
this.id = "";
/**
* Stores an array of strings with the preferred audio API or audio APIs, in order of preference. Possible audio APIs are "WAAPI" ([HTML5 Web Audio API]{@link https://developer.mozilla.org/en-US/docs/Web/API/Web_Audio_API}), "SM2" ([SoundManager 2]{@link http://schillmania.com/projects/soundmanager2/}), "ACMP" ([Apache Cordova Media Plugin]{@link https://github.com/apache/cordova-plugin-media}) or "AAPI" ([HTML5 Audio API]{@link https://developer.mozilla.org/en-US/docs/Web/HTML/Element/audio}). Internal usage only recommended.
* @var
* @readonly
* @type {array}
* @default CB_Configuration.CrossBase.CB_AudioFileCache_PREFERRED_AUDIO_APIS
*/
this.preferredAPIs = undefined;
/**
* Stores an array of strings with the preferred audio format or audio formats (they can include just the format as 'audio/ogg' or also the codec as for example 'audio/ogg; codecs="vorbis"'), in order of preference. Internal usage only recommended.
* @var
* @readonly
* @type {array}
* @default CB_Configuration.CrossBase.CB_AudioFileCache_PREFERRED_AUDIO_FORMATS
*/
this.preferredFormats = undefined;
/**
* Minimum {@link CB_AudioFile} objects to create internally for each {@link CB_AudioFileSprites} object. It must be an integer being 1 the minimum. Internal usage only recommended.
* @var
* @readonly
* @type {integer}
* @default CB_AudioFileCache.minimumAudioFiles_DEFAULT
*/
this.minimumAudioFiles = undefined;
/**
* Maximum {@link CB_AudioFile} objects that are to be created internally for each {@link CB_AudioFileSprites} object. If it is set to null, there will not be a maximum (it will be unlimited). If an integer is provided, it must be the same number or greater than the value set in the {@link CB_AudioFileCache#minimumAudioFiles} property, allowing 1 minimum. Internal usage only recommended.
* @var
* @readonly
* @type {integer|null}
* @default CB_AudioFileCache.maximumAudioFiles_DEFAULT
*/
this.maximumAudioFiles = undefined;
/**
* New {@link CB_AudioFile} objects will be created internally for each {@link CB_AudioFileSprites} object when the number of free {@link CB_AudioFile} objects reaches this limit. It must be an integer being 0 (zero) the minimum. Internal usage only recommended.
* @var
* @readonly
* @type {integer}
* @default parseInt({@link CB_AudioFileCache#minimumAudioFiles} * 0.25 + 0.5)
*/
this.minimumAudioFilesFree = undefined;
/**
* Number of new {@link CB_AudioFile} objects to create internally for each {@link CB_AudioFileSprites} object when the minimum limit of free {@link CB_AudioFile} objects ({@link CB_AudioFileCache#minimumAudioFilesFree}) is reached. It must be an integer being 0 (zero) the minimum. Internal usage only recommended.
* @var
* @readonly
* @type {integer}
* @default Math.min(parseInt({@link CB_AudioFileCache#minimumAudioFiles} * 0.1 + 0.5), 1)
*/
this.newAudioFilesWhenNeeded = undefined;
/**
* Number of retries to try to load a {@link CB_AudioFile} object internally before trying to load the next possible one internally (if any). It must be an integer being 0 the minimum. Internal usage only recommended.
* @var
* @readonly
* @type {integer}
* @default CB_AudioFileCache.retries_DEFAULT
*/
this.retries = undefined;
/**
* Tells whether the {@link CB_AudioFile} objects must be checked automatically or not (manually). Internal usage only recommended.
* @var
* @readonly
* @type {boolean}
* @default CB_AudioFileCache.checkManually_DEFAULT
*/
this.checkManually = undefined;
/**
* Tells whether the {@link CB_AudioFile} objects must be checked automatically or not (manually) when creates a new {@link CB_AudioFile} object needed. Internal usage only recommended.
* @var
* @readonly
* @type {boolean}
* @default CB_AudioFileCache.checkManuallyOnNeededCreated_DEFAULT
*/
this.checkManuallyOnNeededCreated = undefined;
/**
* Tells whether the {@link CB_AudioFile} objects must be checked automatically or not (manually) when playing one has failed and tries to reload it. Internal usage only recommended.
* @var
* @readonly
* @type {boolean}
* @default CB_AudioFileCache.checkManuallyOnPlayingFailed_DEFAULT
*/
this.checkManuallyOnPlayingFailed = undefined;
/**
* Tells whether the {@link CB_AudioFile} objects must be checked automatically or not (manually) when checking one has failed and tries to reload it. Internal usage only recommended.
* @var
* @readonly
* @type {boolean}
* @default CB_AudioFileCache.checkManuallyOnCheckingFailed_DEFAULT
*/
this.checkManuallyOnCheckingFailed = undefined;
/**
* If set to true, it will not create automatically the {@link CB_AudioFile} objects by calling the {@link CB_AudioFileCache#createAudioFiles} method internally. Internal usage only recommended.
* @var
* @readonly
* @type {boolean}
* @default false
*/
this.disableAutoLoad = undefined;
/**
* Desired function to be called once the pool has been loaded. The first and unique parameter will be an integer with the {@link CB_AudioFile} objects that still need to be checked, if any, being "this" the current {@link CB_AudioFileSpritesPool} object.
* @var
* @readonly
* @type {function}
* @default
*/
this.onLoad = undefined;
/**
* Desired function to be called when any kind of error happens. The first and unique parameter will be a string with the error description (if it could be determined), being "this" the current {@link CB_AudioFileSpritesPool} object. If a function is set, it will always be called through the {@link CB_AudioFileSpritesPool#errorFunction} method whenever the "onError" event of an internally-created {@link CB_AudioFileSprites} object is fired.
* @var
* @readonly
* @type {function}
* @default
*/
this.onError = undefined; //Function to call if not all AudioFiles can be loaded.
/**
* Stores the internally-created {@link CB_AudioFileSprites} objects, using the name of each property as their group ID and the value being the {@link CB_AudioFileSprites} object itself. Internal usage only recommended.
* @var
* @readonly
* @type {Object}
* @default
*/
this.audioFileSprites = {}; //Object with the CB_AudioFileSprites objects.
//Internal properties:
this._aborted = false;
this._checkSpritesGroupsLoadedTimeout = null;
this._checkPlayingAllInterval;
this._checkPlayingAllPerforming = false;
this._setAudioAPIAllInterval;
this._setAudioAPIAllPerforming = false;
this._errorFunctionExecuted = false;
//Calls the constructor of the object when creates an instance:
return this._init(dataObject);
}
//Static properties and constants:
/**
* Status value for audio file sprites pool which is unloaded. Can be used to compare the value returned by the {@link CB_AudioFileSpritesPool#getStatus} method. Recommended for internal usage only.
* @constant
* @type {integer}
* @default 0
*/
CB_AudioFileSpritesPool.UNLOADED = 0; //Status value for unloaded cache.
/**
* Status value for an audio file sprites pool which is loading. Can be used to compare the value returned by the {@link CB_AudioFileSpritesPool#getStatus} method. Recommended for internal usage only.
* @constant
* @type {integer}
* @default
*/
CB_AudioFileSpritesPool.LOADING = 1; //Status value for loading cache.
/**
* Status value for an audio file sprites pool which has not been checked yet. Can be used to compare the value returned by the {@link CB_AudioFileSpritesPool#getStatus} method. Recommended for internal usage only.
* @constant
* @type {integer}
* @default
*/
CB_AudioFileSpritesPool.UNCHECKED = 2; //STatus value for an unchecked cache.
/**
* Status value for an audio file sprites pool which is being checked currently. Can be used to compare the value returned by the {@link CB_AudioFileSpritesPool#getStatus} method. Recommended for internal usage only.
* @constant
* @type {integer}
* @default
*/
CB_AudioFileSpritesPool.CHECKING = 3; //Status value for checking a cache.
/**
* Status value for an audio file sprites pool which has been loaded. Can be used to compare the value returned by the {@link CB_AudioFileSpritesPool#getStatus} method. Recommended for internal usage only.
* @constant
* @type {integer}
* @default
*/
CB_AudioFileSpritesPool.LOADED = 4; //Status value for loaded cache.
/**
* Status value for an audio file sprites pool which failed to be loaded or failed for any other reason. Can be used to compare the value returned by the {@link CB_AudioFileSpritesPool#getStatus} method. Recommended for internal usage only.
* @constant
* @type {integer}
* @default
*/
CB_AudioFileSpritesPool.FAILED = 5; //Status value for failed to load cache.
/**
* Status value for an audio file sprites pool which has been aborted. This will happen when the audio file sprites pool has been destroyed with the {@link CB_AudioFileSpritesPool#destructor} method. Can be used to compare the value returned by the {@link CB_AudioFileSpritesPool#getStatus} method. Recommended for internal usage only.
* @constant
* @type {integer}
* @default
*/
CB_AudioFileSpritesPool.ABORTED = 6; //Status value for aborted cache.
//Constructor:
CB_AudioFileSpritesPool.prototype._init = function(dataObject)
{
/*
FORMAT:
dataObject =
{
[id : String,]
[onLoad : Function,]
[onError : Function,]
[preferredAPIs : Array<String>,]
[preferredFormats : Array<String>,]
[minimumAudioFiles : Integer,]
[maximumAudioFiles : Integer,]
[minimumAudioFilesFree : Integer,]
[newAudioFilesWhenNeeded : Integer,]
[retries : Integer,]
[checkManually : Boolean,]
[checkManuallyOnNeededCreated : Boolean,]
[checkManuallyOnPlayingFailed : Boolean,]
[checkManuallyOnCheckingFailed : Boolean,]
[disableAutoLoad : Boolean,]
spritesGroups :
{
"sprites_group_id" : CB_AudioFileSprites.DATA_OBJECT
[, ...]
}
};
*/
//Tries to load the data (if any):
this.load(dataObject);
//Returns the object:
return this;
}
/**
* Destroys the audio file sprites pool object (removing all sprites, etc.), including the internal audio file sprites objects, and frees memory. By default, unless the "preventAbortedStatus" is set to true, sets the current status of all the {@link CB_AudioFileCache} objects as ABORTED ({@link CB_AudioFileCache.ABORTED} value). Internally, calls the {@link CB_AudioFileSprites#destructor} method of all the internally-created {@link CB_AudioFileSprites} objects.
* @function
* @param {boolean} [stopSounds=false] - Used as the "stopSounds" parameter when calling internally the {@link CB_AudioFileSprites#destructor} method of all the internally-created {@link CB_AudioFileSprites} objects.
* @param {boolean} [preventAbortedStatus=false] - If set to true (not recommended), it will not assign the status of "ABORTED" (it will not set the {@link CB_AudioFileSpritesPool#_aborted} property to true}. Used as the "preventAbortedStatus" parameter when calling internally the {@link CB_AudioFileSprites#destructor} method of all the internally-created {@link CB_AudioFileSprites} objects.
*/
CB_AudioFileSpritesPool.prototype.destructor = function(stopSounds, preventAbortedStatus)
{
clearInterval(this._checkPlayingAllInterval);
clearInterval(this._setAudioAPIAllInterval);
clearTimeout(this._checkSpritesGroupsLoadedTimeout);
//Destroys the CB_AudioFileSprites objects:
for (var audioFileSpritesObject in this.audioFileSprites)
{
this.audioFileSprites[audioFileSpritesObject].destructor(stopSounds, preventAbortedStatus);
}
//Resets properties to their default value:
this.preferredAPIs = undefined;
this.preferredFormats = undefined;
this.minimumAudioFiles = undefined;
this.maximumAudioFiles = undefined;
this.minimumAudioFilesFree = undefined;
this.newAudioFilesWhenNeeded = undefined;
this.retries = undefined;
this.checkManually = undefined;
this.checkManuallyOnNeededCreated = undefined;
this.checkManuallyOnPlayingFailed = undefined;
this.checkManuallyOnCheckingFailed = undefined;
this.disableAutoLoad = undefined;
this.onLoad = undefined;
this.onError = undefined;
this.audioFileSprites = {};
if (!preventAbortedStatus) { this._aborted = true; }
}
/**
* Loads the audio file sprites pool with the desired data given. This method is called by the constructor automatically. Recommended to be called through a user-driven event (as onClick, onTouch, etc.), as some clients may need this at least the first time in order to be able to play the audio.
* @function
* @param {CB_AudioFileSpritesPool.DATA_OBJECT} dataObject - Object with the desired data and options for the audio file sprites.
* @returns {CB_AudioFileSpritesPool|null} If a "dataObject" is given, it returns the current {@link CB_AudioFileSpritesPool} object. Otherwise, it returns null.
*/
CB_AudioFileSpritesPool.prototype.load = function(dataObject)
{
if (typeof(dataObject) === "undefined" || dataObject === null) { return null; }
//Destroys all previous data (if any):
this.destructor(true, true); //Also stops all sounds.
this._aborted = false;
//Sanitizes the given data:
dataObject.id = CB_trim(dataObject.id);
//Sets the new data:
if (dataObject.id !== "") { this.id = dataObject.id; }
if (typeof(dataObject.preferredAPIs) !== "undefined") { this.preferredAPIs = dataObject.preferredAPIs; }
if (typeof(dataObject.preferredFormats) !== "undefined") { this.preferredFormats = dataObject.preferredFormats; }
if (typeof(dataObject.minimumAudioFiles) !== "undefined") { this.minimumAudioFiles = dataObject.minimumAudioFiles; }
if (typeof(dataObject.maximumAudioFiles) !== "undefined") { this.maximumAudioFiles = dataObject.maximumAudioFiles; }
if (typeof(dataObject.minimumAudioFilesFree) !== "undefined") { this.minimumAudioFilesFree = dataObject.minimumAudioFilesFree; }
if (typeof(dataObject.newAudioFilesWhenNeeded) !== "undefined") { this.newAudioFilesWhenNeeded = dataObject.newAudioFilesWhenNeeded; }
if (typeof(dataObject.retries) !== "undefined") { this.retries = dataObject.retries; }
if (typeof(dataObject.checkManually) !== "undefined") { this.checkManually = dataObject.checkManually; }
if (typeof(dataObject.checkManuallyOnNeededCreated) !== "undefined") { this.checkManuallyOnNeededCreated = dataObject.checkManuallyOnNeededCreated; }
if (typeof(dataObject.checkManuallyOnPlayingFailed) !== "undefined") { this.checkManuallyOnPlayingFailed = dataObject.checkManuallyOnPlayingFailed; }
if (typeof(dataObject.checkManuallyOnCheckingFailed) !== "undefined") { this.checkManuallyOnCheckingFailed = dataObject.checkManuallyOnCheckingFailed; }
if (typeof(dataObject.disableAutoLoad) !== "undefined") { this.disableAutoLoad = dataObject.disableAutoLoad; }
if (typeof(dataObject.onLoad) !== "undefined") { this.onLoad = dataObject.onLoad; }
if (typeof(dataObject.onError) !== "undefined") { this.onError = dataObject.onError; }
//Inserts the CB_AudioFileSprites objects:
if (typeof(dataObject.spritesGroups) !== "undefined" && dataObject.spritesGroups !== null)
{
this.removeSpritesGroups();
this.insertSpritesGroups(dataObject.spritesGroups);
}
return this;
}
//Checks whether all CB_AudioFileSprites objects are loaded or not:
CB_AudioFileSpritesPool.prototype._checkSpritesGroupsLoaded = function()
{
clearTimeout(this._checkSpritesGroupsLoadedTimeout);
var allLoaded = true;
var x;
for (var audioFileSpritesObject in this.audioFileSprites)
{
x++;
if (!this.audioFileSprites[audioFileSpritesObject].audioFileCache.checkManually && this.audioFileSprites[audioFileSpritesObject].getStatus() !== CB_AudioFileCache.LOADED)
{
allLoaded = false;
break;
}
else if (this.audioFileSprites[audioFileSpritesObject].audioFileCache.checkManually && this.audioFileSprites[audioFileSpritesObject].getStatus() !== CB_AudioFileCache.UNCHECKED && this.audioFileSprites[audioFileSpritesObject].getStatus() !== CB_AudioFileCache.LOADED)
{
allLoaded = false;
break;
}
}
if (x === 0) { allLoaded = false; }
var that = this;
if (this.getStatus() === CB_AudioFileSpritesPool.LOADING || this.getStatus() === CB_AudioFileSpritesPool.UNCHECKED)
{
if (!allLoaded) { this._checkSpritesGroupsLoadedTimeout = setTimeout(function() { that._checkSpritesGroupsLoaded.call(that); }, 100); }
else
{
if (typeof(this.onLoad) === "function")
{
var objectsNeedChecking = 0;
var audioFiles;
var audioFilesLength;
var x;
for (var audioFileSpritesObject in this.audioFileSprites)
{
audioFiles = this.audioFileSprites[audioFileSpritesObject].getAudioFiles(false);
audioFilesLength = audioFiles.length;
for (x = 0; x < audioFilesLength; x++) { if (audioFiles[x].getStatus() === CB_AudioFile.UNCHECKED) { objectsNeedChecking++; } }
}
this.onLoad.call(this, objectsNeedChecking);
}
}
}
}
/**
* Removes all the sprites groups ({@link CB_AudioFileSprites} objects) by clearing the {@link CB_AudioFileSpritesPool#audioFileSprites} property.
* @function
*/
CB_AudioFileSpritesPool.prototype.removeSpritesGroups = function()
{
this.audioFileSprites = {};
}
/**
* Inserts the given sprites groups.
* @function
* @param {CB_AudioFileSpritesPool.SPRITES_GROUPS_OBJECT} sprites - Object with the desired sprites groups.
* @returns {integer} Returns the number of sprites groups inserted.
*/
CB_AudioFileSpritesPool.prototype.insertSpritesGroups = function(spritesGroups)
{
var inserted = 0;
var that = this;
if (typeof(spritesGroups) !== "undefined" && spritesGroups !== null)
{
clearTimeout(this._checkSpritesGroupsLoadedTimeout);
for (var spritesGroupId in spritesGroups)
{
//Inserts the sprite:
if (this.insertSpritesGroup(spritesGroupId, spritesGroups[spritesGroupId], true)) { inserted++; }
}
this._checkSpritesGroupsLoadedTimeout = setTimeout(function() { that._checkSpritesGroupsLoaded.call(that); }, 100);
}
return inserted;
}
/**
* Inserts the given sprites group to the audio file sprites pool object.
* @function
* @param {string} spritesGroupId - The identifier for the sprites group.
* @param {CB_AudioFileSprites.DATA_OBJECT} [dataObject] - Object with the data of the sprites group. Optional but recommended.
* @param {boolean} [avoidCheckingLoaded=false] - If set to true, it will not check whether all sprites groups has been loaded after inserting the desired one. This is done internally by the {@link CB_AudioFileSpritesPool#_checkSpritesGroupsLoaded} method which will fire the {@link CB_AudioFileSpritesPool#onLoad} function (if any).
* @returns {boolean} Returns true if the sprites group has been inserted or false otherwise.
*/
CB_AudioFileSpritesPool.prototype.insertSpritesGroup = function(spritesGroupId, dataObject, avoidCheckingLoaded)
{
if (typeof(spritesGroupId) === "undefined" || spritesGroupId === null) { return false; }
if (typeof(dataObject) === "undefined" || dataObject === null) { dataObject = {}; }
if (avoidCheckingLoaded)
{
clearTimeout(this._checkSpritesGroupsLoadedTimeout);
}
var dataObjectCopy = {};
dataObjectCopy.id = spritesGroupId;
dataObjectCopy.preferredAPIs = dataObject.preferredAPIs;
dataObjectCopy.preferredFormats = dataObject.preferredFormats;
dataObjectCopy.URIs = dataObject.URIs;
dataObjectCopy.minimumAudioFiles = dataObject.minimumAudioFiles;
dataObjectCopy.maximumAudioFiles = dataObject.maximumAudioFiles;
dataObjectCopy.minimumAudioFilesFree = dataObject.minimumAudioFilesFree;
dataObjectCopy.newAudioFilesWhenNeeded = dataObject.newAudioFilesWhenNeeded;
dataObjectCopy.retries = dataObject.retries;
dataObjectCopy.checkManually = dataObject.checkManually;
dataObjectCopy.checkManuallyOnNeededCreated = dataObject.checkManuallyOnNeededCreated;
dataObjectCopy.checkManuallyOnPlayingFailed = dataObject.checkManuallyOnPlayingFailed;
dataObjectCopy.checkManuallyOnCheckingFailed = dataObject.checkManuallyOnCheckingFailed;
dataObjectCopy.disableAutoLoad = dataObject.disableAutoLoad;
dataObjectCopy.onLoad = dataObject.onLoad;
dataObjectCopy.onError = dataObject.onError;
dataObjectCopy.sprites = dataObject.sprites;
if (typeof(dataObjectCopy.preferredAPIs) === "undefined" && typeof(this.preferredAPIs) !== "undefined") { dataObjectCopy.preferredAPIs = this.preferredAPIs; }
if (typeof(dataObjectCopy.preferredFormats) === "undefined" && typeof(this.preferredFormats) !== "undefined") { dataObjectCopy.preferredFormats = this.preferredFormats; }
if (typeof(dataObjectCopy.minimumAudioFiles) === "undefined" && typeof(this.minimumAudioFiles) !== "undefined") { dataObjectCopy.minimumAudioFiles = this.minimumAudioFiles; }
if (typeof(dataObjectCopy.maximumAudioFiles) === "undefined" && typeof(this.maximumAudioFiles) !== "undefined") { dataObjectCopy.maximumAudioFiles = this.maximumAudioFiles; }
if (typeof(dataObjectCopy.minimumAudioFilesFree) === "undefined" && typeof(this.minimumAudioFilesFree) !== "undefined") { dataObjectCopy.minimumAudioFilesFree = this.minimumAudioFilesFree; }
if (typeof(dataObjectCopy.newAudioFilesWhenNeeded) === "undefined" && typeof(this.newAudioFilesWhenNeeded) !== "undefined") { dataObjectCopy.newAudioFilesWhenNeeded = this.newAudioFilesWhenNeeded; }
if (typeof(dataObjectCopy.retries) === "undefined" && typeof(this.retries) !== "undefined") { dataObjectCopy.retries = this.retries; }
if (typeof(dataObjectCopy.checkManually) === "undefined" && typeof(this.checkManually) !== "undefined") { dataObjectCopy.checkManually = this.checkManually; }
if (typeof(dataObjectCopy.checkManuallyOnNeededCreated) === "undefined" && typeof(this.checkManuallyOnNeededCreated) !== "undefined") { dataObjectCopy.checkManuallyOnNeededCreated = this.checkManuallyOnNeededCreated; }
if (typeof(dataObjectCopy.checkManuallyOnPlayingFailed) === "undefined" && typeof(this.checkManuallyOnPlayingFailed) !== "undefined") { dataObjectCopy.checkManuallyOnPlayingFailed = this.checkManuallyOnPlayingFailed; }
if (typeof(dataObjectCopy.checkManuallyOnCheckingFailed) === "undefined" && typeof(this.checkManuallyOnCheckingFailed) !== "undefined") { dataObjectCopy.checkManuallyOnCheckingFailed = this.checkManuallyOnCheckingFailed; }
if (typeof(dataObjectCopy.disableAutoLoad) === "undefined" && typeof(this.disableAutoLoad) !== "undefined") { dataObjectCopy.disableAutoLoad = this.disableAutoLoad; }
//Wraps the error function:
var that = this;
var onErrorOld = dataObjectCopy.onError;
dataObjectCopy.onError =
function(error)
{
if (typeof(onErrorOld) === "function") { onErrorOld.call(this, error); }
setTimeout(function() { that.errorFunction.call(that, error); }, 100);
};
this._errorFunctionExecuted = false; //Allows the execution of the error function again.
this.audioFileSprites[spritesGroupId] = new CB_AudioFileSprites(dataObjectCopy);
if (!avoidCheckingLoaded)
{
this._checkSpritesGroupsLoadedTimeout = setTimeout(function() { that._checkSpritesGroupsLoaded.call(that); }, 100);
}
return true;
}
/**
* Removes a sprites group by its ID.
* @function
* @param {string} spritesGroupId - The identifier for the sprites group.
* @param {boolean} [destroy=false] - If set to true, it will call the {@link CB_AudioFileSprites#destructor} method of the {@link CB_AudioFileSprites} object which belongs to the desired sprites group.
* @param {boolean} [stopSounds=false] - If the "destroy" parameter is set to false, this parameter will be ignored. Used as the "stopSound" parameter when calling internally the {@link CB_AudioFileSprites#destructor} method of the {@link CB_AudioFileSprites} object which belongs to the desired sprites group.
* @param {boolean} [preventAbortedStatus=false] - If the "destroy" parameter is set to false, this parameter will be ignored. Used as the "preventAbortedStatus" parameter when calling internally the {@link CB_AudioFileSprites#destructor} method of the {@link CB_AudioFileSprites} object which belongs to the desired sprites group.
* @returns {boolean} Returns true if the sprites group has been deleted or false otherwise.
*/
CB_AudioFileSpritesPool.prototype.removeSpritesGroup = function(spritesGroupId, destroy, stopSounds, preventAbortedStatus)
{
if (typeof(this.audioFileSprites[spritesGroupId]) !== "undefined" && this.audioFileSprites[spritesGroupId] !== null)
{
if (destroy)
{
this.audioFileSprites[spritesGroupId].destructor(stopSounds, preventAbortedStatus);
}
this.audioFileSprites[spritesGroupId] = null;
var audioFileSprites = {};
for (spritesGroupId in this.audioFileSprites)
{
if (typeof(this.audioFileSprites[spritesGroupId]) !== "undefined" && this.audioFileSprites[spritesGroupId] !== null)
{
audioFileSprites[spritesGroupId] = this.audioFileSprites[spritesGroupId];
}
}
this.audioFileSprites = audioFileSprites;
return true;
}
return false;
}
/**
* Returns a sprites group (the {@link CB_AudioFileSprites} object) by its ID.
* @function
* @param {string} spritesGroupId - The identifier for the sprites group.
* @param {boolean} [withoutChecking=false] - If set to true and the sprites group cannot be found, the method will return undefined (or whatever is stored by the given ID) instead of null.
* @returns {CB_AudioFileSprites|undefined|*|null} Returns null if the "withoutChecking" parameter is set to true and the sprites group cannot be found. Otherwise, it will return what is stored internally by the given ID which can be a {@link CB_AudioFileSprites} object if found or undefined (or whatever is stored by the given ID) if not found.
*/
CB_AudioFileSpritesPool.prototype.getSpritesGroup = function(spritesGroupId, withoutChecking)
{
//return this.audioFileSprites[spritesGroupId];
if (typeof(this.audioFileSprites[spritesGroupId]) !== "undefined" || withoutChecking)
{
return this.audioFileSprites[spritesGroupId];
}
return null;
}
/**
* Returns an object with the sprites groups (all the internally-created {@link CB_AudioFileSprites} objects), being the name of each property their group ID and the value being the {@link CB_AudioFileSprites} object itself. Internally, it just returns the {@link CB_AudioFileSpritesPool#audioFileSprites} property.
* @function
* @returns {Object} Returns an object with the sprites groups (all the internally-created {@link CB_AudioFileSprites} objects), being the name of each property their group ID and the value being the {@link CB_AudioFileSprites} object itself. Internally, it just returns the {@link CB_AudioFileSpritesPool#audioFileSprites} property.
*/
CB_AudioFileSpritesPool.prototype.getSpritesGroups = function()
{
return this.audioFileSprites;
}
/**
* Returns an object with the sprites (and includes "_WITHOUT_SPRITE_ASSOCIATED" if we want to). Internally, uses the {@link CB_AudioFileSprites#getSprites} method.
* @function
* @param {boolean} [includeWithoutSpriteAssociated=false] - If set to true, the returning object will also contain a property called "_WITHOUT_SPRITE_ASSOCIATED" whose value will be an empty object (unless the "orderBySpritesGroup" parameter is set to true and the property existed before in the object stored in the {@link CB_AudioFileSprites#sprites} property and had a value which is not an empty object). If set to false and the "orderBySpritesGroup" parameter is also set to false, the returning object will not contain the "_WITHOUT_SPRITE_ASSOCIATED" property. If set to false and the "orderBySpritesGroup" parameter is set to true, the returning object will not contain the "_WITHOUT_SPRITE_ASSOCIATED" property unless the property existed before in the object stored in the {@link CB_AudioFileSprites#sprites} property.
* @param {boolean} [orderBySpritesGroup=false] - If set to false, it will return a {@link CB_AudioFileSprites.SPRITES_OBJECT} object whose properties will be the ID of each sprite (each sprite ID should be unique) and their value will be a {@link CB_AudioFileSprites.SPRITE_OBJECT} object. If set to true, it will return an object whose properties will be the ID of each sprites group and the value will be a {@link CB_AudioFileSprites.SPRITES_OBJECT} object which will include its sprites.
* @returns {CB_AudioFileSprites.SPRITES_OBJECT|Object} If the "orderBySpritesGroup" is set to false, it will return a {@link CB_AudioFileSprites.SPRITES_OBJECT} object whose properties will be the ID of each sprite (each sprite ID should be unique) and their value will be a {@link CB_AudioFileSprites.SPRITE_OBJECT} object. If the "orderBySpritesGroup" is set to true, it will return an object whose properties will be the ID of each sprites group and the value will be a {@link CB_AudioFileSprites.SPRITES_OBJECT} object which will include its sprites.
*/
CB_AudioFileSpritesPool.prototype.getSprites = function(includeWithoutSpriteAssociated, orderBySpritesGroup)
{
var sprites = {};
if (!orderBySpritesGroup)
{
if (includeWithoutSpriteAssociated) { sprites["_WITHOUT_SPRITE_ASSOCIATED"] = {}; }
var spritesLoop;
var spriteId;
for (var spritesGroupId in this.audioFileSprites)
{
spritesLoop = this.audioFileSprites[spritesGroupId].getSprites(false);
for (spriteId in spritesLoop)
{
sprites[spriteId] = spritesLoop[spriteId];
}
}
}
else
{
for (var spritesGroupId in this.audioFileSprites)
{
sprites[spritesGroupId] = this.audioFileSprites[spritesGroupId].getSprites(includeWithoutSpriteAssociated);
}
}
return sprites;
}
/**
* Returns the sound instances (their ID) used (stored in the {@link CB_AudioFileSprites#spriteSoundInstances} property of each {@link CB_AudioFileSprites} object).
* @function
* @param {boolean} [oneDimension=false] - If set to false, it will return an object whose property names will be the ID of each sprites group and their value will be the {@link CB_AudioFileSprites#spriteSoundInstances} property of each {@link CB_AudioFileSprites} object (which includes the "_WITHOUT_SPRITE_ASSOCIATED" property for sound instances without a sprite associated) which belongs to that sprites group. Otherwise, if it is set to true, it will return a numeric array whose values are the sound instance IDs.
* @param {boolean} [includeWithoutSpriteAssociated=false] - If set to true, it will also return the sound instance identifiers which are not associated to any sprite. Used as the "includeWithoutSpriteAssociated" parameter when calling the {@link CB_AudioFileSprites#getSoundInstancesId} method internally. Only used when the "oneDimension" parameter is set to true.
* @returns {Object|array} Returns the sound instances (their ID) used (stored in the {@link CB_AudioFileSprites#spriteSoundInstances} property). If the "oneDimension" parameter is set to false, it will return an object whose property names will be the ID of each sprites group and their value will be the {@link CB_AudioFileSprites#spriteSoundInstances} property of each {@link CB_AudioFileSprites} object (which includes the "_WITHOUT_SPRITE_ASSOCIATED" property for sound instances without a sprite associated) which belongs to that sprites group. If the "oneDimension" parameter is set to true, it will return a numeric array whose values are the sound instance identifiers (if the "includeWithoutSpriteAssociated" parameter it set to true, it will also include the sound instances which are not associated to any sprite).
*/
CB_AudioFileSpritesPool.prototype.getSoundInstancesId = function(oneDimension, includeWithoutSpriteAssociated)
{
var soundInstances;
if (!oneDimension)
{
soundInstances = {};
for (var spritesGroupId in this.audioFileSprites)
{
soundInstances[spritesGroupId] = this.audioFileSprites[spritesGroupId].getSoundInstancesId(false, includeWithoutSpriteAssociated);
}
}
else
{
soundInstances = [];
var soundInstancesSpritesGroup;
var soundInstancesSpritesGroupLength;
var y = 0;
var x = 0;
for (var spritesGroupId in this.audioFileSprites)
{
soundInstancesSpritesGroup = this.audioFileSprites[spritesGroupId].getSoundInstancesId(true, includeWithoutSpriteAssociated);
soundInstancesSpritesGroupLength = soundInstancesSpritesGroup.length;
for (x = 0; x < soundInstancesSpritesGroupLength; x++)
{
soundInstances[y++] = soundInstancesSpritesGroup[x];
}
}
}
return soundInstances;
}
/**
* Object returned by the {@link CB_AudioFileSpritesPool#getAudioFilesUsed} method. Each property names will be the the ID of each sprites group and their value will be a {@link CB_AudioFileSprites.getAudioFilesUsed_OBJECT} object.
* @memberof CB_AudioFileSpritesPool
* @typedef {Object} CB_AudioFileSpritesPool.getAudioFilesUsed_OBJECT
* @property {CB_AudioFileSpritesPool.getAudioFilesUsed_OBJECT} spriteId - Each property names will be the the ID of each sprites group and their value will be a {@link CB_AudioFileSprites.getAudioFilesUsed_OBJECT} object.
*/
/**
* Returns the {@link CB_AudioFile} objects used by all the sounds instances of all the sprites groups.
* @function
* @param {boolean} [oneDimension=false] - If set to false, it will return an object whose property names will be the ID of each sprites group and their value will be the an object whose property names are the sprite identifiers (including the "_WITHOUT_SPRITE_ASSOCIATED" property for sound instances without a sprite associated, if th