import register from "../util/register.js";
import m_obj_util_fact from "../intern/obj_util.js";
import m_scs_fact from "../intern/scenes.js";
import m_sfx_fact from "../intern/sfx.js";
import m_print_fact from "../intern/print.js";
/**
* Sound effects API.
* Uses Web Audio API for sound effects and HTML5 audio for background music.
* @see https://www.blend4web.com/doc/en/audio.html
* @module sfx
* @cc_externs AudioContext webkitAudioContext MediaElementAudioSourceNode
*/
function SFX(ns, exports) {
var m_obj_util = m_obj_util_fact(ns);
var m_scs = m_scs_fact(ns);
var m_sfx = m_sfx_fact(ns);
var m_print = m_print_fact(ns);
/**
* Play sound through the speaker.
* @method module:sfx.play
* @param {Object3D} obj Object 3D
* @param {number} [when=0] Delay after exec in seconds
* @param {number} [duration=0] Duration of the speaker's playback cycle (in
* seconds). duration=0 - assign default value according to sound playback length.
*/
exports.play = function(obj, when, duration) {
when = when || 0;
duration = duration || 0;
m_sfx.play(obj, when, duration);
}
/**
* Play sound through the speaker using the default delay and duration params.
* @method module:sfx.play_def
* @param {Object3D} obj Object 3D
*/
exports.play_def = function(obj) {
m_sfx.play_def(obj);
}
/**
* Check if sound is played through the speaker now.
* @method module:sfx.is_playing
* @param {Object3D} obj Object 3D
* @returns {boolean} Playing state
*/
exports.is_playing = function(obj) {
return m_sfx.is_playing(obj);
}
/**
* Stop the speaker.
* @method module:sfx.stop
* @param {Object3D} obj Object 3D
*/
exports.stop = function(obj) {
m_sfx.stop(obj);
}
/**
* Pause the speaker.
* @method module:sfx.pause
* @param {Object3D} obj Object 3D
*/
exports.pause = function(obj) {
m_sfx.speaker_pause(obj);
}
/**
* Resume the paused speaker.
* @method module:sfx.resume
* @param {Object3D} obj Object 3D
*/
exports.resume = function(obj) {
m_sfx.speaker_resume(obj);
}
/**
* Stop the speaker's looping playback.
* @method module:sfx.loop_stop
* @param {Object3D} obj Speaker object
* @param {number} [when=0] Delay after exec in seconds
* @param {boolean} [wait=false] Wait loop until currently played cycle is
* finished
*/
exports.loop_stop = function(obj, when, wait) {
when = when || 0;
wait = wait || false;
m_sfx.loop_stop(obj, when, wait);
}
/**
* Change the speaker playback rate value.
* @method module:sfx.playrate
* @param {Object3D} obj Object 3D
* @param {number} playrate Playback rate (1.0 - normal speed).
*/
exports.playrate = function(obj, playrate) {
m_sfx.playrate(obj, playrate);
}
/**
* Get the speaker playback rate value.
* @method module:sfx.playrate
* @param {Object3D} obj Object 3D
* @returns {number} Playback rate
*/
exports.get_playrate = function(obj) {
return m_sfx.get_playrate(obj);
}
/**
* Set cyclic flag.
* @method module:sfx.cyclic
* @param {Object3D} obj Speaker object.
* @param {boolean} cyclic New cyclic flag value.
*/
exports.cyclic = function(obj, cyclic) {
m_sfx.cyclic(obj, cyclic);
}
/**
* Check if the cyclic flag is set.
* @method module:sfx.is_cyclic
* @param {Object3D} obj Speaker object.
* @returns {boolean} Cyclic flag value.
*/
exports.is_cyclic = function(obj) {
return m_sfx.is_cyclic(obj);
}
/**
* Reset the listener speed.
* Use before rapid listener movements to neutralize undesirable doppler effect.
* @method module:sfx.listener_reset_speed
* @param {number} speed The listener new speed
* @param {?Float32Array} [dir=null] The listener new direction
* @deprecated Use {@link module:sfx.listener_stride|sfx.listener_stride} instead
*/
exports.listener_reset_speed = function(speed, dir) {
m_sfx.listener_stride();
}
/**
* Make a listener stride.
* Use before quick listener movements to neutralize undesirable doppler effect.
* @method module:sfx.listener_stride
*/
exports.listener_stride = function() {
m_sfx.listener_stride();
}
/**
* Reset the speaker speed.
* It's necessary to nullify speed before the speaker has moved quickly in order
* to neutralize the undesirable doppler effect.
* @method module:sfx.speaker_reset_speed
* @param {Object3D} obj Speaker object.
* @param {number} speed The speaker's new speed
* @param {?Float32Array} [dir=null] The speaker's new direction
* @deprecated Use {@link module:sfx.speaker_stride|sfx.speaker_stride} instead
*/
exports.speaker_reset_speed = function(obj, speed, dir) {
m_sfx.speaker_stride(obj);
}
/**
* Make a speaker stride.
* Use before rapid speaker movements to neutralize undesirable doppler effect.
* @method module:sfx.speaker_reset_speed
* @param {Object3D} obj Speaker object.
*/
exports.speaker_stride = function(obj) {
m_sfx.speaker_stride(obj);
}
/**
* Get volume level.
* @method module:sfx.get_volume
* @param {?Object3D} obj Object 3D or null for MASTER volume
* @returns {number} Volume (0..1)
*/
exports.get_volume = function(obj) {
if (obj && typeof obj === "object")
return m_sfx.get_volume(obj);
else
return m_sfx.get_master_volume();
}
/**
* Set volume level.
* @method module:sfx.set_volume
* @param {?Object3D} obj Object 3D or null for MASTER volume
* @param {number} volume Volume (0..1)
*/
exports.set_volume = function(obj, volume) {
if (obj && typeof obj === "object")
m_sfx.set_volume(obj, volume);
else
m_sfx.set_master_volume(volume);
}
/**
* Mute/unmute.
* @method module:sfx.mute
* @param {?Object3D} obj Speaker object or null to mute the whole scene.
* @param {boolean} muted New state
*/
exports.mute = function(obj, muted) {
if (obj && typeof obj === "object")
m_sfx.mute(obj, muted);
else
m_sfx.mute_master(muted);
}
/**
* Check if the speaker is muted.
* @method module:sfx.is_muted
* @param {?Object3D} obj Speaker object or null for the whole scene.
* @returns {boolean} Muted state.
*/
exports.is_muted = function(obj) {
if (obj && typeof obj === "object")
return m_sfx.is_muted(obj);
else
return m_sfx.is_master_muted();
}
/**
* Get the speaker objects which are used by the module.
* @returns {Array} Speaker object array
*/
exports.get_speaker_objects = function() {
return m_sfx.get_speaker_objects().slice(0);
}
/**
* Check if there are some active speakers in use or not.
* @method module:sfx.check_active_speakers
* @returns {boolean} Check result
*/
exports.check_active_speakers = m_sfx.check_active_speakers;
/**
* Set compressor params.
* @method module:sfx.set_compressor_params
* @param {CompressorParams} params Params object
* @cc_externs threshold knee ratio attack release
*/
exports.set_compressor_params = function(params) {
m_sfx.set_compressor_params(m_scs.get_active(), params);
}
/**
* Get compressor params.
* @method module:sfx.get_compressor_params
* @returns {CompressorParams} Params object
*/
exports.get_compressor_params = function() {
return m_sfx.get_compressor_params(m_scs.get_active());
}
/**
* Duck (reduce the volume).
* works independently from the volume API and the volume randomization
* @method module:sfx.duck
* @param {?Object3D} obj Object 3D or null for MASTER
* @param {number} value Duck amount.
* @param {number} time Time to change volume.
*/
exports.duck = function(obj, value, time) {
if (obj && typeof obj === "object")
m_sfx.duck(obj, value, time);
else
m_sfx.duck_master(value, time);
}
/**
* Unduck (restore the volume).
* @method module:sfx.unduck
* @param {?Object3D} obj Object 3D or null for MASTER
*/
exports.unduck = function(obj) {
if (obj && typeof obj === "object")
m_sfx.unduck(obj);
else
m_sfx.unduck_master();
}
/**
* Apply the new playlist from the given set of speakers.
* The new playlist starts playing immediately.
* @method module:sfx.apply_playlist
* @param {Object3D[]} objs Array of objects.
* @param {number} delay Number of seconds between tracks
* @param {boolean} random Randomize playback sequence
*/
exports.apply_playlist = m_sfx.apply_playlist;
/**
* Stop playback and clear the playlist.
* @method module:sfx.clear_playlist
*/
exports.clear_playlist = m_sfx.clear_playlist;
/**
* Detect supported audio container.
* Containers have same meaning as file extension here, for each one possible
* fallback exists:
* <ul>
* <li>ogg -> mp4
* <li>mp3 -> ogg
* <li>mp4 -> ogg
* </ul>
* @method module:sfx.detect_audio_container
* @param {string} [hint="ogg"] Required container
* @returns {string} Supported container or ""
*/
exports.detect_audio_container = m_sfx.detect_audio_container;
/**
* Detect supported video container.
* Containers have same meaning as file extension here, for each one possible
* fallback exists:
* <ul>
* <li>ogv -> m4v
* <li>m4v -> webm
* <li>webm -> m4v
* </ul>
* @method module:sfx.detect_video_container
* @param {string} [hint="webm"] Required container
* @returns {string} Supported container or ""
*/
exports.detect_video_container = m_sfx.detect_video_container;
/**
* Set positional params.
* @method module:sfx.set_positional_params
* @param {Object3D} obj Object 3D
* @param {PositionalParams} params Params object
* @cc_externs dist_ref dist_max attenuation
*/
exports.set_positional_params = m_sfx.set_positional_params;
/**
* Get positional params.
* @method module:sfx.get_positional_params
* @param {Object3D} obj Object 3D
* @returns {PositionalParams} Params object
*/
exports.get_positional_params = m_sfx.get_positional_params;
/**
* Set filter params.
* @method module:sfx.set_filter_params
* @param {Object3D} obj Object 3D
* @param {FilterParams} params Params object
* @cc_externs freq Q gain
*/
exports.set_filter_params = m_sfx.set_filter_params;
/**
* Get filter params.
* @method module:sfx.get_filter_params
* @param {Object3D} obj Object 3D
* @returns {FilterParams} Params object
*/
exports.get_filter_params = m_sfx.get_filter_params;
/**
* Get filter frequency response.
* @method module:sfx.get_filter_freq_response
* @param {Object3D} obj Object 3D
* @param {Float32Array} freq_arr Input array with frequencies.
* @param {Float32Array} mag_arr Output array with filter response magnitudes.
* @param {Float32Array} phase_arr Output array with filter response phases.
*/
exports.get_filter_freq_response = m_sfx.get_filter_freq_response;
/**
* Get duration of the speaker's playback cycle.
* Zero duration means looped or non-ready speaker
* @method module:sfx.get_duration
* @param {?Object3D} obj Speaker object.
* @returns {number} Duration
*/
exports.get_duration = function(obj) {
if (!obj || !m_obj_util.is_speaker(obj)) {
m_print.error("Object \"" + (obj ? obj.name : undefined) +
"\" is not a valid speaker");
return 0;
}
return m_sfx.get_duration(obj);
}
}
var sfx_factory = register("sfx", SFX);
export default sfx_factory;