/* eslint-disable no-magic-numbers */ // // soundEmitter.js // // Created by Zach Fox on 2019-07-05 // Copyright High Fidelity 2019 // // Licensed under the Apache 2.0 License // See accompanying license file or http://apache.org/ // (function() { var that; var SOUND_EMITTER_UPDATE_INTERVAL_MS = 500; var DEFAULT_AUDIO_INJECTOR_OPTIONS = { "position": { "x": 0, "y": 0, "z": 0 }, "volume": 0.5, "loop": false, "localOnly": false }; var SoundEmitter = function() { that = this; that.entityID = false; that.soundObjectURL = false; that.soundObject = false; that.audioInjector = false; that.audioInjectorOptions = DEFAULT_AUDIO_INJECTOR_OPTIONS; that.signalsConnected = {}; that.soundEmitterUpdateInterval = false; }; SoundEmitter.prototype = { preload: function(entityID) { that.entityID = entityID; var properties = Entities.getEntityProperties(that.entityID, ["userData"]); var userData; try { userData = JSON.parse(properties.userData); } catch (e) { console.error("Error parsing userData: ", e); } if (userData) { if (userData.soundURL && userData.soundURL.length > 0) { that.handleNewSoundURL(userData.soundURL); } else { console.log("Please specify this entity's `userData`! See README.md for instructions."); return; } } else { console.log("Please specify this entity's `userData`! See README.md for instructions."); return; } }, clearCurrentSoundData: function() { that.soundObjectURL = false; if (that.signalsConnected["soundObjectReady"]) { that.soundObject.ready.disconnect(that.updateSoundEmitter); that.signalsConnected["soundObjectReady"] = false; } that.soundObject = false; if (that.audioInjector) { if (that.audioInjector.playing) { that.audioInjector.stop(); } that.audioInjector = false; } that.audioInjectorOptions = DEFAULT_AUDIO_INJECTOR_OPTIONS; if (that.soundEmitterUpdateInterval) { Script.clearInterval(that.soundEmitterUpdateInterval); that.soundEmitterUpdateInterval = false; } }, unload: function() { that.clearCurrentSoundData(); }, handleNewSoundURL: function(newSoundURL) { that.clearCurrentSoundData(); that.soundObjectURL = newSoundURL; that.soundObject = SoundCache.getSound(that.soundObjectURL); if (that.soundObject.downloaded) { that.updateSoundEmitter(); } else { that.soundObject.ready.connect(that.updateSoundEmitter); that.signalsConnected["soundObjectReady"] = true; } }, positionChanged: function(newPos) { return (newPos.x !== that.audioInjectorOptions.position.x || newPos.y !== that.audioInjectorOptions.position.y || newPos.z !== that.audioInjectorOptions.position.z); }, updateSoundEmitter: function() { var properties = Entities.getEntityProperties(that.entityID, ["userData", "position", "script", "serverScripts"]); var userData; try { userData = JSON.parse(properties.userData); } catch (e) { console.error("Error parsing userData: ", e); } var optionsChanged = false; var shouldRestartPlayback = false; var newPosition = properties.position; if (userData) { if (userData.soundURL && userData.soundURL.length > 0 && userData.soundURL !== that.soundObjectURL) { console.log("Sound Emitter: User put a new sound URL into `userData`! Resetting..."); that.handleNewSoundURL(userData.soundURL); return; } if (typeof(userData.volume) !== "undefined" && !isNaN(userData.volume) && userData.volume !== that.audioInjectorOptions.volume) { optionsChanged = true; that.audioInjectorOptions.volume = userData.volume; } if (typeof(userData.shouldLoop) !== "undefined" && userData.shouldLoop !== that.audioInjectorOptions.shouldLoop) { optionsChanged = true; if (!that.audioInjectorOptions.loop && userData.shouldLoop && that.audioInjector && !that.audioInjector.playing) { shouldRestartPlayback = true; } that.audioInjectorOptions.loop = userData.shouldLoop; } if (typeof(userData.positionOverride) !== "undefined" && !isNaN(userData.positionOverride.x) && !isNaN(userData.positionOverride.y) && !isNaN(userData.positionOverride.z)) { newPosition = userData.positionOverride; } } else { console.log("Please specify this entity's `userData`! See README.md for instructions."); that.clearCurrentSoundData(); return; } var localOnly = that.audioInjectorOptions.localOnly; // If this script is attached as a client entity script... if (properties.script.indexOf("soundEmitter.js") > -1) { // ... Make sure that the audio injector IS local only. localOnly = true; // Else if this script is attached as a client server script... } else if (properties.serverScripts.indexOf("soundEmitter.js") > -1) { // ... Make sure that the audio injector IS NOT local only. localOnly = false; } if (localOnly !== that.audioInjectorOptions.localOnly) { optionsChanged = true; that.audioInjectorOptions.localOnly = localOnly; } if (that.positionChanged(newPosition)) { optionsChanged = true; that.audioInjectorOptions["position"] = newPosition; } if (!that.audioInjector || shouldRestartPlayback) { that.audioInjector = Audio.playSound(that.soundObject, that.audioInjectorOptions); } else if (optionsChanged) { that.audioInjector.setOptions(that.audioInjectorOptions); } if (!that.soundEmitterUpdateInterval) { that.soundEmitterUpdateInterval = Script.setInterval(that.updateSoundEmitter, SOUND_EMITTER_UPDATE_INTERVAL_MS); } } }; return new SoundEmitter(); });