From 20d1ba11c3c342a776826b84c7a6840b69236e10 Mon Sep 17 00:00:00 2001 From: ericrius1 Date: Tue, 2 Feb 2016 10:37:23 -0800 Subject: [PATCH 01/37] Basic ac sound playing and entity searching Injecting sounds from entity --- .../ACAudioSearchAndInject.js | 59 +++++++++++++++++++ .../acAudioSearchCompatibleEntitySpawner.js | 36 +++++++++++ 2 files changed, 95 insertions(+) create mode 100644 examples/audioExamples/acAudioSearching/ACAudioSearchAndInject.js create mode 100644 examples/audioExamples/acAudioSearching/acAudioSearchCompatibleEntitySpawner.js diff --git a/examples/audioExamples/acAudioSearching/ACAudioSearchAndInject.js b/examples/audioExamples/acAudioSearching/ACAudioSearchAndInject.js new file mode 100644 index 0000000000..dee5408589 --- /dev/null +++ b/examples/audioExamples/acAudioSearching/ACAudioSearchAndInject.js @@ -0,0 +1,59 @@ +// +// ACAudioSearchAndInject.js +// audio +// +// Created by Eric Levin 2/1/2016 +// Copyright 2016 High Fidelity, Inc. + +// This AC script constantly searches for entities with a special userData field that specifies audio settings, and then +// injects the sound with the specified URL with other specified settings (playback volume) or playback at interval, or random interval +// +// Distributed under the Apache License, Version 2.0. +// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html +// + +Script.include("https://rawgit.com/highfidelity/hifi/master/examples/libraries/utils.js"); +var SOUND_DATA_KEY = "soundKey"; + + +EntityViewer.setPosition({ + x: 0, + y: 0, + z: 0 +}); +EntityViewer.setKeyholeRadius(60000); +EntityViewer.queryOctree(); +Entities.setPacketsPerSecond(6000); + +Script.setInterval(function() { + var entities = Entities.findEntities({ + x: 0, + y: 0, + z: 0 + }, 16000) + print("EBL ENTITIES FOUND " + entities.length); + entities.forEach(function(entity) { + var soundData = getEntityCustomData(SOUND_KEY, entity); + if (soundData && soundData.url) { + playSound(soundData); + } + }); + +}, 1000); + +function playSound(soundData) { + var sound = SoundCache.getSound(soundData.url); + sound.ready.connect(function() { + print("EBL PLAY SOUND") + Audio.playSound(sound, { + position: { + x: 0, + y: 0, + z: 0 + }, + volume: 1.0, + loop: true + }); + }) + +} \ No newline at end of file diff --git a/examples/audioExamples/acAudioSearching/acAudioSearchCompatibleEntitySpawner.js b/examples/audioExamples/acAudioSearching/acAudioSearchCompatibleEntitySpawner.js new file mode 100644 index 0000000000..e25e114ba5 --- /dev/null +++ b/examples/audioExamples/acAudioSearching/acAudioSearchCompatibleEntitySpawner.js @@ -0,0 +1,36 @@ +// +// acAudioSearchCompatibleEntitySpawner.js +// audio/acAudioSearching +// +// Created by Eric Levin 2/2/2016 +// Copyright 2016 High Fidelity, Inc. + +// This is a client script which spawns entities with a field in userdata compatible with the AcAudioSearchAndInject script +// These entities specify data about the sound they want to play, such as url, volume, and whether to loop or not +// The position of the entity determines the position from which the sound plays from +// +// Distributed under the Apache License, Version 2.0. +// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html +// + +Script.include("../../libraries/utils.js"); + +var SOUND_DATA_KEY = "soundKey"; + +var soundEntity = Entities.addEntity({ + type: "Box", + position: {x: 0, y: 0, z: 0}, + color: {red: 200, green: 10, blue: 200}, + dimensions: {x: .1, y: .1, z: .1}, + userData: JSON.stringify({ + soundKey: { + url: "http://hifi-public.s3.amazonaws.com/ryan/demo/0619_Fireplace__Tree_B.L.wav" + } + }) +}); + +function cleanup() { + Entities.deleteEntity(soundEntity); +} + +Script.scriptEnding.connect(cleanup); \ No newline at end of file From 93220c3b01c065e326b12b5932a46c929db3bb30 Mon Sep 17 00:00:00 2001 From: ericrius1 Date: Tue, 2 Feb 2016 10:51:10 -0800 Subject: [PATCH 02/37] two sounds --- .../ACAudioSearchAndInject.js | 11 ++--- .../acAudioSearchCompatibleEntitySpawner.js | 45 ++++++++++++++----- 2 files changed, 39 insertions(+), 17 deletions(-) diff --git a/examples/audioExamples/acAudioSearching/ACAudioSearchAndInject.js b/examples/audioExamples/acAudioSearching/ACAudioSearchAndInject.js index dee5408589..3356942b8a 100644 --- a/examples/audioExamples/acAudioSearching/ACAudioSearchAndInject.js +++ b/examples/audioExamples/acAudioSearching/ACAudioSearchAndInject.js @@ -25,7 +25,9 @@ EntityViewer.setKeyholeRadius(60000); EntityViewer.queryOctree(); Entities.setPacketsPerSecond(6000); -Script.setInterval(function() { +Script.setInterval(searchForSoundEntities, 1000); + +function searchForSoundEntities() { var entities = Entities.findEntities({ x: 0, y: 0, @@ -33,13 +35,12 @@ Script.setInterval(function() { }, 16000) print("EBL ENTITIES FOUND " + entities.length); entities.forEach(function(entity) { - var soundData = getEntityCustomData(SOUND_KEY, entity); + var soundData = getEntityCustomData(SOUND_DATA_KEY, entity); if (soundData && soundData.url) { playSound(soundData); } }); - -}, 1000); +} function playSound(soundData) { var sound = SoundCache.getSound(soundData.url); @@ -52,7 +53,7 @@ function playSound(soundData) { z: 0 }, volume: 1.0, - loop: true + loop: false }); }) diff --git a/examples/audioExamples/acAudioSearching/acAudioSearchCompatibleEntitySpawner.js b/examples/audioExamples/acAudioSearching/acAudioSearchCompatibleEntitySpawner.js index e25e114ba5..328e2d3cf6 100644 --- a/examples/audioExamples/acAudioSearching/acAudioSearchCompatibleEntitySpawner.js +++ b/examples/audioExamples/acAudioSearching/acAudioSearchCompatibleEntitySpawner.js @@ -5,7 +5,7 @@ // Created by Eric Levin 2/2/2016 // Copyright 2016 High Fidelity, Inc. -// This is a client script which spawns entities with a field in userdata compatible with the AcAudioSearchAndInject script +// This is a client script which spawns entities with a field in userData compatible with the AcAudioSearchAndInject script // These entities specify data about the sound they want to play, such as url, volume, and whether to loop or not // The position of the entity determines the position from which the sound plays from // @@ -17,20 +17,41 @@ Script.include("../../libraries/utils.js"); var SOUND_DATA_KEY = "soundKey"; -var soundEntity = Entities.addEntity({ +var userData = { + soundKey: { + url: "http://hifi-public.s3.amazonaws.com/ryan/Water_Lap_River_Edge_Gentle.L.wav" + } +} + +var entityProps = { type: "Box", - position: {x: 0, y: 0, z: 0}, - color: {red: 200, green: 10, blue: 200}, - dimensions: {x: .1, y: .1, z: .1}, - userData: JSON.stringify({ - soundKey: { - url: "http://hifi-public.s3.amazonaws.com/ryan/demo/0619_Fireplace__Tree_B.L.wav" - } - }) -}); + position: { + x: 0, + y: 0, + z: 0 + }, + color: { + red: 200, + green: 10, + blue: 200 + }, + dimensions: { + x: .1, + y: .1, + z: .1 + }, + userData: JSON.stringify(userData) +} +var soundEntity1 = Entities.addEntity(entityProps); + +userData.soundKey.url = "http://hifi-public.s3.amazonaws.com/ryan/demo/0619_Fireplace__Tree_B.L.wav"; +entityProps.userData = JSON.stringify(userData); +entityProps.position.x += 0.3 +var soundEntity2 = Entities.addEntity(entityProps); function cleanup() { - Entities.deleteEntity(soundEntity); + Entities.deleteEntity(soundEntity1); + Entities.deleteEntity(soundEntity2); } Script.scriptEnding.connect(cleanup); \ No newline at end of file From 0aa68328c89f162ac29945993bdb1d26b138a71f Mon Sep 17 00:00:00 2001 From: ericrius1 Date: Tue, 2 Feb 2016 13:59:56 -0800 Subject: [PATCH 03/37] adding sound entity script --- .../ACAudioSearchAndInject.js | 50 +++++++------------ .../acAudioSearchCompatibleEntitySpawner.js | 15 ++++-- .../acAudioSearching/soundEntityScript.js | 0 3 files changed, 29 insertions(+), 36 deletions(-) create mode 100644 examples/audioExamples/acAudioSearching/soundEntityScript.js diff --git a/examples/audioExamples/acAudioSearching/ACAudioSearchAndInject.js b/examples/audioExamples/acAudioSearching/ACAudioSearchAndInject.js index 3356942b8a..8ff6f22fa4 100644 --- a/examples/audioExamples/acAudioSearching/ACAudioSearchAndInject.js +++ b/examples/audioExamples/acAudioSearching/ACAudioSearchAndInject.js @@ -13,48 +13,34 @@ // Script.include("https://rawgit.com/highfidelity/hifi/master/examples/libraries/utils.js"); -var SOUND_DATA_KEY = "soundKey"; +var ENTITY_QUERY_INTERVAL = 2000; +var SOUND_DATA_KEY = "soundKey"; +var MESSAGE_CHANNEL = "Hifi-Sound-Entity"; + +// Map of all sound entities in domain- key is entity id, value is data +var soundEntities = {}; EntityViewer.setPosition({ x: 0, y: 0, z: 0 }); + EntityViewer.setKeyholeRadius(60000); -EntityViewer.queryOctree(); Entities.setPacketsPerSecond(6000); -Script.setInterval(searchForSoundEntities, 1000); +var DEFAULT_SOUND_DATA = { + volume: 0.5, + loop: false +}; + +print("EBL STARTING AC SCRIPT"); + +function messageReceived(channel, message, sender) { + -function searchForSoundEntities() { - var entities = Entities.findEntities({ - x: 0, - y: 0, - z: 0 - }, 16000) - print("EBL ENTITIES FOUND " + entities.length); - entities.forEach(function(entity) { - var soundData = getEntityCustomData(SOUND_DATA_KEY, entity); - if (soundData && soundData.url) { - playSound(soundData); - } - }); } -function playSound(soundData) { - var sound = SoundCache.getSound(soundData.url); - sound.ready.connect(function() { - print("EBL PLAY SOUND") - Audio.playSound(sound, { - position: { - x: 0, - y: 0, - z: 0 - }, - volume: 1.0, - loop: false - }); - }) - -} \ No newline at end of file +Messages.subscribe(MESSAGE_CHANNEL); +Messages.messageReceived.connect(messageReceived); \ No newline at end of file diff --git a/examples/audioExamples/acAudioSearching/acAudioSearchCompatibleEntitySpawner.js b/examples/audioExamples/acAudioSearching/acAudioSearchCompatibleEntitySpawner.js index 328e2d3cf6..d9c2be461d 100644 --- a/examples/audioExamples/acAudioSearching/acAudioSearchCompatibleEntitySpawner.js +++ b/examples/audioExamples/acAudioSearching/acAudioSearchCompatibleEntitySpawner.js @@ -16,10 +16,14 @@ Script.include("../../libraries/utils.js"); var SOUND_DATA_KEY = "soundKey"; - +var MESSAGE_CHANNEL = "Hifi-Sound-Entity"; +var SCRIPT_URL = Script.resolvePath("soundEntityScript.js?v1" + Math.random()); +//http://hifi-public.s3.amazonaws.com/ryan/Water_Lap_River_Edge_Gentle.L.wav var userData = { soundKey: { - url: "http://hifi-public.s3.amazonaws.com/ryan/Water_Lap_River_Edge_Gentle.L.wav" + url: "https://s3-us-west-1.amazonaws.com/hifi-content/eric/Sounds/dove.wav", + volume: 0.5, + loop: true } } @@ -47,11 +51,14 @@ var soundEntity1 = Entities.addEntity(entityProps); userData.soundKey.url = "http://hifi-public.s3.amazonaws.com/ryan/demo/0619_Fireplace__Tree_B.L.wav"; entityProps.userData = JSON.stringify(userData); entityProps.position.x += 0.3 -var soundEntity2 = Entities.addEntity(entityProps); + +print("EBL SENDING MESSAGE") +Messages.sendMessage(MESSAGE_CHANNEL, JSON.stringify({})); +//var soundEntity2 = Entities.addEntity(entityProps); function cleanup() { Entities.deleteEntity(soundEntity1); - Entities.deleteEntity(soundEntity2); + //Entities.deleteEntity(soundEntity2); } Script.scriptEnding.connect(cleanup); \ No newline at end of file diff --git a/examples/audioExamples/acAudioSearching/soundEntityScript.js b/examples/audioExamples/acAudioSearching/soundEntityScript.js new file mode 100644 index 0000000000..e69de29bb2 From d08bdb371a2c720f4d3a9773926e614999cefb75 Mon Sep 17 00:00:00 2001 From: ericrius1 Date: Tue, 2 Feb 2016 14:50:30 -0800 Subject: [PATCH 04/37] receiving push messages from entity script --- .../ACAudioSearchAndInject.js | 9 +++++- .../acAudioSearchCompatibleEntitySpawner.js | 7 ++--- .../acAudioSearching/soundEntityScript.js | 30 +++++++++++++++++++ 3 files changed, 41 insertions(+), 5 deletions(-) diff --git a/examples/audioExamples/acAudioSearching/ACAudioSearchAndInject.js b/examples/audioExamples/acAudioSearching/ACAudioSearchAndInject.js index 8ff6f22fa4..7630cf984c 100644 --- a/examples/audioExamples/acAudioSearching/ACAudioSearchAndInject.js +++ b/examples/audioExamples/acAudioSearching/ACAudioSearchAndInject.js @@ -38,7 +38,14 @@ var DEFAULT_SOUND_DATA = { print("EBL STARTING AC SCRIPT"); function messageReceived(channel, message, sender) { - + EntityViewer.queryOctree(); + print("EBL RECEIVED A MESSAGE FROM ENTITY: " + message); + var entityID = JSON.parse(message).id; + var soundData = getEntityCustomData(SOUND_DATA_KEY, entityID); + print("SOUND DATA " + JSON.stringify(soundData)) + if (soundData && soundData.url) { + + } } diff --git a/examples/audioExamples/acAudioSearching/acAudioSearchCompatibleEntitySpawner.js b/examples/audioExamples/acAudioSearching/acAudioSearchCompatibleEntitySpawner.js index d9c2be461d..7452f29845 100644 --- a/examples/audioExamples/acAudioSearching/acAudioSearchCompatibleEntitySpawner.js +++ b/examples/audioExamples/acAudioSearching/acAudioSearchCompatibleEntitySpawner.js @@ -44,16 +44,15 @@ var entityProps = { y: .1, z: .1 }, - userData: JSON.stringify(userData) + userData: JSON.stringify(userData), + script: SCRIPT_URL } + var soundEntity1 = Entities.addEntity(entityProps); userData.soundKey.url = "http://hifi-public.s3.amazonaws.com/ryan/demo/0619_Fireplace__Tree_B.L.wav"; entityProps.userData = JSON.stringify(userData); entityProps.position.x += 0.3 - -print("EBL SENDING MESSAGE") -Messages.sendMessage(MESSAGE_CHANNEL, JSON.stringify({})); //var soundEntity2 = Entities.addEntity(entityProps); function cleanup() { diff --git a/examples/audioExamples/acAudioSearching/soundEntityScript.js b/examples/audioExamples/acAudioSearching/soundEntityScript.js index e69de29bb2..702dc94243 100644 --- a/examples/audioExamples/acAudioSearching/soundEntityScript.js +++ b/examples/audioExamples/acAudioSearching/soundEntityScript.js @@ -0,0 +1,30 @@ +// soundEntityScript.js +// +// Script Type: Entity +// Created by Eric Levin on 2/2/16. +// Copyright 2016 High Fidelity, Inc. +// +// This entity script sends a message meant for a running AC script on preload +// Distributed under the Apache License, Version 2.0. +// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html +// + +(function() { + Script.include("../../libraries/utils.js"); + var _this; + // this is the "constructor" for the entity as a JS object we don't do much here + var SoundEntity = function() { + _this = this; + this.MESSAGE_CHANNEL = "Hifi-Sound-Entity"; + }; + + SoundEntity.prototype = { + preload: function(entityID) { + this.entityID = entityID; + print("EBL SENDING MESSAGE " + this.entityID); + Messages.sendMessage(this.MESSAGE_CHANNEL, JSON.stringify({id: this.entityID})); + }, + }; + // entity scripts always need to return a newly constructed object of our type + return new SoundEntity(); +}); From 964763b88c5af94cddb05b8249f4ac83d7eeb425 Mon Sep 17 00:00:00 2001 From: ericrius1 Date: Tue, 2 Feb 2016 15:54:37 -0800 Subject: [PATCH 05/37] caching sounds --- .../ACAudioSearchAndInject.js | 56 +++++++++++++++++-- .../acAudioSearchCompatibleEntitySpawner.js | 6 +- 2 files changed, 55 insertions(+), 7 deletions(-) diff --git a/examples/audioExamples/acAudioSearching/ACAudioSearchAndInject.js b/examples/audioExamples/acAudioSearching/ACAudioSearchAndInject.js index 7630cf984c..b50eb48c37 100644 --- a/examples/audioExamples/acAudioSearching/ACAudioSearchAndInject.js +++ b/examples/audioExamples/acAudioSearching/ACAudioSearchAndInject.js @@ -19,7 +19,8 @@ var SOUND_DATA_KEY = "soundKey"; var MESSAGE_CHANNEL = "Hifi-Sound-Entity"; // Map of all sound entities in domain- key is entity id, value is data -var soundEntities = {}; +var soundEntityMap = {}; +var soundUrls = {}; EntityViewer.setPosition({ x: 0, @@ -38,16 +39,63 @@ var DEFAULT_SOUND_DATA = { print("EBL STARTING AC SCRIPT"); function messageReceived(channel, message, sender) { + + var entityID = JSON.parse(message).id; + if (soundEntityMap[entityID]) { + // We already have this entity in our sound map, so don't re-add + return; + } + EntityViewer.queryOctree(); print("EBL RECEIVED A MESSAGE FROM ENTITY: " + message); - var entityID = JSON.parse(message).id; var soundData = getEntityCustomData(SOUND_DATA_KEY, entityID); print("SOUND DATA " + JSON.stringify(soundData)) if (soundData && soundData.url) { - + var soundProperties = { + url: soundData.url, + volume: soundData.volume || DEFAULT_SOUND_DATA.volume, + loop: soundData.loop || DEFAULT_SOUND_DATA.loop, + needsPlay: true, + position: Entities.getEntityProperties(entityID, "position").position + }; + if (!soundUrls[soundData.url]) { + // We need to download sound before we add it to our map + var sound = SoundCache.getSound(soundData.url); + soundUrls[soundData.url] = sound; + // Only add it to map once it's downloaded + sound.ready.connect(function() { + soundProperties.sound = sound; + soundEntityMap[entityID] = soundProperties; + }); + } else { + // We already have sound downloaded, so just add it to map right away + soundProperties.sound = soundUrls[soundData.url]; + soundEntityMap[entityID] = soundProperties; + } } - } +function update() { + // Go through each sound and play it if it needs to be played + for (var property in soundEntityMap) { + if(!soundEntityMap.hasOwnProperty(property)) { + // The current property is not a direct propert of soundEntityMap + continue; + } + var entity = property; + var soundProperties = soundEntityMap[entity]; + if (soundProperties.needsPlay) { + print("EBL NEEDS TO PLAY!") + Audio.playSound(soundProperties.sound, { + volume: soundProperties.volume, + position: soundProperties.position, + loop: soundProperties.loop + }); + soundEntityMap[entity].needsPlay = false; + } + } +} + +Script.update.connect(update); Messages.subscribe(MESSAGE_CHANNEL); Messages.messageReceived.connect(messageReceived); \ No newline at end of file diff --git a/examples/audioExamples/acAudioSearching/acAudioSearchCompatibleEntitySpawner.js b/examples/audioExamples/acAudioSearching/acAudioSearchCompatibleEntitySpawner.js index 7452f29845..187e6da38f 100644 --- a/examples/audioExamples/acAudioSearching/acAudioSearchCompatibleEntitySpawner.js +++ b/examples/audioExamples/acAudioSearching/acAudioSearchCompatibleEntitySpawner.js @@ -22,15 +22,15 @@ var SCRIPT_URL = Script.resolvePath("soundEntityScript.js?v1" + Math.random()); var userData = { soundKey: { url: "https://s3-us-west-1.amazonaws.com/hifi-content/eric/Sounds/dove.wav", - volume: 0.5, - loop: true + volume: 1.0, + loop: false } } var entityProps = { type: "Box", position: { - x: 0, + x: Math.random(), y: 0, z: 0 }, From 1bfe14c70e43f5e3f3081a823ba35d88e26efde5 Mon Sep 17 00:00:00 2001 From: ericrius1 Date: Tue, 2 Feb 2016 16:38:14 -0800 Subject: [PATCH 06/37] If sound is already downloaded, it's fetched from cache --- .../audioExamples/acAudioSearching/ACAudioSearchAndInject.js | 2 +- .../acAudioSearching/acAudioSearchCompatibleEntitySpawner.js | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/examples/audioExamples/acAudioSearching/ACAudioSearchAndInject.js b/examples/audioExamples/acAudioSearching/ACAudioSearchAndInject.js index b50eb48c37..66ab4211d6 100644 --- a/examples/audioExamples/acAudioSearching/ACAudioSearchAndInject.js +++ b/examples/audioExamples/acAudioSearching/ACAudioSearchAndInject.js @@ -40,6 +40,7 @@ print("EBL STARTING AC SCRIPT"); function messageReceived(channel, message, sender) { + print("EBL RECEIVED A MESSAGE FROM ENTITY: " + message); var entityID = JSON.parse(message).id; if (soundEntityMap[entityID]) { // We already have this entity in our sound map, so don't re-add @@ -47,7 +48,6 @@ function messageReceived(channel, message, sender) { } EntityViewer.queryOctree(); - print("EBL RECEIVED A MESSAGE FROM ENTITY: " + message); var soundData = getEntityCustomData(SOUND_DATA_KEY, entityID); print("SOUND DATA " + JSON.stringify(soundData)) if (soundData && soundData.url) { diff --git a/examples/audioExamples/acAudioSearching/acAudioSearchCompatibleEntitySpawner.js b/examples/audioExamples/acAudioSearching/acAudioSearchCompatibleEntitySpawner.js index 187e6da38f..5a61f04225 100644 --- a/examples/audioExamples/acAudioSearching/acAudioSearchCompatibleEntitySpawner.js +++ b/examples/audioExamples/acAudioSearching/acAudioSearchCompatibleEntitySpawner.js @@ -22,8 +22,8 @@ var SCRIPT_URL = Script.resolvePath("soundEntityScript.js?v1" + Math.random()); var userData = { soundKey: { url: "https://s3-us-west-1.amazonaws.com/hifi-content/eric/Sounds/dove.wav", - volume: 1.0, - loop: false + volume: 0.2, + loop: true } } From c26d7e61b51bc85a91ca5130d7d80c01fb4d4f83 Mon Sep 17 00:00:00 2001 From: ericrius1 Date: Tue, 2 Feb 2016 17:18:24 -0800 Subject: [PATCH 07/37] interval is working --- .../ACAudioSearchAndInject.js | 33 +++++++++++++------ .../acAudioSearchCompatibleEntitySpawner.js | 3 +- 2 files changed, 25 insertions(+), 11 deletions(-) diff --git a/examples/audioExamples/acAudioSearching/ACAudioSearchAndInject.js b/examples/audioExamples/acAudioSearching/ACAudioSearchAndInject.js index 66ab4211d6..9fcc6ccda5 100644 --- a/examples/audioExamples/acAudioSearching/ACAudioSearchAndInject.js +++ b/examples/audioExamples/acAudioSearching/ACAudioSearchAndInject.js @@ -33,7 +33,8 @@ Entities.setPacketsPerSecond(6000); var DEFAULT_SOUND_DATA = { volume: 0.5, - loop: false + loop: false, + interval: -1 // An interval of -1 means this sound only plays once (if it's non-looping) }; print("EBL STARTING AC SCRIPT"); @@ -55,8 +56,10 @@ function messageReceived(channel, message, sender) { url: soundData.url, volume: soundData.volume || DEFAULT_SOUND_DATA.volume, loop: soundData.loop || DEFAULT_SOUND_DATA.loop, - needsPlay: true, - position: Entities.getEntityProperties(entityID, "position").position + interval: soundData.interval || DEFAULT_SOUND_DATA.interval, + readyToPlay: true, + position: Entities.getEntityProperties(entityID, "position").position, + timeSinceLastPlay: 0 }; if (!soundUrls[soundData.url]) { // We need to download sound before we add it to our map @@ -75,23 +78,33 @@ function messageReceived(channel, message, sender) { } } -function update() { +function update(deltaTime) { // Go through each sound and play it if it needs to be played - for (var property in soundEntityMap) { - if(!soundEntityMap.hasOwnProperty(property)) { + for (var potentialEntity in soundEntityMap) { + if(!soundEntityMap.hasOwnProperty(potentialEntity)) { // The current property is not a direct propert of soundEntityMap continue; } - var entity = property; + var entity = potentialEntity; var soundProperties = soundEntityMap[entity]; - if (soundProperties.needsPlay) { + if (soundProperties.readyToPlay) { print("EBL NEEDS TO PLAY!") Audio.playSound(soundProperties.sound, { volume: soundProperties.volume, position: soundProperties.position, loop: soundProperties.loop - }); - soundEntityMap[entity].needsPlay = false; + }); + soundProperties.readyToPlay = false; + } else if(soundProperties.loop === false && soundProperties.interval !==-1) { + // We need to check all of our entities that are not looping but have an interval associated with them + // to see if it's time for them to play again + soundProperties.timeSinceLastPlay += deltaTime; + if (soundProperties.timeSinceLastPlay > soundProperties.interval) { + print ("EBL TIME TO PLAY AGAIN!"); + soundProperties.readyToPlay = true; + soundProperties.timeSinceLastPlay = 0; + } + } } } diff --git a/examples/audioExamples/acAudioSearching/acAudioSearchCompatibleEntitySpawner.js b/examples/audioExamples/acAudioSearching/acAudioSearchCompatibleEntitySpawner.js index 5a61f04225..1ddc75a5f7 100644 --- a/examples/audioExamples/acAudioSearching/acAudioSearchCompatibleEntitySpawner.js +++ b/examples/audioExamples/acAudioSearching/acAudioSearchCompatibleEntitySpawner.js @@ -23,7 +23,8 @@ var userData = { soundKey: { url: "https://s3-us-west-1.amazonaws.com/hifi-content/eric/Sounds/dove.wav", volume: 0.2, - loop: true + loop: false, + interval: 3 } } From e6a1300cd91711be0ad4896fb00ed2e934530806 Mon Sep 17 00:00:00 2001 From: ericrius1 Date: Tue, 2 Feb 2016 17:28:21 -0800 Subject: [PATCH 08/37] random interval spread --- .../ACAudioSearchAndInject.js | 26 +++++++++++++------ .../acAudioSearchCompatibleEntitySpawner.js | 3 ++- 2 files changed, 20 insertions(+), 9 deletions(-) diff --git a/examples/audioExamples/acAudioSearching/ACAudioSearchAndInject.js b/examples/audioExamples/acAudioSearching/ACAudioSearchAndInject.js index 9fcc6ccda5..81251e881d 100644 --- a/examples/audioExamples/acAudioSearching/ACAudioSearchAndInject.js +++ b/examples/audioExamples/acAudioSearching/ACAudioSearchAndInject.js @@ -34,13 +34,15 @@ Entities.setPacketsPerSecond(6000); var DEFAULT_SOUND_DATA = { volume: 0.5, loop: false, - interval: -1 // An interval of -1 means this sound only plays once (if it's non-looping) + interval: -1, // An interval of -1 means this sound only plays once (if it's non-looping) (In seconds) + intervalSpread: 0 // amount of randomness to add to the interval }; +var MIN_INTERVAL = 0.2; print("EBL STARTING AC SCRIPT"); function messageReceived(channel, message, sender) { - + print("EBL RECEIVED A MESSAGE FROM ENTITY: " + message); var entityID = JSON.parse(message).id; if (soundEntityMap[entityID]) { @@ -57,10 +59,15 @@ function messageReceived(channel, message, sender) { volume: soundData.volume || DEFAULT_SOUND_DATA.volume, loop: soundData.loop || DEFAULT_SOUND_DATA.loop, interval: soundData.interval || DEFAULT_SOUND_DATA.interval, + intervalSpread: soundData.intervalSpread || DEFAULT_SOUND_DATA.intervalSpread, readyToPlay: true, position: Entities.getEntityProperties(entityID, "position").position, timeSinceLastPlay: 0 }; + if (soundProperties.interval !== -1) { + soundProperties.currentInterval = soundProperties.interval + randFloat(-soundProperties.intervalSpread, soundProperties.intervalSpread); + soundProperties.currentInterval = Math.max(MIN_INTERVAL, soundProperties.currentInterval); + } if (!soundUrls[soundData.url]) { // We need to download sound before we add it to our map var sound = SoundCache.getSound(soundData.url); @@ -81,7 +88,7 @@ function messageReceived(channel, message, sender) { function update(deltaTime) { // Go through each sound and play it if it needs to be played for (var potentialEntity in soundEntityMap) { - if(!soundEntityMap.hasOwnProperty(potentialEntity)) { + if (!soundEntityMap.hasOwnProperty(potentialEntity)) { // The current property is not a direct propert of soundEntityMap continue; } @@ -93,16 +100,19 @@ function update(deltaTime) { volume: soundProperties.volume, position: soundProperties.position, loop: soundProperties.loop - }); - soundProperties.readyToPlay = false; - } else if(soundProperties.loop === false && soundProperties.interval !==-1) { + }); + soundProperties.readyToPlay = false; + } else if (soundProperties.loop === false && soundProperties.interval !== -1) { // We need to check all of our entities that are not looping but have an interval associated with them // to see if it's time for them to play again soundProperties.timeSinceLastPlay += deltaTime; - if (soundProperties.timeSinceLastPlay > soundProperties.interval) { - print ("EBL TIME TO PLAY AGAIN!"); + if (soundProperties.timeSinceLastPlay > soundProperties.currentInterval) { + print("EBL TIME TO PLAY AGAIN!"); soundProperties.readyToPlay = true; soundProperties.timeSinceLastPlay = 0; + // Now lets get our next current interval + soundProperties.currentInterval = soundProperties.interval + randFloat(-soundProperties.intervalSpread, soundProperties.intervalSpread); + soundProperties.currentInterval = Math.max(MIN_INTERVAL, soundProperties.currentInterval); } } diff --git a/examples/audioExamples/acAudioSearching/acAudioSearchCompatibleEntitySpawner.js b/examples/audioExamples/acAudioSearching/acAudioSearchCompatibleEntitySpawner.js index 1ddc75a5f7..05a9fcf09e 100644 --- a/examples/audioExamples/acAudioSearching/acAudioSearchCompatibleEntitySpawner.js +++ b/examples/audioExamples/acAudioSearching/acAudioSearchCompatibleEntitySpawner.js @@ -24,7 +24,8 @@ var userData = { url: "https://s3-us-west-1.amazonaws.com/hifi-content/eric/Sounds/dove.wav", volume: 0.2, loop: false, - interval: 3 + interval: 4, + intervalSpread: 3.5 } } From 89d235e2c2a9dc08901cb77626a22782fbee1da2 Mon Sep 17 00:00:00 2001 From: ericrius1 Date: Tue, 2 Feb 2016 18:09:26 -0800 Subject: [PATCH 09/37] First cut complete --- .../acAudioSearching/ACAudioSearchAndInject.js | 17 ++++++----------- .../acAudioSearchCompatibleEntitySpawner.js | 16 +++++----------- .../acAudioSearching/soundEntityScript.js | 15 ++++++++++----- 3 files changed, 21 insertions(+), 27 deletions(-) diff --git a/examples/audioExamples/acAudioSearching/ACAudioSearchAndInject.js b/examples/audioExamples/acAudioSearching/ACAudioSearchAndInject.js index 81251e881d..88bb17ca0e 100644 --- a/examples/audioExamples/acAudioSearching/ACAudioSearchAndInject.js +++ b/examples/audioExamples/acAudioSearching/ACAudioSearchAndInject.js @@ -14,12 +14,13 @@ Script.include("https://rawgit.com/highfidelity/hifi/master/examples/libraries/utils.js"); -var ENTITY_QUERY_INTERVAL = 2000; var SOUND_DATA_KEY = "soundKey"; var MESSAGE_CHANNEL = "Hifi-Sound-Entity"; -// Map of all sound entities in domain- key is entity id, value is data +// Map of all sound entities in domain- key is entity id, value is sound data var soundEntityMap = {}; +// Map of sound urls so a sound that's already been downloaded from one entity is not re-downloaded if +// another entity with same sound url is discovered var soundUrls = {}; EntityViewer.setPosition({ @@ -39,11 +40,8 @@ var DEFAULT_SOUND_DATA = { }; var MIN_INTERVAL = 0.2; -print("EBL STARTING AC SCRIPT"); - function messageReceived(channel, message, sender) { - print("EBL RECEIVED A MESSAGE FROM ENTITY: " + message); var entityID = JSON.parse(message).id; if (soundEntityMap[entityID]) { // We already have this entity in our sound map, so don't re-add @@ -52,7 +50,6 @@ function messageReceived(channel, message, sender) { EntityViewer.queryOctree(); var soundData = getEntityCustomData(SOUND_DATA_KEY, entityID); - print("SOUND DATA " + JSON.stringify(soundData)) if (soundData && soundData.url) { var soundProperties = { url: soundData.url, @@ -89,16 +86,16 @@ function update(deltaTime) { // Go through each sound and play it if it needs to be played for (var potentialEntity in soundEntityMap) { if (!soundEntityMap.hasOwnProperty(potentialEntity)) { - // The current property is not a direct propert of soundEntityMap + // The current property is not a direct propert of soundEntityMap so ignore it continue; } var entity = potentialEntity; var soundProperties = soundEntityMap[entity]; if (soundProperties.readyToPlay) { - print("EBL NEEDS TO PLAY!") + var newPosition = Entities.getEntityProperties(entity, "position").position Audio.playSound(soundProperties.sound, { volume: soundProperties.volume, - position: soundProperties.position, + position: newPosition, loop: soundProperties.loop }); soundProperties.readyToPlay = false; @@ -107,14 +104,12 @@ function update(deltaTime) { // to see if it's time for them to play again soundProperties.timeSinceLastPlay += deltaTime; if (soundProperties.timeSinceLastPlay > soundProperties.currentInterval) { - print("EBL TIME TO PLAY AGAIN!"); soundProperties.readyToPlay = true; soundProperties.timeSinceLastPlay = 0; // Now lets get our next current interval soundProperties.currentInterval = soundProperties.interval + randFloat(-soundProperties.intervalSpread, soundProperties.intervalSpread); soundProperties.currentInterval = Math.max(MIN_INTERVAL, soundProperties.currentInterval); } - } } } diff --git a/examples/audioExamples/acAudioSearching/acAudioSearchCompatibleEntitySpawner.js b/examples/audioExamples/acAudioSearching/acAudioSearchCompatibleEntitySpawner.js index 05a9fcf09e..3ac7d22211 100644 --- a/examples/audioExamples/acAudioSearching/acAudioSearchCompatibleEntitySpawner.js +++ b/examples/audioExamples/acAudioSearching/acAudioSearchCompatibleEntitySpawner.js @@ -17,15 +17,14 @@ Script.include("../../libraries/utils.js"); var SOUND_DATA_KEY = "soundKey"; var MESSAGE_CHANNEL = "Hifi-Sound-Entity"; -var SCRIPT_URL = Script.resolvePath("soundEntityScript.js?v1" + Math.random()); -//http://hifi-public.s3.amazonaws.com/ryan/Water_Lap_River_Edge_Gentle.L.wav +var SCRIPT_URL = Script.resolvePath("soundEntityScript.js"); var userData = { soundKey: { url: "https://s3-us-west-1.amazonaws.com/hifi-content/eric/Sounds/dove.wav", - volume: 0.2, + volume: 0.3, loop: false, interval: 4, - intervalSpread: 3.5 + intervalSpread: 2 } } @@ -50,16 +49,11 @@ var entityProps = { script: SCRIPT_URL } -var soundEntity1 = Entities.addEntity(entityProps); +var soundEntity = Entities.addEntity(entityProps); -userData.soundKey.url = "http://hifi-public.s3.amazonaws.com/ryan/demo/0619_Fireplace__Tree_B.L.wav"; -entityProps.userData = JSON.stringify(userData); -entityProps.position.x += 0.3 -//var soundEntity2 = Entities.addEntity(entityProps); function cleanup() { - Entities.deleteEntity(soundEntity1); - //Entities.deleteEntity(soundEntity2); + Entities.deleteEntity(soundEntity); } Script.scriptEnding.connect(cleanup); \ No newline at end of file diff --git a/examples/audioExamples/acAudioSearching/soundEntityScript.js b/examples/audioExamples/acAudioSearching/soundEntityScript.js index 702dc94243..0f466c2c2b 100644 --- a/examples/audioExamples/acAudioSearching/soundEntityScript.js +++ b/examples/audioExamples/acAudioSearching/soundEntityScript.js @@ -4,7 +4,7 @@ // Created by Eric Levin on 2/2/16. // Copyright 2016 High Fidelity, Inc. // -// This entity script sends a message meant for a running AC script on preload +// This entity script sends a message meant for a running AC script on its preload // Distributed under the Apache License, Version 2.0. // See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html // @@ -18,13 +18,18 @@ this.MESSAGE_CHANNEL = "Hifi-Sound-Entity"; }; - SoundEntity.prototype = { + SoundEntity.prototype = { preload: function(entityID) { this.entityID = entityID; - print("EBL SENDING MESSAGE " + this.entityID); - Messages.sendMessage(this.MESSAGE_CHANNEL, JSON.stringify({id: this.entityID})); + Script.setTimeout(function() { + var soundData = getEntityCustomData("soundKey", _this.entityID); + // Just a hack for now until bug https://app.asana.com/0/26225263936266/86767805352289 is fixed + Messages.sendMessage(_this.MESSAGE_CHANNEL, JSON.stringify({ + id: _this.entityID + })); + }, 1000); }, }; // entity scripts always need to return a newly constructed object of our type return new SoundEntity(); -}); +}); \ No newline at end of file From a95176be8fc25a58e0d272119a1efc874b110cc3 Mon Sep 17 00:00:00 2001 From: ericrius1 Date: Tue, 2 Feb 2016 18:22:39 -0800 Subject: [PATCH 10/37] added 0 prefix to nums --- .../acAudioSearchCompatibleEntitySpawner.js | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/examples/audioExamples/acAudioSearching/acAudioSearchCompatibleEntitySpawner.js b/examples/audioExamples/acAudioSearching/acAudioSearchCompatibleEntitySpawner.js index 3ac7d22211..6264c62964 100644 --- a/examples/audioExamples/acAudioSearching/acAudioSearchCompatibleEntitySpawner.js +++ b/examples/audioExamples/acAudioSearching/acAudioSearchCompatibleEntitySpawner.js @@ -41,9 +41,9 @@ var entityProps = { blue: 200 }, dimensions: { - x: .1, - y: .1, - z: .1 + x: 0.1, + y: 0.1, + z: 0.1 }, userData: JSON.stringify(userData), script: SCRIPT_URL From 03f90c20706f1c54e5ddff1d6c2baf9a507f5506 Mon Sep 17 00:00:00 2001 From: ericrius1 Date: Wed, 3 Feb 2016 12:11:09 -0800 Subject: [PATCH 11/37] fixed potential bug --- .../acAudioSearching/ACAudioSearchAndInject.js | 12 +++++++++++- .../acAudioSearchCompatibleEntitySpawner.js | 2 +- .../acAudioSearching/soundEntityScript.js | 3 ++- 3 files changed, 14 insertions(+), 3 deletions(-) diff --git a/examples/audioExamples/acAudioSearching/ACAudioSearchAndInject.js b/examples/audioExamples/acAudioSearching/ACAudioSearchAndInject.js index 88bb17ca0e..0b3aab0b84 100644 --- a/examples/audioExamples/acAudioSearching/ACAudioSearchAndInject.js +++ b/examples/audioExamples/acAudioSearching/ACAudioSearchAndInject.js @@ -41,7 +41,7 @@ var DEFAULT_SOUND_DATA = { var MIN_INTERVAL = 0.2; function messageReceived(channel, message, sender) { - + print("EBL MESSAGE RECIEVED"); var entityID = JSON.parse(message).id; if (soundEntityMap[entityID]) { // We already have this entity in our sound map, so don't re-add @@ -49,7 +49,15 @@ function messageReceived(channel, message, sender) { } EntityViewer.queryOctree(); + Script.setTimeout(function() { + handleIncomingEntity(entityID); + }, 2000); + +} + +function handleIncomingEntity(entityID) { var soundData = getEntityCustomData(SOUND_DATA_KEY, entityID); + print("SOUND DATA " + JSON.stringify(soundData)); if (soundData && soundData.url) { var soundProperties = { url: soundData.url, @@ -80,6 +88,7 @@ function messageReceived(channel, message, sender) { soundEntityMap[entityID] = soundProperties; } } + } function update(deltaTime) { @@ -93,6 +102,7 @@ function update(deltaTime) { var soundProperties = soundEntityMap[entity]; if (soundProperties.readyToPlay) { var newPosition = Entities.getEntityProperties(entity, "position").position + print("EBL SHOULD BE PLAYING SOUND!") Audio.playSound(soundProperties.sound, { volume: soundProperties.volume, position: newPosition, diff --git a/examples/audioExamples/acAudioSearching/acAudioSearchCompatibleEntitySpawner.js b/examples/audioExamples/acAudioSearching/acAudioSearchCompatibleEntitySpawner.js index 6264c62964..876f5e6461 100644 --- a/examples/audioExamples/acAudioSearching/acAudioSearchCompatibleEntitySpawner.js +++ b/examples/audioExamples/acAudioSearching/acAudioSearchCompatibleEntitySpawner.js @@ -17,7 +17,7 @@ Script.include("../../libraries/utils.js"); var SOUND_DATA_KEY = "soundKey"; var MESSAGE_CHANNEL = "Hifi-Sound-Entity"; -var SCRIPT_URL = Script.resolvePath("soundEntityScript.js"); +var SCRIPT_URL = Script.resolvePath("soundEntityScript.js?v1" + Math.random()); var userData = { soundKey: { url: "https://s3-us-west-1.amazonaws.com/hifi-content/eric/Sounds/dove.wav", diff --git a/examples/audioExamples/acAudioSearching/soundEntityScript.js b/examples/audioExamples/acAudioSearching/soundEntityScript.js index 0f466c2c2b..b58a4cc0fe 100644 --- a/examples/audioExamples/acAudioSearching/soundEntityScript.js +++ b/examples/audioExamples/acAudioSearching/soundEntityScript.js @@ -24,10 +24,11 @@ Script.setTimeout(function() { var soundData = getEntityCustomData("soundKey", _this.entityID); // Just a hack for now until bug https://app.asana.com/0/26225263936266/86767805352289 is fixed + print("EBL SEND MESSAGE"); Messages.sendMessage(_this.MESSAGE_CHANNEL, JSON.stringify({ id: _this.entityID })); - }, 1000); + }, 2000); }, }; // entity scripts always need to return a newly constructed object of our type From e3fe20c818151163bcb3b9559eed32604cf67d85 Mon Sep 17 00:00:00 2001 From: ericrius1 Date: Wed, 3 Feb 2016 13:50:10 -0800 Subject: [PATCH 12/37] query octree right away --- .../ACAudioSearchAndInject.js | 1 + .../ACAudioSearchAndInject2.js | 48 +++++++++++++++++++ 2 files changed, 49 insertions(+) create mode 100644 examples/audioExamples/acAudioSearching/ACAudioSearchAndInject2.js diff --git a/examples/audioExamples/acAudioSearching/ACAudioSearchAndInject.js b/examples/audioExamples/acAudioSearching/ACAudioSearchAndInject.js index 0b3aab0b84..bafaead7db 100644 --- a/examples/audioExamples/acAudioSearching/ACAudioSearchAndInject.js +++ b/examples/audioExamples/acAudioSearching/ACAudioSearchAndInject.js @@ -39,6 +39,7 @@ var DEFAULT_SOUND_DATA = { intervalSpread: 0 // amount of randomness to add to the interval }; var MIN_INTERVAL = 0.2; +EntityViewer.queryOctree(); function messageReceived(channel, message, sender) { print("EBL MESSAGE RECIEVED"); diff --git a/examples/audioExamples/acAudioSearching/ACAudioSearchAndInject2.js b/examples/audioExamples/acAudioSearching/ACAudioSearchAndInject2.js new file mode 100644 index 0000000000..ada682e2a1 --- /dev/null +++ b/examples/audioExamples/acAudioSearching/ACAudioSearchAndInject2.js @@ -0,0 +1,48 @@ +// +// ACAudioSearchAndInject.js +// audio +// +// Created by Eric Levin 2/1/2016 +// Copyright 2016 High Fidelity, Inc. + +// This AC script constantly searches for entities with a special userData field that specifies audio settings, and then +// injects the sound with the specified URL with other specified settings (playback volume) or playback at interval, or random interval +// +// Distributed under the Apache License, Version 2.0. +// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html +// + +Script.include("https://rawgit.com/highfidelity/hifi/master/examples/libraries/utils.js"); + +var SOUND_DATA_KEY = "soundKey"; +var MESSAGE_CHANNEL = "Hifi-Sound-Entity"; + +// Map of all sound entities in domain- key is entity id, value is sound data +var soundEntityMap = {}; +// Map of sound urls so a sound that's already been downloaded from one entity is not re-downloaded if +// another entity with same sound url is discovered +var soundUrls = {}; + +Agent.isAvatar = true; + +EntityViewer.setPosition({ + x: 0, + y: 0, + z: 0 +}); + +EntityViewer.setKeyholeRadius(60000); +Entities.setPacketsPerSecond(6000); +EntityViewer.queryOctree(); + +var DEFAULT_SOUND_DATA = { + volume: 0.5, + loop: false, + interval: -1, // An interval of -1 means this sound only plays once (if it's non-looping) (In seconds) + intervalSpread: 0 // amount of randomness to add to the interval +}; +var MIN_INTERVAL = 0.2; + +var avatars = AvatarList.getAvatarIdentifiers(); +print("EBL AVATARS " + JSON.stringify(avatars)); + From 8591de4873d5b16eeed74b79dd7fed64536e860b Mon Sep 17 00:00:00 2001 From: ericrius1 Date: Thu, 4 Feb 2016 11:57:22 -0800 Subject: [PATCH 13/37] getting avatar position --- .../acAudioSearching/ACAudioSearchAndInject2.js | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/examples/audioExamples/acAudioSearching/ACAudioSearchAndInject2.js b/examples/audioExamples/acAudioSearching/ACAudioSearchAndInject2.js index ada682e2a1..73b7d5372b 100644 --- a/examples/audioExamples/acAudioSearching/ACAudioSearchAndInject2.js +++ b/examples/audioExamples/acAudioSearching/ACAudioSearchAndInject2.js @@ -43,6 +43,13 @@ var DEFAULT_SOUND_DATA = { }; var MIN_INTERVAL = 0.2; -var avatars = AvatarList.getAvatarIdentifiers(); -print("EBL AVATARS " + JSON.stringify(avatars)); + +// First, constantly query for avatars and get their position +Script.setTimeout(function() { + var avatars = AvatarList.getAvatarIdentifiers(); + var avatarID = avatars[0]; + var avatar = AvatarList.getAvatar(avatarID); + print(" EBL avatar Position " + JSON.stringify(avatar.position)); + +}, 2000); From c8704234b19dd866fe69ed3469fdd991a4a66f96 Mon Sep 17 00:00:00 2001 From: ericrius1 Date: Thu, 4 Feb 2016 16:19:23 -0800 Subject: [PATCH 14/37] basic setup for new design --- .../ACAudioSearchAndInject2.js | 104 +++++++++++++----- .../acAudioSearchCompatibleEntitySpawner2.js | 56 ++++++++++ 2 files changed, 135 insertions(+), 25 deletions(-) create mode 100644 examples/audioExamples/acAudioSearching/acAudioSearchCompatibleEntitySpawner2.js diff --git a/examples/audioExamples/acAudioSearching/ACAudioSearchAndInject2.js b/examples/audioExamples/acAudioSearching/ACAudioSearchAndInject2.js index 73b7d5372b..3a582365ee 100644 --- a/examples/audioExamples/acAudioSearching/ACAudioSearchAndInject2.js +++ b/examples/audioExamples/acAudioSearching/ACAudioSearchAndInject2.js @@ -1,5 +1,5 @@ // -// ACAudioSearchAndInject.js +// ACAudioSearchAndInject2.js // audio // // Created by Eric Levin 2/1/2016 @@ -15,26 +15,14 @@ Script.include("https://rawgit.com/highfidelity/hifi/master/examples/libraries/utils.js"); var SOUND_DATA_KEY = "soundKey"; -var MESSAGE_CHANNEL = "Hifi-Sound-Entity"; -// Map of all sound entities in domain- key is entity id, value is sound data -var soundEntityMap = {}; -// Map of sound urls so a sound that's already been downloaded from one entity is not re-downloaded if -// another entity with same sound url is discovered -var soundUrls = {}; +var QUERY_RADIUS = 5; + +EntityViewer.setKeyholeRadius(QUERY_RADIUS); +Entities.setPacketsPerSecond(6000); Agent.isAvatar = true; -EntityViewer.setPosition({ - x: 0, - y: 0, - z: 0 -}); - -EntityViewer.setKeyholeRadius(60000); -Entities.setPacketsPerSecond(6000); -EntityViewer.queryOctree(); - var DEFAULT_SOUND_DATA = { volume: 0.5, loop: false, @@ -43,13 +31,79 @@ var DEFAULT_SOUND_DATA = { }; var MIN_INTERVAL = 0.2; +print("EBL STARTING SCRIPT"); -// First, constantly query for avatars and get their position -Script.setTimeout(function() { - var avatars = AvatarList.getAvatarIdentifiers(); - var avatarID = avatars[0]; - var avatar = AvatarList.getAvatar(avatarID); - print(" EBL avatar Position " + JSON.stringify(avatar.position)); - -}, 2000); +function slowUpdate() { + var avatars = AvatarList.getAvatarIdentifiers(); + print("AVATARS LENGTH " + avatars.length); + for (var i = 0; i < avatars.length; i++) { + print("In loop"); + var avatar = AvatarList.getAvatar(avatars[i]); + EntityViewer.setPosition(avatar.position); + EntityViewer.queryOctree(); + Script.setTimeout(function() { + var entities = Entities.findEntities(avatar.position, QUERY_RADIUS); + print("EBL ENTITIES LENGTH " + entities.length); + }, 1000); + } +} +Script.setInterval(slowUpdate, 1000); +// Script.setInterval(function() { +// var avatars = AvatarList.getAvatarIdentifiers(); +// print("Checking avatar identifiers" + JSON.stringify(avatars)); +// }, 2000)// +// ACAudioSearchAndInject2.js +// audio +// +// Created by Eric Levin 2/1/2016 +// Copyright 2016 High Fidelity, Inc. + +// This AC script constantly searches for entities with a special userData field that specifies audio settings, and then +// injects the sound with the specified URL with other specified settings (playback volume) or playback at interval, or random interval +// +// Distributed under the Apache License, Version 2.0. +// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html +// + +Script.include("https://rawgit.com/highfidelity/hifi/master/examples/libraries/utils.js"); + +var SOUND_DATA_KEY = "soundKey"; + +var QUERY_RADIUS = 5; + +EntityViewer.setKeyholeRadius(QUERY_RADIUS); +Entities.setPacketsPerSecond(6000); + +Agent.isAvatar = true; + +var DEFAULT_SOUND_DATA = { + volume: 0.5, + loop: false, + interval: -1, // An interval of -1 means this sound only plays once (if it's non-looping) (In seconds) + intervalSpread: 0 // amount of randomness to add to the interval +}; +var MIN_INTERVAL = 0.2; + +print("EBL STARTING SCRIPT"); + +function slowUpdate() { + var avatars = AvatarList.getAvatarIdentifiers(); + print("AVATARS LENGTH " + avatars.length); + for (var i = 0; i < avatars.length; i++) { + print("In loop"); + var avatar = AvatarList.getAvatar(avatars[i]); + EntityViewer.setPosition(avatar.position); + EntityViewer.queryOctree(); + Script.setTimeout(function() { + var entities = Entities.findEntities(avatar.position, QUERY_RADIUS); + print("EBL ENTITIES LENGTH " + entities.length); + }, 1000); + } +} +Script.setInterval(slowUpdate, 1000); + +// Script.setInterval(function() { +// var avatars = AvatarList.getAvatarIdentifiers(); +// print("Checking avatar identifiers" + JSON.stringify(avatars)); +// }, 2000) \ No newline at end of file diff --git a/examples/audioExamples/acAudioSearching/acAudioSearchCompatibleEntitySpawner2.js b/examples/audioExamples/acAudioSearching/acAudioSearchCompatibleEntitySpawner2.js new file mode 100644 index 0000000000..6216f6e4b4 --- /dev/null +++ b/examples/audioExamples/acAudioSearching/acAudioSearchCompatibleEntitySpawner2.js @@ -0,0 +1,56 @@ +// +// acAudioSearchCompatibleEntitySpawner.js +// audio/acAudioSearching +// +// Created by Eric Levin 2/2/2016 +// Copyright 2016 High Fidelity, Inc. + +// This is a client script which spawns entities with a field in userData compatible with the AcAudioSearchAndInject script +// These entities specify data about the sound they want to play, such as url, volume, and whether to loop or not +// The position of the entity determines the position from which the sound plays from +// +// Distributed under the Apache License, Version 2.0. +// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html +// + +Script.include("../../libraries/utils.js"); + +var SOUND_DATA_KEY = "soundKey"; +var userData = { + soundKey: { + url: "https://s3-us-west-1.amazonaws.com/hifi-content/eric/Sounds/dove.wav", + volume: 0.3, + loop: false, + interval: 4, + intervalSpread: 2 + } +} + +var entityProps = { + type: "Box", + position: { + x: Math.random(), + y: 0, + z: 0 + }, + color: { + red: 200, + green: 10, + blue: 200 + }, + dimensions: { + x: 0.1, + y: 0.1, + z: 0.1 + }, + userData: JSON.stringify(userData) +} + +var soundEntity = Entities.addEntity(entityProps); + + +function cleanup() { + Entities.deleteEntity(soundEntity); +} + +Script.scriptEnding.connect(cleanup); \ No newline at end of file From 16af9b9e3165869e6717c879cb45cf6ae0c26d3a Mon Sep 17 00:00:00 2001 From: ericrius1 Date: Thu, 4 Feb 2016 17:12:25 -0800 Subject: [PATCH 15/37] deleting sound entity if it hasn't been around for a while --- .../ACAudioSearchAndInject2.js | 125 ++++++++---------- 1 file changed, 53 insertions(+), 72 deletions(-) diff --git a/examples/audioExamples/acAudioSearching/ACAudioSearchAndInject2.js b/examples/audioExamples/acAudioSearching/ACAudioSearchAndInject2.js index 3a582365ee..33a6e63ca7 100644 --- a/examples/audioExamples/acAudioSearching/ACAudioSearchAndInject2.js +++ b/examples/audioExamples/acAudioSearching/ACAudioSearchAndInject2.js @@ -1,16 +1,4 @@ // -// ACAudioSearchAndInject2.js -// audio -// -// Created by Eric Levin 2/1/2016 -// Copyright 2016 High Fidelity, Inc. - -// This AC script constantly searches for entities with a special userData field that specifies audio settings, and then -// injects the sound with the specified URL with other specified settings (playback volume) or playback at interval, or random interval -// -// Distributed under the Apache License, Version 2.0. -// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html -// Script.include("https://rawgit.com/highfidelity/hifi/master/examples/libraries/utils.js"); @@ -31,79 +19,72 @@ var DEFAULT_SOUND_DATA = { }; var MIN_INTERVAL = 0.2; -print("EBL STARTING SCRIPT"); +var UPDATE_TIME = 3000; +var EXPIRATION_TIME = 5000; -function slowUpdate() { - var avatars = AvatarList.getAvatarIdentifiers(); - print("AVATARS LENGTH " + avatars.length); - for (var i = 0; i < avatars.length; i++) { - print("In loop"); - var avatar = AvatarList.getAvatar(avatars[i]); - EntityViewer.setPosition(avatar.position); - EntityViewer.queryOctree(); - Script.setTimeout(function() { - var entities = Entities.findEntities(avatar.position, QUERY_RADIUS); - print("EBL ENTITIES LENGTH " + entities.length); - }, 1000); - } -} -Script.setInterval(slowUpdate, 1000); - -// Script.setInterval(function() { -// var avatars = AvatarList.getAvatarIdentifiers(); -// print("Checking avatar identifiers" + JSON.stringify(avatars)); -// }, 2000)// -// ACAudioSearchAndInject2.js -// audio -// -// Created by Eric Levin 2/1/2016 -// Copyright 2016 High Fidelity, Inc. - -// This AC script constantly searches for entities with a special userData field that specifies audio settings, and then -// injects the sound with the specified URL with other specified settings (playback volume) or playback at interval, or random interval -// -// Distributed under the Apache License, Version 2.0. -// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html -// - -Script.include("https://rawgit.com/highfidelity/hifi/master/examples/libraries/utils.js"); - -var SOUND_DATA_KEY = "soundKey"; - -var QUERY_RADIUS = 5; - -EntityViewer.setKeyholeRadius(QUERY_RADIUS); -Entities.setPacketsPerSecond(6000); - -Agent.isAvatar = true; - -var DEFAULT_SOUND_DATA = { - volume: 0.5, - loop: false, - interval: -1, // An interval of -1 means this sound only plays once (if it's non-looping) (In seconds) - intervalSpread: 0 // amount of randomness to add to the interval -}; -var MIN_INTERVAL = 0.2; +var soundEntityMap = {}; print("EBL STARTING SCRIPT"); function slowUpdate() { var avatars = AvatarList.getAvatarIdentifiers(); - print("AVATARS LENGTH " + avatars.length); for (var i = 0; i < avatars.length; i++) { - print("In loop"); var avatar = AvatarList.getAvatar(avatars[i]); EntityViewer.setPosition(avatar.position); EntityViewer.queryOctree(); Script.setTimeout(function() { var entities = Entities.findEntities(avatar.position, QUERY_RADIUS); - print("EBL ENTITIES LENGTH " + entities.length); + handleFoundSoundEntities(entities); }, 1000); } + handleActiveSoundEntities(); } -Script.setInterval(slowUpdate, 1000); -// Script.setInterval(function() { -// var avatars = AvatarList.getAvatarIdentifiers(); -// print("Checking avatar identifiers" + JSON.stringify(avatars)); -// }, 2000) \ No newline at end of file +function handleActiveSoundEntities() { + // Go through all our sound entities, if they have passed expiration time, remove them from map + for (var potentialSoundEntity in soundEntityMap) { + if (!soundEntityMap.hasOwnProperty(potentialSoundEntity)) { + // The current property is not a direct property of soundEntityMap so ignore it + continue; + } + var soundEntity = potentialSoundEntity; + var soundProperties = soundEntityMap[soundEntity]; + soundProperties.timeWithoutAvatarInRange += UPDATE_TIME; + if (soundProperties.timeWithoutAvatarInRange > EXPIRATION_TIME) { + // An avatar hasn't been within range of this sound entity recently, so remove it from map + print ("NO AVATARS HAVE BEEN AROUND FOR A WHILE SO REMOVE THIS SOUND FROM SOUNDMAP!"); + delete soundEntityMap[soundEntity]; + print("NEW MAP " + JSON.stringify(soundEntityMap)); + } + } +} + +function handleFoundSoundEntities(entities) { + entities.forEach(function(entity) { + var soundData = getEntityCustomData(SOUND_DATA_KEY, entity); + if (soundData && soundData.url) { + //check sound entities list- if it's not in, add it + if (!soundEntityMap[entity]) { + print("FOUND A NEW SOUND ENTITY!") + var soundProperties = { + url: soundData.url, + volume: soundData.volume || DEFAULT_SOUND_DATA.volume, + loop: soundData.loop || DEFAULT_SOUND_DATA.loop, + interval: soundData.interval || DEFAULT_SOUND_DATA.interval, + intervalSpread: soundData.intervalSpread || DEFAULT_SOUND_DATA.intervalSpread, + readyToPlay: true, + position: Entities.getEntityProperties(entity, "position").position, + timeSinceLastPlay: 0, + timeWithoutAvatarInRange: 0 + }; + + // If it's not in list, add it + soundEntityMap[entity] = soundProperties; + } else { + //If this sound is in our map already, we want to reset timeWithoutAvatarInRange + soundEntityMap[entity].timeWithoutAvatarInRange = 0; + } + } + }); +} +Script.setInterval(slowUpdate, UPDATE_TIME); \ No newline at end of file From f6a091b941807a8559772fb05e7eb5c653602201 Mon Sep 17 00:00:00 2001 From: ericrius1 Date: Thu, 4 Feb 2016 17:41:52 -0800 Subject: [PATCH 16/37] basic of new design working --- .../ACAudioSearchAndInject2.js | 54 ++++++++++++++++--- .../acAudioSearchCompatibleEntitySpawner2.js | 4 +- 2 files changed, 49 insertions(+), 9 deletions(-) diff --git a/examples/audioExamples/acAudioSearching/ACAudioSearchAndInject2.js b/examples/audioExamples/acAudioSearching/ACAudioSearchAndInject2.js index 33a6e63ca7..0a251d1e5b 100644 --- a/examples/audioExamples/acAudioSearching/ACAudioSearchAndInject2.js +++ b/examples/audioExamples/acAudioSearching/ACAudioSearchAndInject2.js @@ -17,12 +17,13 @@ var DEFAULT_SOUND_DATA = { interval: -1, // An interval of -1 means this sound only plays once (if it's non-looping) (In seconds) intervalSpread: 0 // amount of randomness to add to the interval }; -var MIN_INTERVAL = 0.2; +var MIN_PLAY_INTERVAL = 0.2; -var UPDATE_TIME = 3000; -var EXPIRATION_TIME = 5000; +var UPDATE_TIME = 100; +var EXPIRATION_TIME = 5000; var soundEntityMap = {}; +var soundUrls = {}; print("EBL STARTING SCRIPT"); @@ -52,10 +53,32 @@ function handleActiveSoundEntities() { soundProperties.timeWithoutAvatarInRange += UPDATE_TIME; if (soundProperties.timeWithoutAvatarInRange > EXPIRATION_TIME) { // An avatar hasn't been within range of this sound entity recently, so remove it from map - print ("NO AVATARS HAVE BEEN AROUND FOR A WHILE SO REMOVE THIS SOUND FROM SOUNDMAP!"); + print("NO AVATARS HAVE BEEN AROUND FOR A WHILE SO REMOVE THIS SOUND FROM SOUNDMAP!"); delete soundEntityMap[soundEntity]; print("NEW MAP " + JSON.stringify(soundEntityMap)); - } + } else { + // If this sound hasn't expired yet, we want to potentially play it! + if (soundProperties.readyToPlay) { + var newPosition = Entities.getEntityProperties(soundEntity, "position").position; + Audio.playSound(soundProperties.sound, { + volume: soundProperties.volume, + position: newPosition, + loop: soundProperties.loop + }); + soundProperties.readyToPlay = false; + } else if (soundProperties.loop === false && soundProperties.interval !== -1) { + // We need to check all of our entities that are not looping but have an interval associated with them + // to see if it's time for them to play again + soundProperties.timeSinceLastPlay += UPDATE_TIME; + if (soundProperties.timeSinceLastPlay > soundProperties.currentInterval) { + soundProperties.readyToPlay = true; + soundProperties.timeSinceLastPlay = 0; + // Now let's get our new current interval + soundProperties.currentInterval = soundProperties.interval + randFloat(-soundProperties.intervalSpread, soundProperties.intervalSpread); + soundProperties.currentInterval = Math.max(MIN_PLAY_INTERVAL, soundProperties.currentInterval); + } + } + } } } @@ -78,8 +101,25 @@ function handleFoundSoundEntities(entities) { timeWithoutAvatarInRange: 0 }; - // If it's not in list, add it - soundEntityMap[entity] = soundProperties; + if (soundProperties.interval !== -1) { + soundProperties.currentInterval = soundProperties.interval + randFloat(-soundProperties.intervalSpread, soundProperties.intervalSpread); + soundProperties.currentInterval = Math.max(MIN_PLAY_INTERVAL, soundProperties.currentInterval); + } + + if (!soundUrls[soundData.url]) { + // We need to download sound before we add it to our map + var sound = SoundCache.getSound(soundData.url); + soundUrls[soundData.url] = sound; + // Only add it to map once it's downloaded + sound.ready.connect(function() { + soundProperties.sound = sound; + soundEntityMap[entity] = soundProperties; + }); + } else { + // We already have sound downloaded, so just add it to map right away + soundProperties.sound = soundUrls[soundData.url]; + soundEntityMap[entity] = soundProperties; + } } else { //If this sound is in our map already, we want to reset timeWithoutAvatarInRange soundEntityMap[entity].timeWithoutAvatarInRange = 0; diff --git a/examples/audioExamples/acAudioSearching/acAudioSearchCompatibleEntitySpawner2.js b/examples/audioExamples/acAudioSearching/acAudioSearchCompatibleEntitySpawner2.js index 6216f6e4b4..dce1cda54f 100644 --- a/examples/audioExamples/acAudioSearching/acAudioSearchCompatibleEntitySpawner2.js +++ b/examples/audioExamples/acAudioSearching/acAudioSearchCompatibleEntitySpawner2.js @@ -21,8 +21,8 @@ var userData = { url: "https://s3-us-west-1.amazonaws.com/hifi-content/eric/Sounds/dove.wav", volume: 0.3, loop: false, - interval: 4, - intervalSpread: 2 + interval: 2000, + intervalSpread: 1000 } } From 9b0e20d82b2236ff21af6aeeff05038847e8af22 Mon Sep 17 00:00:00 2001 From: ericrius1 Date: Thu, 4 Feb 2016 17:57:25 -0800 Subject: [PATCH 17/37] stopping sound injector if sound was looping --- .../ACAudioSearchAndInject2.js | 27 ++++++++++++++----- .../acAudioSearchCompatibleEntitySpawner2.js | 2 +- 2 files changed, 21 insertions(+), 8 deletions(-) diff --git a/examples/audioExamples/acAudioSearching/ACAudioSearchAndInject2.js b/examples/audioExamples/acAudioSearching/ACAudioSearchAndInject2.js index 0a251d1e5b..0ad0740310 100644 --- a/examples/audioExamples/acAudioSearching/ACAudioSearchAndInject2.js +++ b/examples/audioExamples/acAudioSearching/ACAudioSearchAndInject2.js @@ -19,7 +19,7 @@ var DEFAULT_SOUND_DATA = { }; var MIN_PLAY_INTERVAL = 0.2; -var UPDATE_TIME = 100; +var UPDATE_TIME = 2000; var EXPIRATION_TIME = 5000; var soundEntityMap = {}; @@ -54,17 +54,28 @@ function handleActiveSoundEntities() { if (soundProperties.timeWithoutAvatarInRange > EXPIRATION_TIME) { // An avatar hasn't been within range of this sound entity recently, so remove it from map print("NO AVATARS HAVE BEEN AROUND FOR A WHILE SO REMOVE THIS SOUND FROM SOUNDMAP!"); + // If the sound was looping, make sure to stop playing it + if (soundProperties.loop) { + print ("STOP SOUND INJECTOR!!"); + soundProperties.soundInjector.stop(); + } + + delete soundEntityMap[soundEntity]; print("NEW MAP " + JSON.stringify(soundEntityMap)); } else { // If this sound hasn't expired yet, we want to potentially play it! if (soundProperties.readyToPlay) { var newPosition = Entities.getEntityProperties(soundEntity, "position").position; - Audio.playSound(soundProperties.sound, { - volume: soundProperties.volume, - position: newPosition, - loop: soundProperties.loop - }); + if (!soundProperties.soundInjector) { + soundProperties.soundInjector = Audio.playSound(soundProperties.sound, { + volume: soundProperties.volume, + position: newPosition, + loop: soundProperties.loop + }); + } else { + soundProperties.soundInjector.restart(); + } soundProperties.readyToPlay = false; } else if (soundProperties.loop === false && soundProperties.interval !== -1) { // We need to check all of our entities that are not looping but have an interval associated with them @@ -82,6 +93,7 @@ function handleActiveSoundEntities() { } } + function handleFoundSoundEntities(entities) { entities.forEach(function(entity) { var soundData = getEntityCustomData(SOUND_DATA_KEY, entity); @@ -121,7 +133,8 @@ function handleFoundSoundEntities(entities) { soundEntityMap[entity] = soundProperties; } } else { - //If this sound is in our map already, we want to reset timeWithoutAvatarInRange + //If this sound is in our map already, we want to reset timeWithoutAvatarInRange + // Also we want to check to see if the entity has been updated with new sound data- if so we want to update! soundEntityMap[entity].timeWithoutAvatarInRange = 0; } } diff --git a/examples/audioExamples/acAudioSearching/acAudioSearchCompatibleEntitySpawner2.js b/examples/audioExamples/acAudioSearching/acAudioSearchCompatibleEntitySpawner2.js index dce1cda54f..4d9064c3a7 100644 --- a/examples/audioExamples/acAudioSearching/acAudioSearchCompatibleEntitySpawner2.js +++ b/examples/audioExamples/acAudioSearching/acAudioSearchCompatibleEntitySpawner2.js @@ -20,7 +20,7 @@ var userData = { soundKey: { url: "https://s3-us-west-1.amazonaws.com/hifi-content/eric/Sounds/dove.wav", volume: 0.3, - loop: false, + loop: true, interval: 2000, intervalSpread: 1000 } From aa49db9992f04b9eecd93e1c561f84d5c5acef1e Mon Sep 17 00:00:00 2001 From: ericrius1 Date: Thu, 4 Feb 2016 19:21:12 -0800 Subject: [PATCH 18/37] updating sound volume --- .../ACAudioSearchAndInject2.js | 20 +++++++++++++++++++ 1 file changed, 20 insertions(+) diff --git a/examples/audioExamples/acAudioSearching/ACAudioSearchAndInject2.js b/examples/audioExamples/acAudioSearching/ACAudioSearchAndInject2.js index 0ad0740310..94d4213840 100644 --- a/examples/audioExamples/acAudioSearching/ACAudioSearchAndInject2.js +++ b/examples/audioExamples/acAudioSearching/ACAudioSearchAndInject2.js @@ -68,6 +68,7 @@ function handleActiveSoundEntities() { if (soundProperties.readyToPlay) { var newPosition = Entities.getEntityProperties(soundEntity, "position").position; if (!soundProperties.soundInjector) { + print("SOUND VOLUME " + soundProperties.volume) soundProperties.soundInjector = Audio.playSound(soundProperties.sound, { volume: soundProperties.volume, position: newPosition, @@ -136,8 +137,27 @@ function handleFoundSoundEntities(entities) { //If this sound is in our map already, we want to reset timeWithoutAvatarInRange // Also we want to check to see if the entity has been updated with new sound data- if so we want to update! soundEntityMap[entity].timeWithoutAvatarInRange = 0; + checkForSoundPropertyChanges(soundEntityMap[entity], soundData); } } }); } + +function checkForSoundPropertyChanges(currentProps, newProps) { + var needsUpdate = false; + if(currentProps.volume !== newProps.volume) { + print("VOLUME CHANGED!!"); + currentProps.volume = newProps.volume; + needsUpdate = true; + } + if (needsUpdate && currentProps.loop) { + print ("LOOP CHANGED!"); + currentProps.loop = newProps.loop; + // If we were looping we need to stop that so new changes are applied + currentProps.soundInjector.stop(); + currentProps.soundInjector = null; + currentProps.readyToPlay = true; + } + +} Script.setInterval(slowUpdate, UPDATE_TIME); \ No newline at end of file From 355f60f0888c0dd244946ce86ef0e1d31a7b5ca5 Mon Sep 17 00:00:00 2001 From: ericrius1 Date: Fri, 5 Feb 2016 11:07:21 -0800 Subject: [PATCH 19/37] Not adding deleted avatars to the list of avatars to use for querying --- .../ACAudioSearchAndInject2.js | 44 +++++++++++++++---- .../acAudioSearchCompatibleEntitySpawner2.js | 4 +- 2 files changed, 37 insertions(+), 11 deletions(-) diff --git a/examples/audioExamples/acAudioSearching/ACAudioSearchAndInject2.js b/examples/audioExamples/acAudioSearching/ACAudioSearchAndInject2.js index 94d4213840..d0d0122cb9 100644 --- a/examples/audioExamples/acAudioSearching/ACAudioSearchAndInject2.js +++ b/examples/audioExamples/acAudioSearching/ACAudioSearchAndInject2.js @@ -20,7 +20,7 @@ var DEFAULT_SOUND_DATA = { var MIN_PLAY_INTERVAL = 0.2; var UPDATE_TIME = 2000; -var EXPIRATION_TIME = 5000; +var EXPIRATION_TIME = 7000; var soundEntityMap = {}; var soundUrls = {}; @@ -29,9 +29,15 @@ print("EBL STARTING SCRIPT"); function slowUpdate() { var avatars = AvatarList.getAvatarIdentifiers(); + print("CURRENT AVATAR LIST: " + JSON.stringify(avatars)); for (var i = 0; i < avatars.length; i++) { var avatar = AvatarList.getAvatar(avatars[i]); - EntityViewer.setPosition(avatar.position); + var avatarPosition = avatar.position; + if (!avatarPosition) { + print("EBL This avatars been DELETED *******! Don't add it to list"); + continue; + } + EntityViewer.setPosition(avatarPosition); EntityViewer.queryOctree(); Script.setTimeout(function() { var entities = Entities.findEntities(avatar.position, QUERY_RADIUS); @@ -56,7 +62,7 @@ function handleActiveSoundEntities() { print("NO AVATARS HAVE BEEN AROUND FOR A WHILE SO REMOVE THIS SOUND FROM SOUNDMAP!"); // If the sound was looping, make sure to stop playing it if (soundProperties.loop) { - print ("STOP SOUND INJECTOR!!"); + print("STOP SOUND INJECTOR!!"); soundProperties.soundInjector.stop(); } @@ -68,7 +74,7 @@ function handleActiveSoundEntities() { if (soundProperties.readyToPlay) { var newPosition = Entities.getEntityProperties(soundEntity, "position").position; if (!soundProperties.soundInjector) { - print("SOUND VOLUME " + soundProperties.volume) + print("PLAY SOUND! SOUND VOLUME " + soundProperties.volume) soundProperties.soundInjector = Audio.playSound(soundProperties.sound, { volume: soundProperties.volume, position: newPosition, @@ -78,7 +84,7 @@ function handleActiveSoundEntities() { soundProperties.soundInjector.restart(); } soundProperties.readyToPlay = false; - } else if (soundProperties.loop === false && soundProperties.interval !== -1) { + } else if (soundProperties.sound && soundProperties.loop === false && soundProperties.interval !== -1) { // We need to check all of our entities that are not looping but have an interval associated with them // to see if it's time for them to play again soundProperties.timeSinceLastPlay += UPDATE_TIME; @@ -108,7 +114,7 @@ function handleFoundSoundEntities(entities) { loop: soundData.loop || DEFAULT_SOUND_DATA.loop, interval: soundData.interval || DEFAULT_SOUND_DATA.interval, intervalSpread: soundData.intervalSpread || DEFAULT_SOUND_DATA.intervalSpread, - readyToPlay: true, + readyToPlay: false, position: Entities.getEntityProperties(entity, "position").position, timeSinceLastPlay: 0, timeWithoutAvatarInRange: 0 @@ -119,18 +125,22 @@ function handleFoundSoundEntities(entities) { soundProperties.currentInterval = Math.max(MIN_PLAY_INTERVAL, soundProperties.currentInterval); } + soundEntityMap[entity] = soundProperties; if (!soundUrls[soundData.url]) { // We need to download sound before we add it to our map var sound = SoundCache.getSound(soundData.url); - soundUrls[soundData.url] = sound; // Only add it to map once it's downloaded + soundUrls[soundData.url] = sound; sound.ready.connect(function() { + print("ADD TO MAP!") soundProperties.sound = sound; + soundProperties.readyToPlay = true; soundEntityMap[entity] = soundProperties; }); } else { // We already have sound downloaded, so just add it to map right away soundProperties.sound = soundUrls[soundData.url]; + soundProperties.readyToPlay = true; soundEntityMap[entity] = soundProperties; } } else { @@ -145,15 +155,31 @@ function handleFoundSoundEntities(entities) { function checkForSoundPropertyChanges(currentProps, newProps) { var needsUpdate = false; - if(currentProps.volume !== newProps.volume) { + if (currentProps.volume !== newProps.volume) { print("VOLUME CHANGED!!"); currentProps.volume = newProps.volume; needsUpdate = true; } + if (currentProps.url !== newProps.url) { + currentProps.url = newProps.url; + if (!soundUrls[currentProps.url]) { + var sound = SoundCache.getSound(currentProps.url); + currentProps.sound = null; + currentProps.readyToPlay = false; + sound.ready.connect(function() { + print("Ready to play new sound!") + currentProps.soundInjector.restart(); + currentProps.soundInjector.stop(); + currentProps.sound = sound; + currentProps.soundInjector = null; + }); + } + } if (needsUpdate && currentProps.loop) { - print ("LOOP CHANGED!"); + print("LOOP CHANGED!"); currentProps.loop = newProps.loop; // If we were looping we need to stop that so new changes are applied + currentProps.soundInjector.restart(); currentProps.soundInjector.stop(); currentProps.soundInjector = null; currentProps.readyToPlay = true; diff --git a/examples/audioExamples/acAudioSearching/acAudioSearchCompatibleEntitySpawner2.js b/examples/audioExamples/acAudioSearching/acAudioSearchCompatibleEntitySpawner2.js index 4d9064c3a7..8fcb1ad02f 100644 --- a/examples/audioExamples/acAudioSearching/acAudioSearchCompatibleEntitySpawner2.js +++ b/examples/audioExamples/acAudioSearching/acAudioSearchCompatibleEntitySpawner2.js @@ -14,11 +14,11 @@ // Script.include("../../libraries/utils.js"); - +// http://hifi-public.s3.amazonaws.com/ryan/demo/0619_Fireplace__Tree_B.L.wav var SOUND_DATA_KEY = "soundKey"; var userData = { soundKey: { - url: "https://s3-us-west-1.amazonaws.com/hifi-content/eric/Sounds/dove.wav", + url: "https://s3-us-west-1.amazonaws.com/hifi-content/eric/Sounds/dove2.wav", volume: 0.3, loop: true, interval: 2000, From 120c5ac370b375c06e7ad4313c07be4d449de372 Mon Sep 17 00:00:00 2001 From: ericrius1 Date: Fri, 5 Feb 2016 13:35:45 -0800 Subject: [PATCH 20/37] Able to switch url sounds --- .../ACAudioSearchAndInject2.js | 42 +++++++++---------- 1 file changed, 20 insertions(+), 22 deletions(-) diff --git a/examples/audioExamples/acAudioSearching/ACAudioSearchAndInject2.js b/examples/audioExamples/acAudioSearching/ACAudioSearchAndInject2.js index d0d0122cb9..dfc1527b1b 100644 --- a/examples/audioExamples/acAudioSearching/ACAudioSearchAndInject2.js +++ b/examples/audioExamples/acAudioSearching/ACAudioSearchAndInject2.js @@ -29,7 +29,6 @@ print("EBL STARTING SCRIPT"); function slowUpdate() { var avatars = AvatarList.getAvatarIdentifiers(); - print("CURRENT AVATAR LIST: " + JSON.stringify(avatars)); for (var i = 0; i < avatars.length; i++) { var avatar = AvatarList.getAvatar(avatars[i]); var avatarPosition = avatar.position; @@ -57,30 +56,26 @@ function handleActiveSoundEntities() { var soundEntity = potentialSoundEntity; var soundProperties = soundEntityMap[soundEntity]; soundProperties.timeWithoutAvatarInRange += UPDATE_TIME; - if (soundProperties.timeWithoutAvatarInRange > EXPIRATION_TIME) { + if (soundProperties.timeWithoutAvatarInRange > EXPIRATION_TIME && soundProperties.soundInjector) { // An avatar hasn't been within range of this sound entity recently, so remove it from map print("NO AVATARS HAVE BEEN AROUND FOR A WHILE SO REMOVE THIS SOUND FROM SOUNDMAP!"); - // If the sound was looping, make sure to stop playing it - if (soundProperties.loop) { - print("STOP SOUND INJECTOR!!"); - soundProperties.soundInjector.stop(); - } - - + soundProperties.soundInjector.stop(); delete soundEntityMap[soundEntity]; - print("NEW MAP " + JSON.stringify(soundEntityMap)); - } else { + } else if(soundProperties.isDownloaded) { + print("WERE DOWNLOADED"); // If this sound hasn't expired yet, we want to potentially play it! if (soundProperties.readyToPlay) { + print("WERE READY TO PLAY") var newPosition = Entities.getEntityProperties(soundEntity, "position").position; if (!soundProperties.soundInjector) { - print("PLAY SOUND! SOUND VOLUME " + soundProperties.volume) + print("PLAY SOUND!"); soundProperties.soundInjector = Audio.playSound(soundProperties.sound, { volume: soundProperties.volume, position: newPosition, loop: soundProperties.loop }); } else { + print ("RESTART INJECTOR!") soundProperties.soundInjector.restart(); } soundProperties.readyToPlay = false; @@ -88,6 +83,7 @@ function handleActiveSoundEntities() { // We need to check all of our entities that are not looping but have an interval associated with them // to see if it's time for them to play again soundProperties.timeSinceLastPlay += UPDATE_TIME; + print("INCREMENT TIME SINCE LAST PLAY") if (soundProperties.timeSinceLastPlay > soundProperties.currentInterval) { soundProperties.readyToPlay = true; soundProperties.timeSinceLastPlay = 0; @@ -117,7 +113,8 @@ function handleFoundSoundEntities(entities) { readyToPlay: false, position: Entities.getEntityProperties(entity, "position").position, timeSinceLastPlay: 0, - timeWithoutAvatarInRange: 0 + timeWithoutAvatarInRange: 0, + isDownloaded: false }; if (soundProperties.interval !== -1) { @@ -135,6 +132,7 @@ function handleFoundSoundEntities(entities) { print("ADD TO MAP!") soundProperties.sound = sound; soundProperties.readyToPlay = true; + soundProperties.isDownloaded = true; soundEntityMap[entity] = soundProperties; }); } else { @@ -162,28 +160,28 @@ function checkForSoundPropertyChanges(currentProps, newProps) { } if (currentProps.url !== newProps.url) { currentProps.url = newProps.url; + currentProps.sound = null; if (!soundUrls[currentProps.url]) { var sound = SoundCache.getSound(currentProps.url); - currentProps.sound = null; - currentProps.readyToPlay = false; + currentProps.isDownloaded = false; sound.ready.connect(function() { print("Ready to play new sound!") - currentProps.soundInjector.restart(); - currentProps.soundInjector.stop(); currentProps.sound = sound; - currentProps.soundInjector = null; + currentProps.isDownloaded = true; }); + } else { + currentProps.sound = sound; } + needsUpdate = true; } - if (needsUpdate && currentProps.loop) { - print("LOOP CHANGED!"); - currentProps.loop = newProps.loop; + if (needsUpdate) { + print("UPDATING!"); // If we were looping we need to stop that so new changes are applied - currentProps.soundInjector.restart(); currentProps.soundInjector.stop(); currentProps.soundInjector = null; currentProps.readyToPlay = true; } } + Script.setInterval(slowUpdate, UPDATE_TIME); \ No newline at end of file From a65c86923997155e37abb6593b9676f46f931e57 Mon Sep 17 00:00:00 2001 From: ericrius1 Date: Fri, 5 Feb 2016 13:36:31 -0800 Subject: [PATCH 21/37] removed commenting --- .../acAudioSearching/ACAudioSearchAndInject2.js | 11 ----------- 1 file changed, 11 deletions(-) diff --git a/examples/audioExamples/acAudioSearching/ACAudioSearchAndInject2.js b/examples/audioExamples/acAudioSearching/ACAudioSearchAndInject2.js index dfc1527b1b..974bfb085d 100644 --- a/examples/audioExamples/acAudioSearching/ACAudioSearchAndInject2.js +++ b/examples/audioExamples/acAudioSearching/ACAudioSearchAndInject2.js @@ -58,24 +58,19 @@ function handleActiveSoundEntities() { soundProperties.timeWithoutAvatarInRange += UPDATE_TIME; if (soundProperties.timeWithoutAvatarInRange > EXPIRATION_TIME && soundProperties.soundInjector) { // An avatar hasn't been within range of this sound entity recently, so remove it from map - print("NO AVATARS HAVE BEEN AROUND FOR A WHILE SO REMOVE THIS SOUND FROM SOUNDMAP!"); soundProperties.soundInjector.stop(); delete soundEntityMap[soundEntity]; } else if(soundProperties.isDownloaded) { - print("WERE DOWNLOADED"); // If this sound hasn't expired yet, we want to potentially play it! if (soundProperties.readyToPlay) { - print("WERE READY TO PLAY") var newPosition = Entities.getEntityProperties(soundEntity, "position").position; if (!soundProperties.soundInjector) { - print("PLAY SOUND!"); soundProperties.soundInjector = Audio.playSound(soundProperties.sound, { volume: soundProperties.volume, position: newPosition, loop: soundProperties.loop }); } else { - print ("RESTART INJECTOR!") soundProperties.soundInjector.restart(); } soundProperties.readyToPlay = false; @@ -83,7 +78,6 @@ function handleActiveSoundEntities() { // We need to check all of our entities that are not looping but have an interval associated with them // to see if it's time for them to play again soundProperties.timeSinceLastPlay += UPDATE_TIME; - print("INCREMENT TIME SINCE LAST PLAY") if (soundProperties.timeSinceLastPlay > soundProperties.currentInterval) { soundProperties.readyToPlay = true; soundProperties.timeSinceLastPlay = 0; @@ -103,7 +97,6 @@ function handleFoundSoundEntities(entities) { if (soundData && soundData.url) { //check sound entities list- if it's not in, add it if (!soundEntityMap[entity]) { - print("FOUND A NEW SOUND ENTITY!") var soundProperties = { url: soundData.url, volume: soundData.volume || DEFAULT_SOUND_DATA.volume, @@ -129,7 +122,6 @@ function handleFoundSoundEntities(entities) { // Only add it to map once it's downloaded soundUrls[soundData.url] = sound; sound.ready.connect(function() { - print("ADD TO MAP!") soundProperties.sound = sound; soundProperties.readyToPlay = true; soundProperties.isDownloaded = true; @@ -154,7 +146,6 @@ function handleFoundSoundEntities(entities) { function checkForSoundPropertyChanges(currentProps, newProps) { var needsUpdate = false; if (currentProps.volume !== newProps.volume) { - print("VOLUME CHANGED!!"); currentProps.volume = newProps.volume; needsUpdate = true; } @@ -165,7 +156,6 @@ function checkForSoundPropertyChanges(currentProps, newProps) { var sound = SoundCache.getSound(currentProps.url); currentProps.isDownloaded = false; sound.ready.connect(function() { - print("Ready to play new sound!") currentProps.sound = sound; currentProps.isDownloaded = true; }); @@ -175,7 +165,6 @@ function checkForSoundPropertyChanges(currentProps, newProps) { needsUpdate = true; } if (needsUpdate) { - print("UPDATING!"); // If we were looping we need to stop that so new changes are applied currentProps.soundInjector.stop(); currentProps.soundInjector = null; From 609ddda74e91b47d024a24f72a5c4ed5d5b06eeb Mon Sep 17 00:00:00 2001 From: ericrius1 Date: Fri, 5 Feb 2016 13:49:44 -0800 Subject: [PATCH 22/37] adjusting for interval and interval spread --- .../ACAudioSearchAndInject2.js | 31 ++++++++++++++----- .../acAudioSearchCompatibleEntitySpawner2.js | 2 +- 2 files changed, 24 insertions(+), 9 deletions(-) diff --git a/examples/audioExamples/acAudioSearching/ACAudioSearchAndInject2.js b/examples/audioExamples/acAudioSearching/ACAudioSearchAndInject2.js index 974bfb085d..6f69b969e0 100644 --- a/examples/audioExamples/acAudioSearching/ACAudioSearchAndInject2.js +++ b/examples/audioExamples/acAudioSearching/ACAudioSearchAndInject2.js @@ -19,7 +19,7 @@ var DEFAULT_SOUND_DATA = { }; var MIN_PLAY_INTERVAL = 0.2; -var UPDATE_TIME = 2000; +var UPDATE_TIME = 100; var EXPIRATION_TIME = 7000; var soundEntityMap = {}; @@ -27,7 +27,7 @@ var soundUrls = {}; print("EBL STARTING SCRIPT"); -function slowUpdate() { +function update() { var avatars = AvatarList.getAvatarIdentifiers(); for (var i = 0; i < avatars.length; i++) { var avatar = AvatarList.getAvatar(avatars[i]); @@ -60,7 +60,7 @@ function handleActiveSoundEntities() { // An avatar hasn't been within range of this sound entity recently, so remove it from map soundProperties.soundInjector.stop(); delete soundEntityMap[soundEntity]; - } else if(soundProperties.isDownloaded) { + } else if (soundProperties.isDownloaded) { // If this sound hasn't expired yet, we want to potentially play it! if (soundProperties.readyToPlay) { var newPosition = Entities.getEntityProperties(soundEntity, "position").position; @@ -71,6 +71,7 @@ function handleActiveSoundEntities() { loop: soundProperties.loop }); } else { + print("PLAY!!") soundProperties.soundInjector.restart(); } soundProperties.readyToPlay = false; @@ -84,6 +85,7 @@ function handleActiveSoundEntities() { // Now let's get our new current interval soundProperties.currentInterval = soundProperties.interval + randFloat(-soundProperties.intervalSpread, soundProperties.intervalSpread); soundProperties.currentInterval = Math.max(MIN_PLAY_INTERVAL, soundProperties.currentInterval); + print("CURRENT INTERVAL " + soundProperties.currentInterval) } } } @@ -144,10 +146,23 @@ function handleFoundSoundEntities(entities) { } function checkForSoundPropertyChanges(currentProps, newProps) { - var needsUpdate = false; + var needsNewInjector = false; + + if (currentProps.interval !== newProps.interval && !currentProps.loop) { + // interval only applies to non looping sounds + currentProps.interval = newProps.interval; + currentProps.currentInterval = currentProps.interval + randFloat(-currentProps.intervalSpread, currentProps.intervalSpread); + currentProps.currentInterval = Math.max(MIN_PLAY_INTERVAL, currentProps.currentInterval); + currentProps.readyToPlay = true; + } + + if (currentProps.intervalSpread !== currentProps.intervalSpread) { + currentProps.currentInterval = currentProps.interval + randFloat(-currentProps.intervalSpread, currentProps.intervalSpread); + currentProps.currentInterval = Math.max(MIN_PLAY_INTERVAL, currentProps.currentInterval); + } if (currentProps.volume !== newProps.volume) { currentProps.volume = newProps.volume; - needsUpdate = true; + needsNewInjector = true; } if (currentProps.url !== newProps.url) { currentProps.url = newProps.url; @@ -162,9 +177,9 @@ function checkForSoundPropertyChanges(currentProps, newProps) { } else { currentProps.sound = sound; } - needsUpdate = true; + needsNewInjector = true; } - if (needsUpdate) { + if (needsNewInjector) { // If we were looping we need to stop that so new changes are applied currentProps.soundInjector.stop(); currentProps.soundInjector = null; @@ -173,4 +188,4 @@ function checkForSoundPropertyChanges(currentProps, newProps) { } -Script.setInterval(slowUpdate, UPDATE_TIME); \ No newline at end of file +Script.setInterval(update, UPDATE_TIME); \ No newline at end of file diff --git a/examples/audioExamples/acAudioSearching/acAudioSearchCompatibleEntitySpawner2.js b/examples/audioExamples/acAudioSearching/acAudioSearchCompatibleEntitySpawner2.js index 8fcb1ad02f..aa0ab761bb 100644 --- a/examples/audioExamples/acAudioSearching/acAudioSearchCompatibleEntitySpawner2.js +++ b/examples/audioExamples/acAudioSearching/acAudioSearchCompatibleEntitySpawner2.js @@ -20,7 +20,7 @@ var userData = { soundKey: { url: "https://s3-us-west-1.amazonaws.com/hifi-content/eric/Sounds/dove2.wav", volume: 0.3, - loop: true, + loop: false, interval: 2000, intervalSpread: 1000 } From 208007c9d88dcbf8b8e7f6b666db13fec0319611 Mon Sep 17 00:00:00 2001 From: ericrius1 Date: Fri, 5 Feb 2016 15:43:15 -0800 Subject: [PATCH 23/37] log --- .../audioExamples/acAudioSearching/ACAudioSearchAndInject2.js | 1 + 1 file changed, 1 insertion(+) diff --git a/examples/audioExamples/acAudioSearching/ACAudioSearchAndInject2.js b/examples/audioExamples/acAudioSearching/ACAudioSearchAndInject2.js index 6f69b969e0..044d87878c 100644 --- a/examples/audioExamples/acAudioSearching/ACAudioSearchAndInject2.js +++ b/examples/audioExamples/acAudioSearching/ACAudioSearchAndInject2.js @@ -57,6 +57,7 @@ function handleActiveSoundEntities() { var soundProperties = soundEntityMap[soundEntity]; soundProperties.timeWithoutAvatarInRange += UPDATE_TIME; if (soundProperties.timeWithoutAvatarInRange > EXPIRATION_TIME && soundProperties.soundInjector) { + print("NO AVATARS NEAR THIS ENTITY FOR A WHILE. DELETING!") // An avatar hasn't been within range of this sound entity recently, so remove it from map soundProperties.soundInjector.stop(); delete soundEntityMap[soundEntity]; From a5c037b23fcedfcc8d737a0a8e79d4a07e149ca0 Mon Sep 17 00:00:00 2001 From: ericrius1 Date: Fri, 5 Feb 2016 16:09:30 -0800 Subject: [PATCH 24/37] possible bug fix for sound not playing on avatar rentry --- .../ACAudioSearchAndInject2.js | 18 ++++++++++++++---- 1 file changed, 14 insertions(+), 4 deletions(-) diff --git a/examples/audioExamples/acAudioSearching/ACAudioSearchAndInject2.js b/examples/audioExamples/acAudioSearching/ACAudioSearchAndInject2.js index 044d87878c..906d3382e9 100644 --- a/examples/audioExamples/acAudioSearching/ACAudioSearchAndInject2.js +++ b/examples/audioExamples/acAudioSearching/ACAudioSearchAndInject2.js @@ -25,6 +25,8 @@ var EXPIRATION_TIME = 7000; var soundEntityMap = {}; var soundUrls = {}; +var avatarPositions = []; + print("EBL STARTING SCRIPT"); function update() { @@ -38,11 +40,16 @@ function update() { } EntityViewer.setPosition(avatarPosition); EntityViewer.queryOctree(); - Script.setTimeout(function() { - var entities = Entities.findEntities(avatar.position, QUERY_RADIUS); - handleFoundSoundEntities(entities); - }, 1000); + avatarPositions.push(avatarPosition); } + Script.setTimeout(function() { + avatarPositions.forEach(function(avatarPosition) { + var entities = Entities.findEntities(avatarPosition, QUERY_RADIUS); + handleFoundSoundEntities(entities); + }); + //Now wipe list for next query; + avatarPositions = []; + }, 1000); handleActiveSoundEntities(); } @@ -66,6 +73,7 @@ function handleActiveSoundEntities() { if (soundProperties.readyToPlay) { var newPosition = Entities.getEntityProperties(soundEntity, "position").position; if (!soundProperties.soundInjector) { + print("PLAY first injector!!!") soundProperties.soundInjector = Audio.playSound(soundProperties.sound, { volume: soundProperties.volume, position: newPosition, @@ -100,6 +108,7 @@ function handleFoundSoundEntities(entities) { if (soundData && soundData.url) { //check sound entities list- if it's not in, add it if (!soundEntityMap[entity]) { + print("NEW SOUND!") var soundProperties = { url: soundData.url, volume: soundData.volume || DEFAULT_SOUND_DATA.volume, @@ -134,6 +143,7 @@ function handleFoundSoundEntities(entities) { // We already have sound downloaded, so just add it to map right away soundProperties.sound = soundUrls[soundData.url]; soundProperties.readyToPlay = true; + soundProperties.isDownloaded = true; soundEntityMap[entity] = soundProperties; } } else { From 1c54de6f571b2d67201cfd78c2341de849e630d9 Mon Sep 17 00:00:00 2001 From: ericrius1 Date: Fri, 5 Feb 2016 16:11:43 -0800 Subject: [PATCH 25/37] better logging --- .../audioExamples/acAudioSearching/ACAudioSearchAndInject2.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/examples/audioExamples/acAudioSearching/ACAudioSearchAndInject2.js b/examples/audioExamples/acAudioSearching/ACAudioSearchAndInject2.js index 906d3382e9..f41d45e6ad 100644 --- a/examples/audioExamples/acAudioSearching/ACAudioSearchAndInject2.js +++ b/examples/audioExamples/acAudioSearching/ACAudioSearchAndInject2.js @@ -64,7 +64,7 @@ function handleActiveSoundEntities() { var soundProperties = soundEntityMap[soundEntity]; soundProperties.timeWithoutAvatarInRange += UPDATE_TIME; if (soundProperties.timeWithoutAvatarInRange > EXPIRATION_TIME && soundProperties.soundInjector) { - print("NO AVATARS NEAR THIS ENTITY FOR A WHILE. DELETING!") + print("THIS ENTITY IS GONE OR NO AVATARS ARE IN RANGE!") // An avatar hasn't been within range of this sound entity recently, so remove it from map soundProperties.soundInjector.stop(); delete soundEntityMap[soundEntity]; From 4c33c6e1710400738eb5123d87455cfc1a397ad0 Mon Sep 17 00:00:00 2001 From: ericrius1 Date: Fri, 5 Feb 2016 17:13:29 -0800 Subject: [PATCH 26/37] clean up --- .../ACAudioSearchAndInject.js | 265 +++++++++++------- .../ACAudioSearchAndInject2.js | 202 ------------- .../acAudioSearchCompatibleEntitySpawner.js | 24 +- .../acAudioSearchCompatibleEntitySpawner2.js | 56 ---- .../acAudioSearching/soundEntityScript.js | 36 --- 5 files changed, 182 insertions(+), 401 deletions(-) delete mode 100644 examples/audioExamples/acAudioSearching/ACAudioSearchAndInject2.js delete mode 100644 examples/audioExamples/acAudioSearching/acAudioSearchCompatibleEntitySpawner2.js delete mode 100644 examples/audioExamples/acAudioSearching/soundEntityScript.js diff --git a/examples/audioExamples/acAudioSearching/ACAudioSearchAndInject.js b/examples/audioExamples/acAudioSearching/ACAudioSearchAndInject.js index bafaead7db..076811b1c0 100644 --- a/examples/audioExamples/acAudioSearching/ACAudioSearchAndInject.js +++ b/examples/audioExamples/acAudioSearching/ACAudioSearchAndInject.js @@ -5,126 +5,203 @@ // Created by Eric Levin 2/1/2016 // Copyright 2016 High Fidelity, Inc. -// This AC script constantly searches for entities with a special userData field that specifies audio settings, and then -// injects the sound with the specified URL with other specified settings (playback volume) or playback at interval, or random interval +// This AC script searches for special sound entities nearby avatars and plays those sounds based off information specified in the entity's +// user data field ( see acAudioSearchAndCompatibilityEntitySpawner.js for an example) // // Distributed under the Apache License, Version 2.0. // See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html -// Script.include("https://rawgit.com/highfidelity/hifi/master/examples/libraries/utils.js"); var SOUND_DATA_KEY = "soundKey"; -var MESSAGE_CHANNEL = "Hifi-Sound-Entity"; -// Map of all sound entities in domain- key is entity id, value is sound data -var soundEntityMap = {}; -// Map of sound urls so a sound that's already been downloaded from one entity is not re-downloaded if -// another entity with same sound url is discovered -var soundUrls = {}; +var QUERY_RADIUS = 50; -EntityViewer.setPosition({ - x: 0, - y: 0, - z: 0 -}); - -EntityViewer.setKeyholeRadius(60000); +EntityViewer.setKeyholeRadius(QUERY_RADIUS); Entities.setPacketsPerSecond(6000); +Agent.isAvatar = true; + var DEFAULT_SOUND_DATA = { volume: 0.5, loop: false, interval: -1, // An interval of -1 means this sound only plays once (if it's non-looping) (In seconds) intervalSpread: 0 // amount of randomness to add to the interval }; -var MIN_INTERVAL = 0.2; -EntityViewer.queryOctree(); +var MIN_PLAY_INTERVAL = 0.2; -function messageReceived(channel, message, sender) { - print("EBL MESSAGE RECIEVED"); - var entityID = JSON.parse(message).id; - if (soundEntityMap[entityID]) { - // We already have this entity in our sound map, so don't re-add - return; - } +var UPDATE_TIME = 100; +var EXPIRATION_TIME = 20000; - EntityViewer.queryOctree(); - Script.setTimeout(function() { - handleIncomingEntity(entityID); - }, 2000); +var soundEntityMap = {}; +var soundUrls = {}; -} +var avatarPositions = []; -function handleIncomingEntity(entityID) { - var soundData = getEntityCustomData(SOUND_DATA_KEY, entityID); - print("SOUND DATA " + JSON.stringify(soundData)); - if (soundData && soundData.url) { - var soundProperties = { - url: soundData.url, - volume: soundData.volume || DEFAULT_SOUND_DATA.volume, - loop: soundData.loop || DEFAULT_SOUND_DATA.loop, - interval: soundData.interval || DEFAULT_SOUND_DATA.interval, - intervalSpread: soundData.intervalSpread || DEFAULT_SOUND_DATA.intervalSpread, - readyToPlay: true, - position: Entities.getEntityProperties(entityID, "position").position, - timeSinceLastPlay: 0 - }; - if (soundProperties.interval !== -1) { - soundProperties.currentInterval = soundProperties.interval + randFloat(-soundProperties.intervalSpread, soundProperties.intervalSpread); - soundProperties.currentInterval = Math.max(MIN_INTERVAL, soundProperties.currentInterval); - } - if (!soundUrls[soundData.url]) { - // We need to download sound before we add it to our map - var sound = SoundCache.getSound(soundData.url); - soundUrls[soundData.url] = sound; - // Only add it to map once it's downloaded - sound.ready.connect(function() { - soundProperties.sound = sound; - soundEntityMap[entityID] = soundProperties; - }); - } else { - // We already have sound downloaded, so just add it to map right away - soundProperties.sound = soundUrls[soundData.url]; - soundEntityMap[entityID] = soundProperties; - } - } -} - -function update(deltaTime) { - // Go through each sound and play it if it needs to be played - for (var potentialEntity in soundEntityMap) { - if (!soundEntityMap.hasOwnProperty(potentialEntity)) { - // The current property is not a direct propert of soundEntityMap so ignore it +function update() { + var avatars = AvatarList.getAvatarIdentifiers(); + for (var i = 0; i < avatars.length; i++) { + var avatar = AvatarList.getAvatar(avatars[i]); + var avatarPosition = avatar.position; + if (!avatarPosition) { continue; } - var entity = potentialEntity; - var soundProperties = soundEntityMap[entity]; - if (soundProperties.readyToPlay) { - var newPosition = Entities.getEntityProperties(entity, "position").position - print("EBL SHOULD BE PLAYING SOUND!") - Audio.playSound(soundProperties.sound, { - volume: soundProperties.volume, - position: newPosition, - loop: soundProperties.loop - }); - soundProperties.readyToPlay = false; - } else if (soundProperties.loop === false && soundProperties.interval !== -1) { - // We need to check all of our entities that are not looping but have an interval associated with them - // to see if it's time for them to play again - soundProperties.timeSinceLastPlay += deltaTime; - if (soundProperties.timeSinceLastPlay > soundProperties.currentInterval) { - soundProperties.readyToPlay = true; - soundProperties.timeSinceLastPlay = 0; - // Now lets get our next current interval - soundProperties.currentInterval = soundProperties.interval + randFloat(-soundProperties.intervalSpread, soundProperties.intervalSpread); - soundProperties.currentInterval = Math.max(MIN_INTERVAL, soundProperties.currentInterval); + EntityViewer.setPosition(avatarPosition); + EntityViewer.queryOctree(); + avatarPositions.push(avatarPosition); + } + Script.setTimeout(function() { + avatarPositions.forEach(function(avatarPosition) { + var entities = Entities.findEntities(avatarPosition, QUERY_RADIUS); + handleFoundSoundEntities(entities); + }); + //Now wipe list for next query; + avatarPositions = []; + }, 1000); + handleActiveSoundEntities(); +} + +function handleActiveSoundEntities() { + // Go through all our sound entities, if they have passed expiration time, remove them from map + for (var potentialSoundEntity in soundEntityMap) { + if (!soundEntityMap.hasOwnProperty(potentialSoundEntity)) { + // The current property is not a direct property of soundEntityMap so ignore it + continue; + } + var soundEntity = potentialSoundEntity; + var soundProperties = soundEntityMap[soundEntity]; + soundProperties.timeWithoutAvatarInRange += UPDATE_TIME; + if (soundProperties.timeWithoutAvatarInRange > EXPIRATION_TIME && soundProperties.soundInjector) { + // An avatar hasn't been within range of this sound entity recently, so remove it from map + soundProperties.soundInjector.stop(); + delete soundEntityMap[soundEntity]; + } else if (soundProperties.isDownloaded) { + // If this sound hasn't expired yet, we want to potentially play it! + if (soundProperties.readyToPlay) { + var newPosition = Entities.getEntityProperties(soundEntity, "position").position; + if (!soundProperties.soundInjector) { + soundProperties.soundInjector = Audio.playSound(soundProperties.sound, { + volume: soundProperties.volume, + position: newPosition, + loop: soundProperties.loop + }); + } else { + soundProperties.soundInjector.restart(); + } + soundProperties.readyToPlay = false; + } else if (soundProperties.sound && soundProperties.loop === false && soundProperties.interval !== -1) { + // We need to check all of our entities that are not looping but have an interval associated with them + // to see if it's time for them to play again + soundProperties.timeSinceLastPlay += UPDATE_TIME; + if (soundProperties.timeSinceLastPlay > soundProperties.currentInterval) { + soundProperties.readyToPlay = true; + soundProperties.timeSinceLastPlay = 0; + // Now let's get our new current interval + soundProperties.currentInterval = soundProperties.interval + randFloat(-soundProperties.intervalSpread, soundProperties.intervalSpread); + soundProperties.currentInterval = Math.max(MIN_PLAY_INTERVAL, soundProperties.currentInterval); + } } } } } -Script.update.connect(update); -Messages.subscribe(MESSAGE_CHANNEL); -Messages.messageReceived.connect(messageReceived); \ No newline at end of file + +function handleFoundSoundEntities(entities) { + entities.forEach(function(entity) { + var soundData = getEntityCustomData(SOUND_DATA_KEY, entity); + if (soundData && soundData.url) { + //check sound entities list- if it's not in, add it + if (!soundEntityMap[entity]) { + print("NEW SOUND!") + var soundProperties = { + url: soundData.url, + volume: soundData.volume || DEFAULT_SOUND_DATA.volume, + loop: soundData.loop || DEFAULT_SOUND_DATA.loop, + interval: soundData.interval || DEFAULT_SOUND_DATA.interval, + intervalSpread: soundData.intervalSpread || DEFAULT_SOUND_DATA.intervalSpread, + readyToPlay: false, + position: Entities.getEntityProperties(entity, "position").position, + timeSinceLastPlay: 0, + timeWithoutAvatarInRange: 0, + isDownloaded: false + }; + + if (soundProperties.interval !== -1) { + soundProperties.currentInterval = soundProperties.interval + randFloat(-soundProperties.intervalSpread, soundProperties.intervalSpread); + soundProperties.currentInterval = Math.max(MIN_PLAY_INTERVAL, soundProperties.currentInterval); + } + + soundEntityMap[entity] = soundProperties; + if (!soundUrls[soundData.url]) { + // We need to download sound before we add it to our map + var sound = SoundCache.getSound(soundData.url); + // Only add it to map once it's downloaded + soundUrls[soundData.url] = sound; + sound.ready.connect(function() { + soundProperties.sound = sound; + soundProperties.readyToPlay = true; + soundProperties.isDownloaded = true; + soundEntityMap[entity] = soundProperties; + }); + } else { + // We already have sound downloaded, so just add it to map right away + soundProperties.sound = soundUrls[soundData.url]; + soundProperties.readyToPlay = true; + soundProperties.isDownloaded = true; + soundEntityMap[entity] = soundProperties; + } + } else { + //If this sound is in our map already, we want to reset timeWithoutAvatarInRange + // Also we want to check to see if the entity has been updated with new sound data- if so we want to update! + soundEntityMap[entity].timeWithoutAvatarInRange = 0; + checkForSoundPropertyChanges(soundEntityMap[entity], soundData); + } + } + }); +} + +function checkForSoundPropertyChanges(currentProps, newProps) { + var needsNewInjector = false; + + if (currentProps.interval !== newProps.interval && !currentProps.loop) { + // interval only applies to non looping sounds + currentProps.interval = newProps.interval; + currentProps.currentInterval = currentProps.interval + randFloat(-currentProps.intervalSpread, currentProps.intervalSpread); + currentProps.currentInterval = Math.max(MIN_PLAY_INTERVAL, currentProps.currentInterval); + currentProps.readyToPlay = true; + } + + if (currentProps.intervalSpread !== currentProps.intervalSpread) { + currentProps.currentInterval = currentProps.interval + randFloat(-currentProps.intervalSpread, currentProps.intervalSpread); + currentProps.currentInterval = Math.max(MIN_PLAY_INTERVAL, currentProps.currentInterval); + } + if (currentProps.volume !== newProps.volume) { + currentProps.volume = newProps.volume; + needsNewInjector = true; + } + if (currentProps.url !== newProps.url) { + currentProps.url = newProps.url; + currentProps.sound = null; + if (!soundUrls[currentProps.url]) { + var sound = SoundCache.getSound(currentProps.url); + currentProps.isDownloaded = false; + sound.ready.connect(function() { + currentProps.sound = sound; + currentProps.isDownloaded = true; + }); + } else { + currentProps.sound = sound; + } + needsNewInjector = true; + } + if (needsNewInjector) { + // If we were looping we need to stop that so new changes are applied + currentProps.soundInjector.stop(); + currentProps.soundInjector = null; + currentProps.readyToPlay = true; + } + +} + +Script.setInterval(update, UPDATE_TIME); \ No newline at end of file diff --git a/examples/audioExamples/acAudioSearching/ACAudioSearchAndInject2.js b/examples/audioExamples/acAudioSearching/ACAudioSearchAndInject2.js deleted file mode 100644 index f41d45e6ad..0000000000 --- a/examples/audioExamples/acAudioSearching/ACAudioSearchAndInject2.js +++ /dev/null @@ -1,202 +0,0 @@ -// - -Script.include("https://rawgit.com/highfidelity/hifi/master/examples/libraries/utils.js"); - -var SOUND_DATA_KEY = "soundKey"; - -var QUERY_RADIUS = 5; - -EntityViewer.setKeyholeRadius(QUERY_RADIUS); -Entities.setPacketsPerSecond(6000); - -Agent.isAvatar = true; - -var DEFAULT_SOUND_DATA = { - volume: 0.5, - loop: false, - interval: -1, // An interval of -1 means this sound only plays once (if it's non-looping) (In seconds) - intervalSpread: 0 // amount of randomness to add to the interval -}; -var MIN_PLAY_INTERVAL = 0.2; - -var UPDATE_TIME = 100; -var EXPIRATION_TIME = 7000; - -var soundEntityMap = {}; -var soundUrls = {}; - -var avatarPositions = []; - -print("EBL STARTING SCRIPT"); - -function update() { - var avatars = AvatarList.getAvatarIdentifiers(); - for (var i = 0; i < avatars.length; i++) { - var avatar = AvatarList.getAvatar(avatars[i]); - var avatarPosition = avatar.position; - if (!avatarPosition) { - print("EBL This avatars been DELETED *******! Don't add it to list"); - continue; - } - EntityViewer.setPosition(avatarPosition); - EntityViewer.queryOctree(); - avatarPositions.push(avatarPosition); - } - Script.setTimeout(function() { - avatarPositions.forEach(function(avatarPosition) { - var entities = Entities.findEntities(avatarPosition, QUERY_RADIUS); - handleFoundSoundEntities(entities); - }); - //Now wipe list for next query; - avatarPositions = []; - }, 1000); - handleActiveSoundEntities(); -} - -function handleActiveSoundEntities() { - // Go through all our sound entities, if they have passed expiration time, remove them from map - for (var potentialSoundEntity in soundEntityMap) { - if (!soundEntityMap.hasOwnProperty(potentialSoundEntity)) { - // The current property is not a direct property of soundEntityMap so ignore it - continue; - } - var soundEntity = potentialSoundEntity; - var soundProperties = soundEntityMap[soundEntity]; - soundProperties.timeWithoutAvatarInRange += UPDATE_TIME; - if (soundProperties.timeWithoutAvatarInRange > EXPIRATION_TIME && soundProperties.soundInjector) { - print("THIS ENTITY IS GONE OR NO AVATARS ARE IN RANGE!") - // An avatar hasn't been within range of this sound entity recently, so remove it from map - soundProperties.soundInjector.stop(); - delete soundEntityMap[soundEntity]; - } else if (soundProperties.isDownloaded) { - // If this sound hasn't expired yet, we want to potentially play it! - if (soundProperties.readyToPlay) { - var newPosition = Entities.getEntityProperties(soundEntity, "position").position; - if (!soundProperties.soundInjector) { - print("PLAY first injector!!!") - soundProperties.soundInjector = Audio.playSound(soundProperties.sound, { - volume: soundProperties.volume, - position: newPosition, - loop: soundProperties.loop - }); - } else { - print("PLAY!!") - soundProperties.soundInjector.restart(); - } - soundProperties.readyToPlay = false; - } else if (soundProperties.sound && soundProperties.loop === false && soundProperties.interval !== -1) { - // We need to check all of our entities that are not looping but have an interval associated with them - // to see if it's time for them to play again - soundProperties.timeSinceLastPlay += UPDATE_TIME; - if (soundProperties.timeSinceLastPlay > soundProperties.currentInterval) { - soundProperties.readyToPlay = true; - soundProperties.timeSinceLastPlay = 0; - // Now let's get our new current interval - soundProperties.currentInterval = soundProperties.interval + randFloat(-soundProperties.intervalSpread, soundProperties.intervalSpread); - soundProperties.currentInterval = Math.max(MIN_PLAY_INTERVAL, soundProperties.currentInterval); - print("CURRENT INTERVAL " + soundProperties.currentInterval) - } - } - } - } -} - - -function handleFoundSoundEntities(entities) { - entities.forEach(function(entity) { - var soundData = getEntityCustomData(SOUND_DATA_KEY, entity); - if (soundData && soundData.url) { - //check sound entities list- if it's not in, add it - if (!soundEntityMap[entity]) { - print("NEW SOUND!") - var soundProperties = { - url: soundData.url, - volume: soundData.volume || DEFAULT_SOUND_DATA.volume, - loop: soundData.loop || DEFAULT_SOUND_DATA.loop, - interval: soundData.interval || DEFAULT_SOUND_DATA.interval, - intervalSpread: soundData.intervalSpread || DEFAULT_SOUND_DATA.intervalSpread, - readyToPlay: false, - position: Entities.getEntityProperties(entity, "position").position, - timeSinceLastPlay: 0, - timeWithoutAvatarInRange: 0, - isDownloaded: false - }; - - if (soundProperties.interval !== -1) { - soundProperties.currentInterval = soundProperties.interval + randFloat(-soundProperties.intervalSpread, soundProperties.intervalSpread); - soundProperties.currentInterval = Math.max(MIN_PLAY_INTERVAL, soundProperties.currentInterval); - } - - soundEntityMap[entity] = soundProperties; - if (!soundUrls[soundData.url]) { - // We need to download sound before we add it to our map - var sound = SoundCache.getSound(soundData.url); - // Only add it to map once it's downloaded - soundUrls[soundData.url] = sound; - sound.ready.connect(function() { - soundProperties.sound = sound; - soundProperties.readyToPlay = true; - soundProperties.isDownloaded = true; - soundEntityMap[entity] = soundProperties; - }); - } else { - // We already have sound downloaded, so just add it to map right away - soundProperties.sound = soundUrls[soundData.url]; - soundProperties.readyToPlay = true; - soundProperties.isDownloaded = true; - soundEntityMap[entity] = soundProperties; - } - } else { - //If this sound is in our map already, we want to reset timeWithoutAvatarInRange - // Also we want to check to see if the entity has been updated with new sound data- if so we want to update! - soundEntityMap[entity].timeWithoutAvatarInRange = 0; - checkForSoundPropertyChanges(soundEntityMap[entity], soundData); - } - } - }); -} - -function checkForSoundPropertyChanges(currentProps, newProps) { - var needsNewInjector = false; - - if (currentProps.interval !== newProps.interval && !currentProps.loop) { - // interval only applies to non looping sounds - currentProps.interval = newProps.interval; - currentProps.currentInterval = currentProps.interval + randFloat(-currentProps.intervalSpread, currentProps.intervalSpread); - currentProps.currentInterval = Math.max(MIN_PLAY_INTERVAL, currentProps.currentInterval); - currentProps.readyToPlay = true; - } - - if (currentProps.intervalSpread !== currentProps.intervalSpread) { - currentProps.currentInterval = currentProps.interval + randFloat(-currentProps.intervalSpread, currentProps.intervalSpread); - currentProps.currentInterval = Math.max(MIN_PLAY_INTERVAL, currentProps.currentInterval); - } - if (currentProps.volume !== newProps.volume) { - currentProps.volume = newProps.volume; - needsNewInjector = true; - } - if (currentProps.url !== newProps.url) { - currentProps.url = newProps.url; - currentProps.sound = null; - if (!soundUrls[currentProps.url]) { - var sound = SoundCache.getSound(currentProps.url); - currentProps.isDownloaded = false; - sound.ready.connect(function() { - currentProps.sound = sound; - currentProps.isDownloaded = true; - }); - } else { - currentProps.sound = sound; - } - needsNewInjector = true; - } - if (needsNewInjector) { - // If we were looping we need to stop that so new changes are applied - currentProps.soundInjector.stop(); - currentProps.soundInjector = null; - currentProps.readyToPlay = true; - } - -} - -Script.setInterval(update, UPDATE_TIME); \ No newline at end of file diff --git a/examples/audioExamples/acAudioSearching/acAudioSearchCompatibleEntitySpawner.js b/examples/audioExamples/acAudioSearching/acAudioSearchCompatibleEntitySpawner.js index 876f5e6461..7f71dad3a4 100644 --- a/examples/audioExamples/acAudioSearching/acAudioSearchCompatibleEntitySpawner.js +++ b/examples/audioExamples/acAudioSearching/acAudioSearchCompatibleEntitySpawner.js @@ -14,27 +14,26 @@ // Script.include("../../libraries/utils.js"); - +var orientation = Camera.getOrientation(); +orientation = Quat.safeEulerAngles(orientation); +orientation.x = 0; +orientation = Quat.fromVec3Degrees(orientation); +var center = Vec3.sum(MyAvatar.position, Vec3.multiply(3, Quat.getFront(orientation))); +// http://hifi-public.s3.amazonaws.com/ryan/demo/0619_Fireplace__Tree_B.L.wav var SOUND_DATA_KEY = "soundKey"; -var MESSAGE_CHANNEL = "Hifi-Sound-Entity"; -var SCRIPT_URL = Script.resolvePath("soundEntityScript.js?v1" + Math.random()); var userData = { soundKey: { - url: "https://s3-us-west-1.amazonaws.com/hifi-content/eric/Sounds/dove.wav", + url: "https://s3-us-west-1.amazonaws.com/hifi-content/eric/Sounds/dove2.wav", volume: 0.3, loop: false, - interval: 4, - intervalSpread: 2 + interval: 2000, + intervalSpread: 1000 } } var entityProps = { type: "Box", - position: { - x: Math.random(), - y: 0, - z: 0 - }, + position: center, color: { red: 200, green: 10, @@ -45,8 +44,7 @@ var entityProps = { y: 0.1, z: 0.1 }, - userData: JSON.stringify(userData), - script: SCRIPT_URL + userData: JSON.stringify(userData) } var soundEntity = Entities.addEntity(entityProps); diff --git a/examples/audioExamples/acAudioSearching/acAudioSearchCompatibleEntitySpawner2.js b/examples/audioExamples/acAudioSearching/acAudioSearchCompatibleEntitySpawner2.js deleted file mode 100644 index aa0ab761bb..0000000000 --- a/examples/audioExamples/acAudioSearching/acAudioSearchCompatibleEntitySpawner2.js +++ /dev/null @@ -1,56 +0,0 @@ -// -// acAudioSearchCompatibleEntitySpawner.js -// audio/acAudioSearching -// -// Created by Eric Levin 2/2/2016 -// Copyright 2016 High Fidelity, Inc. - -// This is a client script which spawns entities with a field in userData compatible with the AcAudioSearchAndInject script -// These entities specify data about the sound they want to play, such as url, volume, and whether to loop or not -// The position of the entity determines the position from which the sound plays from -// -// Distributed under the Apache License, Version 2.0. -// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html -// - -Script.include("../../libraries/utils.js"); -// http://hifi-public.s3.amazonaws.com/ryan/demo/0619_Fireplace__Tree_B.L.wav -var SOUND_DATA_KEY = "soundKey"; -var userData = { - soundKey: { - url: "https://s3-us-west-1.amazonaws.com/hifi-content/eric/Sounds/dove2.wav", - volume: 0.3, - loop: false, - interval: 2000, - intervalSpread: 1000 - } -} - -var entityProps = { - type: "Box", - position: { - x: Math.random(), - y: 0, - z: 0 - }, - color: { - red: 200, - green: 10, - blue: 200 - }, - dimensions: { - x: 0.1, - y: 0.1, - z: 0.1 - }, - userData: JSON.stringify(userData) -} - -var soundEntity = Entities.addEntity(entityProps); - - -function cleanup() { - Entities.deleteEntity(soundEntity); -} - -Script.scriptEnding.connect(cleanup); \ No newline at end of file diff --git a/examples/audioExamples/acAudioSearching/soundEntityScript.js b/examples/audioExamples/acAudioSearching/soundEntityScript.js deleted file mode 100644 index b58a4cc0fe..0000000000 --- a/examples/audioExamples/acAudioSearching/soundEntityScript.js +++ /dev/null @@ -1,36 +0,0 @@ -// soundEntityScript.js -// -// Script Type: Entity -// Created by Eric Levin on 2/2/16. -// Copyright 2016 High Fidelity, Inc. -// -// This entity script sends a message meant for a running AC script on its preload -// Distributed under the Apache License, Version 2.0. -// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html -// - -(function() { - Script.include("../../libraries/utils.js"); - var _this; - // this is the "constructor" for the entity as a JS object we don't do much here - var SoundEntity = function() { - _this = this; - this.MESSAGE_CHANNEL = "Hifi-Sound-Entity"; - }; - - SoundEntity.prototype = { - preload: function(entityID) { - this.entityID = entityID; - Script.setTimeout(function() { - var soundData = getEntityCustomData("soundKey", _this.entityID); - // Just a hack for now until bug https://app.asana.com/0/26225263936266/86767805352289 is fixed - print("EBL SEND MESSAGE"); - Messages.sendMessage(_this.MESSAGE_CHANNEL, JSON.stringify({ - id: _this.entityID - })); - }, 2000); - }, - }; - // entity scripts always need to return a newly constructed object of our type - return new SoundEntity(); -}); \ No newline at end of file From 6d64da2df73fb7e40d3f953ff0fe5d188f24562a Mon Sep 17 00:00:00 2001 From: ericrius1 Date: Fri, 5 Feb 2016 17:28:55 -0800 Subject: [PATCH 27/37] expiration time is 5 seconds now --- .../audioExamples/acAudioSearching/ACAudioSearchAndInject.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/examples/audioExamples/acAudioSearching/ACAudioSearchAndInject.js b/examples/audioExamples/acAudioSearching/ACAudioSearchAndInject.js index 076811b1c0..b776a21439 100644 --- a/examples/audioExamples/acAudioSearching/ACAudioSearchAndInject.js +++ b/examples/audioExamples/acAudioSearching/ACAudioSearchAndInject.js @@ -31,7 +31,7 @@ var DEFAULT_SOUND_DATA = { var MIN_PLAY_INTERVAL = 0.2; var UPDATE_TIME = 100; -var EXPIRATION_TIME = 20000; +var EXPIRATION_TIME = 5000; var soundEntityMap = {}; var soundUrls = {}; From 053f163b9276718d8c60af8185f805e637617968 Mon Sep 17 00:00:00 2001 From: Eric Levin Date: Fri, 5 Feb 2016 22:13:25 -0800 Subject: [PATCH 28/37] Changed wait time of avatar list query to entity query to update time so avatar positions don't pile up --- .../audioExamples/acAudioSearching/ACAudioSearchAndInject.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/examples/audioExamples/acAudioSearching/ACAudioSearchAndInject.js b/examples/audioExamples/acAudioSearching/ACAudioSearchAndInject.js index b776a21439..d9212899d8 100644 --- a/examples/audioExamples/acAudioSearching/ACAudioSearchAndInject.js +++ b/examples/audioExamples/acAudioSearching/ACAudioSearchAndInject.js @@ -58,7 +58,7 @@ function update() { }); //Now wipe list for next query; avatarPositions = []; - }, 1000); + }, UPDATE_TIME); handleActiveSoundEntities(); } @@ -204,4 +204,4 @@ function checkForSoundPropertyChanges(currentProps, newProps) { } -Script.setInterval(update, UPDATE_TIME); \ No newline at end of file +Script.setInterval(update, UPDATE_TIME); From 0932df621a62a5944d352af57e2c1b73d581e140 Mon Sep 17 00:00:00 2001 From: Eric Levin Date: Fri, 5 Feb 2016 22:15:16 -0800 Subject: [PATCH 29/37] Changed MIN_TIME_INTERVAL to be in milliseconds --- .../audioExamples/acAudioSearching/ACAudioSearchAndInject.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/examples/audioExamples/acAudioSearching/ACAudioSearchAndInject.js b/examples/audioExamples/acAudioSearching/ACAudioSearchAndInject.js index d9212899d8..9382f47c33 100644 --- a/examples/audioExamples/acAudioSearching/ACAudioSearchAndInject.js +++ b/examples/audioExamples/acAudioSearching/ACAudioSearchAndInject.js @@ -28,7 +28,7 @@ var DEFAULT_SOUND_DATA = { interval: -1, // An interval of -1 means this sound only plays once (if it's non-looping) (In seconds) intervalSpread: 0 // amount of randomness to add to the interval }; -var MIN_PLAY_INTERVAL = 0.2; +var MIN_PLAY_INTERVAL = 200; var UPDATE_TIME = 100; var EXPIRATION_TIME = 5000; From 4ab3bd204ddfc7007a1aef0fbdca0fdea285fa60 Mon Sep 17 00:00:00 2001 From: ericrius1 Date: Mon, 8 Feb 2016 10:05:05 -0800 Subject: [PATCH 30/37] no comment --- .../audioExamples/acAudioSearching/ACAudioSearchAndInject.js | 1 - 1 file changed, 1 deletion(-) diff --git a/examples/audioExamples/acAudioSearching/ACAudioSearchAndInject.js b/examples/audioExamples/acAudioSearching/ACAudioSearchAndInject.js index 9382f47c33..12de302530 100644 --- a/examples/audioExamples/acAudioSearching/ACAudioSearchAndInject.js +++ b/examples/audioExamples/acAudioSearching/ACAudioSearchAndInject.js @@ -113,7 +113,6 @@ function handleFoundSoundEntities(entities) { if (soundData && soundData.url) { //check sound entities list- if it's not in, add it if (!soundEntityMap[entity]) { - print("NEW SOUND!") var soundProperties = { url: soundData.url, volume: soundData.volume || DEFAULT_SOUND_DATA.volume, From 193857f3449eba4f8cad1dab072bd149eb0efd5e Mon Sep 17 00:00:00 2001 From: ericrius1 Date: Mon, 8 Feb 2016 11:51:52 -0800 Subject: [PATCH 31/37] added explanatory comment about format of interval time --- .../acAudioSearching/acAudioSearchCompatibleEntitySpawner.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/examples/audioExamples/acAudioSearching/acAudioSearchCompatibleEntitySpawner.js b/examples/audioExamples/acAudioSearching/acAudioSearchCompatibleEntitySpawner.js index 7f71dad3a4..95737d6a5c 100644 --- a/examples/audioExamples/acAudioSearching/acAudioSearchCompatibleEntitySpawner.js +++ b/examples/audioExamples/acAudioSearching/acAudioSearchCompatibleEntitySpawner.js @@ -26,8 +26,8 @@ var userData = { url: "https://s3-us-west-1.amazonaws.com/hifi-content/eric/Sounds/dove2.wav", volume: 0.3, loop: false, - interval: 2000, - intervalSpread: 1000 + interval: 2000, // In ms + intervalSpread: 1000 // In ms } } From 6b240dfd5f14fbbb7848bf308bbb239ae23d5025 Mon Sep 17 00:00:00 2001 From: ericrius1 Date: Mon, 8 Feb 2016 12:34:46 -0800 Subject: [PATCH 32/37] calculating length of wav file --- libraries/audio/src/Sound.cpp | 3 +++ 1 file changed, 3 insertions(+) diff --git a/libraries/audio/src/Sound.cpp b/libraries/audio/src/Sound.cpp index ff80ba08a9..e3efe9b141 100644 --- a/libraries/audio/src/Sound.cpp +++ b/libraries/audio/src/Sound.cpp @@ -258,6 +258,9 @@ void Sound::interpretAsWav(const QByteArray& inputAudioByteArray, QByteArray& ou qCDebug(audio) << "Error reading WAV file"; } + _clipLength = (float) (outputAudioByteArraySize / (fileHeader.wave.sampleRate * fileHeader.wave.numChannels * fileHeader.wave.bitsPerSample / 8.0f)); + + } else { qCDebug(audio) << "Could not read wav audio file header."; return; From c169a7cdd5e201b86f946304aa9a4eff51988cd9 Mon Sep 17 00:00:00 2001 From: ericrius1 Date: Mon, 8 Feb 2016 12:36:14 -0800 Subject: [PATCH 33/37] calculating clip length --- libraries/audio/src/Sound.h | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/libraries/audio/src/Sound.h b/libraries/audio/src/Sound.h index 6baf691957..5affaeb348 100644 --- a/libraries/audio/src/Sound.h +++ b/libraries/audio/src/Sound.h @@ -27,9 +27,13 @@ public: bool isStereo() const { return _isStereo; } bool isReady() const { return _isReady; } - + + const QByteArray& getByteArray() { return _byteArray; } +public slots: + float getClipLength() const { return _clipLength; } + signals: void ready(); @@ -37,6 +41,7 @@ private: QByteArray _byteArray; bool _isStereo; bool _isReady; + float _clipLength; void downSample(const QByteArray& rawAudioByteArray); void interpretAsWav(const QByteArray& inputAudioByteArray, QByteArray& outputAudioByteArray); From bad4a5d6019565c69b253954ac936d47f37587b6 Mon Sep 17 00:00:00 2001 From: ericrius1 Date: Mon, 8 Feb 2016 12:49:56 -0800 Subject: [PATCH 34/37] changed ac script to take into account duration --- .../ACAudioSearchAndInject.js | 42 ++++++++++--------- .../acAudioSearchCompatibleEntitySpawner.js | 4 +- libraries/audio/src/Sound.h | 5 ++- 3 files changed, 27 insertions(+), 24 deletions(-) diff --git a/examples/audioExamples/acAudioSearching/ACAudioSearchAndInject.js b/examples/audioExamples/acAudioSearching/ACAudioSearchAndInject.js index 12de302530..545ac7b46e 100644 --- a/examples/audioExamples/acAudioSearching/ACAudioSearchAndInject.js +++ b/examples/audioExamples/acAudioSearching/ACAudioSearchAndInject.js @@ -25,10 +25,10 @@ Agent.isAvatar = true; var DEFAULT_SOUND_DATA = { volume: 0.5, loop: false, - interval: -1, // An interval of -1 means this sound only plays once (if it's non-looping) (In seconds) - intervalSpread: 0 // amount of randomness to add to the interval + playbackGap: 1000, // in ms + playbackGapRange: 0 // in ms }; -var MIN_PLAY_INTERVAL = 200; +var MIN_PLAYBACK_GAP = 0; var UPDATE_TIME = 100; var EXPIRATION_TIME = 5000; @@ -90,16 +90,16 @@ function handleActiveSoundEntities() { soundProperties.soundInjector.restart(); } soundProperties.readyToPlay = false; - } else if (soundProperties.sound && soundProperties.loop === false && soundProperties.interval !== -1) { + } else if (soundProperties.sound && soundProperties.loop === false) { // We need to check all of our entities that are not looping but have an interval associated with them // to see if it's time for them to play again soundProperties.timeSinceLastPlay += UPDATE_TIME; - if (soundProperties.timeSinceLastPlay > soundProperties.currentInterval) { + if (soundProperties.timeSinceLastPlay > soundProperties.clipDuration + soundProperties.currentPlaybackGap) { soundProperties.readyToPlay = true; soundProperties.timeSinceLastPlay = 0; // Now let's get our new current interval - soundProperties.currentInterval = soundProperties.interval + randFloat(-soundProperties.intervalSpread, soundProperties.intervalSpread); - soundProperties.currentInterval = Math.max(MIN_PLAY_INTERVAL, soundProperties.currentInterval); + soundProperties.currentPlaybackGap = soundProperties.playbackGap + randFloat(-soundProperties.playbackGapRange, soundProperties.playbackGapRange); + soundProperties.currentPlaybackGap = Math.max(MIN_PLAYBACK_GAP, soundProperties.currentPlaybackGap); } } } @@ -117,8 +117,8 @@ function handleFoundSoundEntities(entities) { url: soundData.url, volume: soundData.volume || DEFAULT_SOUND_DATA.volume, loop: soundData.loop || DEFAULT_SOUND_DATA.loop, - interval: soundData.interval || DEFAULT_SOUND_DATA.interval, - intervalSpread: soundData.intervalSpread || DEFAULT_SOUND_DATA.intervalSpread, + playbackGap: soundData.playbackGap || DEFAULT_SOUND_DATA.playbackGap, + playbackGapRange: soundData.playbackGapRange || DEFAULT_SOUND_DATA.playbackGapRange, readyToPlay: false, position: Entities.getEntityProperties(entity, "position").position, timeSinceLastPlay: 0, @@ -126,10 +126,10 @@ function handleFoundSoundEntities(entities) { isDownloaded: false }; - if (soundProperties.interval !== -1) { - soundProperties.currentInterval = soundProperties.interval + randFloat(-soundProperties.intervalSpread, soundProperties.intervalSpread); - soundProperties.currentInterval = Math.max(MIN_PLAY_INTERVAL, soundProperties.currentInterval); - } + + soundProperties.currentPlaybackGap = soundProperties.playbackGap + randFloat(-soundProperties.playbackGapRange, soundProperties.playbackGapRange); + soundProperties.currentPlaybackGap = Math.max(MIN_PLAYBACK_GAP, soundProperties.currentPlaybackGap); + soundEntityMap[entity] = soundProperties; if (!soundUrls[soundData.url]) { @@ -141,6 +141,7 @@ function handleFoundSoundEntities(entities) { soundProperties.sound = sound; soundProperties.readyToPlay = true; soundProperties.isDownloaded = true; + soundProperties.clipDuration = sound.getClipDuration() * 1000; soundEntityMap[entity] = soundProperties; }); } else { @@ -163,17 +164,17 @@ function handleFoundSoundEntities(entities) { function checkForSoundPropertyChanges(currentProps, newProps) { var needsNewInjector = false; - if (currentProps.interval !== newProps.interval && !currentProps.loop) { - // interval only applies to non looping sounds - currentProps.interval = newProps.interval; - currentProps.currentInterval = currentProps.interval + randFloat(-currentProps.intervalSpread, currentProps.intervalSpread); - currentProps.currentInterval = Math.max(MIN_PLAY_INTERVAL, currentProps.currentInterval); + if (currentProps.playbackGap !== newProps.playbackGap && !currentProps.loop) { + // playbackGap only applies to non looping sounds + currentProps.playbackGap = newProps.playbackGap; + currentProps.currentPlaybackGap = currentProps.playbackGap + randFloat(-currentProps.playbackGapRange, currentProps.playbackGapRange); + currentProps.currentPlaybackGap = Math.max(MIN_PLAYBACK_GAP, currentProps.currentPlaybackGap); currentProps.readyToPlay = true; } if (currentProps.intervalSpread !== currentProps.intervalSpread) { - currentProps.currentInterval = currentProps.interval + randFloat(-currentProps.intervalSpread, currentProps.intervalSpread); - currentProps.currentInterval = Math.max(MIN_PLAY_INTERVAL, currentProps.currentInterval); + currentProps.currentPlaybackGap = currentProps.interval + randFloat(-currentProps.intervalSpread, currentProps.intervalSpread); + currentProps.currentPlaybackGap = Math.max(MIN_PLAYBACK_GAP, currentProps.currentPlaybackGap); } if (currentProps.volume !== newProps.volume) { currentProps.volume = newProps.volume; @@ -187,6 +188,7 @@ function checkForSoundPropertyChanges(currentProps, newProps) { currentProps.isDownloaded = false; sound.ready.connect(function() { currentProps.sound = sound; + currentProps.clipDuration = sound.getClipDuration() * 1000; currentProps.isDownloaded = true; }); } else { diff --git a/examples/audioExamples/acAudioSearching/acAudioSearchCompatibleEntitySpawner.js b/examples/audioExamples/acAudioSearching/acAudioSearchCompatibleEntitySpawner.js index 95737d6a5c..2f957ecbed 100644 --- a/examples/audioExamples/acAudioSearching/acAudioSearchCompatibleEntitySpawner.js +++ b/examples/audioExamples/acAudioSearching/acAudioSearchCompatibleEntitySpawner.js @@ -26,8 +26,8 @@ var userData = { url: "https://s3-us-west-1.amazonaws.com/hifi-content/eric/Sounds/dove2.wav", volume: 0.3, loop: false, - interval: 2000, // In ms - intervalSpread: 1000 // In ms + playbackGap: 2000, // In ms - time to wait in between clip plays + playbackGapRange: 1000 // In ms - the range to wait in between clip plays } } diff --git a/libraries/audio/src/Sound.h b/libraries/audio/src/Sound.h index 5affaeb348..8c13f4b257 100644 --- a/libraries/audio/src/Sound.h +++ b/libraries/audio/src/Sound.h @@ -32,7 +32,8 @@ public: const QByteArray& getByteArray() { return _byteArray; } public slots: - float getClipLength() const { return _clipLength; } + // _clipLength is in seconds + float getClipDuration() const { return _clipDuration; } signals: void ready(); @@ -41,7 +42,7 @@ private: QByteArray _byteArray; bool _isStereo; bool _isReady; - float _clipLength; + float _clipDuration; void downSample(const QByteArray& rawAudioByteArray); void interpretAsWav(const QByteArray& inputAudioByteArray, QByteArray& outputAudioByteArray); From b60ba0c5a7d694f9983b7bc7b544ac7aef74ad6c Mon Sep 17 00:00:00 2001 From: ericrius1 Date: Mon, 8 Feb 2016 16:22:05 -0800 Subject: [PATCH 35/37] can now change loop --- .../acAudioSearching/ACAudioSearchAndInject.js | 18 ++++++++++++++---- .../acAudioSearchCompatibleEntitySpawner.js | 4 ++-- libraries/audio/src/Sound.cpp | 3 +-- libraries/audio/src/Sound.h | 8 +++----- 4 files changed, 20 insertions(+), 13 deletions(-) diff --git a/examples/audioExamples/acAudioSearching/ACAudioSearchAndInject.js b/examples/audioExamples/acAudioSearching/ACAudioSearchAndInject.js index 545ac7b46e..d20e132113 100644 --- a/examples/audioExamples/acAudioSearching/ACAudioSearchAndInject.js +++ b/examples/audioExamples/acAudioSearching/ACAudioSearchAndInject.js @@ -141,15 +141,19 @@ function handleFoundSoundEntities(entities) { soundProperties.sound = sound; soundProperties.readyToPlay = true; soundProperties.isDownloaded = true; - soundProperties.clipDuration = sound.getClipDuration() * 1000; + soundProperties.clipDuration = sound.duration * 1000; soundEntityMap[entity] = soundProperties; + + print("DURATION " + soundProperties.clipDuration); }); } else { // We already have sound downloaded, so just add it to map right away soundProperties.sound = soundUrls[soundData.url]; + soundProperties.clipDuration = soundProperties.sound.duration * 1000; soundProperties.readyToPlay = true; soundProperties.isDownloaded = true; soundEntityMap[entity] = soundProperties; + print("DURATION " + soundProperties.clipDuration); } } else { //If this sound is in our map already, we want to reset timeWithoutAvatarInRange @@ -172,8 +176,8 @@ function checkForSoundPropertyChanges(currentProps, newProps) { currentProps.readyToPlay = true; } - if (currentProps.intervalSpread !== currentProps.intervalSpread) { - currentProps.currentPlaybackGap = currentProps.interval + randFloat(-currentProps.intervalSpread, currentProps.intervalSpread); + if (currentProps.playbackGapRange !== currentProps.playbackGapRange) { + currentProps.currentPlaybackGap = currentProps.playbackGap + randFloat(-currentProps.playbackGapRange, currentProps.playbackGapRange); currentProps.currentPlaybackGap = Math.max(MIN_PLAYBACK_GAP, currentProps.currentPlaybackGap); } if (currentProps.volume !== newProps.volume) { @@ -188,14 +192,20 @@ function checkForSoundPropertyChanges(currentProps, newProps) { currentProps.isDownloaded = false; sound.ready.connect(function() { currentProps.sound = sound; - currentProps.clipDuration = sound.getClipDuration() * 1000; + currentProps.clipDuration = sound.duration * 1000; currentProps.isDownloaded = true; }); } else { currentProps.sound = sound; + currentProps.clipDuration = sound.duration * 1000; } needsNewInjector = true; } + + if (currentProps.loop !== newProps.loop) { + currentProps.loop = newProps.loop; + needsNewInjector = true; + } if (needsNewInjector) { // If we were looping we need to stop that so new changes are applied currentProps.soundInjector.stop(); diff --git a/examples/audioExamples/acAudioSearching/acAudioSearchCompatibleEntitySpawner.js b/examples/audioExamples/acAudioSearching/acAudioSearchCompatibleEntitySpawner.js index 2f957ecbed..455ff13427 100644 --- a/examples/audioExamples/acAudioSearching/acAudioSearchCompatibleEntitySpawner.js +++ b/examples/audioExamples/acAudioSearching/acAudioSearchCompatibleEntitySpawner.js @@ -25,9 +25,9 @@ var userData = { soundKey: { url: "https://s3-us-west-1.amazonaws.com/hifi-content/eric/Sounds/dove2.wav", volume: 0.3, - loop: false, + loop: true, playbackGap: 2000, // In ms - time to wait in between clip plays - playbackGapRange: 1000 // In ms - the range to wait in between clip plays + playbackGapRange: 0 // In ms - the range to wait in between clip plays } } diff --git a/libraries/audio/src/Sound.cpp b/libraries/audio/src/Sound.cpp index e3efe9b141..808fd2aa0c 100644 --- a/libraries/audio/src/Sound.cpp +++ b/libraries/audio/src/Sound.cpp @@ -258,8 +258,7 @@ void Sound::interpretAsWav(const QByteArray& inputAudioByteArray, QByteArray& ou qCDebug(audio) << "Error reading WAV file"; } - _clipLength = (float) (outputAudioByteArraySize / (fileHeader.wave.sampleRate * fileHeader.wave.numChannels * fileHeader.wave.bitsPerSample / 8.0f)); - + _duration = (float) (outputAudioByteArraySize / (fileHeader.wave.sampleRate * fileHeader.wave.numChannels * fileHeader.wave.bitsPerSample / 8.0f)); } else { qCDebug(audio) << "Could not read wav audio file header."; diff --git a/libraries/audio/src/Sound.h b/libraries/audio/src/Sound.h index 8c13f4b257..91456f2fff 100644 --- a/libraries/audio/src/Sound.h +++ b/libraries/audio/src/Sound.h @@ -22,19 +22,17 @@ class Sound : public Resource { Q_OBJECT Q_PROPERTY(bool downloaded READ isReady) + Q_PROPERTY(float duration READ getDuration) public: Sound(const QUrl& url, bool isStereo = false); bool isStereo() const { return _isStereo; } bool isReady() const { return _isReady; } + float getDuration() { return _duration; } const QByteArray& getByteArray() { return _byteArray; } -public slots: - // _clipLength is in seconds - float getClipDuration() const { return _clipDuration; } - signals: void ready(); @@ -42,7 +40,7 @@ private: QByteArray _byteArray; bool _isStereo; bool _isReady; - float _clipDuration; + float _duration; // In seconds void downSample(const QByteArray& rawAudioByteArray); void interpretAsWav(const QByteArray& inputAudioByteArray, QByteArray& outputAudioByteArray); From 85ddb7100c9bfd6d23b82aab8f3714ffe0114d52 Mon Sep 17 00:00:00 2001 From: ericrius1 Date: Mon, 8 Feb 2016 16:51:04 -0800 Subject: [PATCH 36/37] fixed gap range bug --- .../audioExamples/acAudioSearching/ACAudioSearchAndInject.js | 3 +-- .../acAudioSearching/acAudioSearchCompatibleEntitySpawner.js | 4 ++-- 2 files changed, 3 insertions(+), 4 deletions(-) diff --git a/examples/audioExamples/acAudioSearching/ACAudioSearchAndInject.js b/examples/audioExamples/acAudioSearching/ACAudioSearchAndInject.js index d20e132113..f7fbb2140b 100644 --- a/examples/audioExamples/acAudioSearching/ACAudioSearchAndInject.js +++ b/examples/audioExamples/acAudioSearching/ACAudioSearchAndInject.js @@ -144,7 +144,6 @@ function handleFoundSoundEntities(entities) { soundProperties.clipDuration = sound.duration * 1000; soundEntityMap[entity] = soundProperties; - print("DURATION " + soundProperties.clipDuration); }); } else { // We already have sound downloaded, so just add it to map right away @@ -153,7 +152,6 @@ function handleFoundSoundEntities(entities) { soundProperties.readyToPlay = true; soundProperties.isDownloaded = true; soundEntityMap[entity] = soundProperties; - print("DURATION " + soundProperties.clipDuration); } } else { //If this sound is in our map already, we want to reset timeWithoutAvatarInRange @@ -177,6 +175,7 @@ function checkForSoundPropertyChanges(currentProps, newProps) { } if (currentProps.playbackGapRange !== currentProps.playbackGapRange) { + currentProps.playbackGapRange = newProps.playbackGapRange; currentProps.currentPlaybackGap = currentProps.playbackGap + randFloat(-currentProps.playbackGapRange, currentProps.playbackGapRange); currentProps.currentPlaybackGap = Math.max(MIN_PLAYBACK_GAP, currentProps.currentPlaybackGap); } diff --git a/examples/audioExamples/acAudioSearching/acAudioSearchCompatibleEntitySpawner.js b/examples/audioExamples/acAudioSearching/acAudioSearchCompatibleEntitySpawner.js index 455ff13427..96516af45f 100644 --- a/examples/audioExamples/acAudioSearching/acAudioSearchCompatibleEntitySpawner.js +++ b/examples/audioExamples/acAudioSearching/acAudioSearchCompatibleEntitySpawner.js @@ -25,9 +25,9 @@ var userData = { soundKey: { url: "https://s3-us-west-1.amazonaws.com/hifi-content/eric/Sounds/dove2.wav", volume: 0.3, - loop: true, + loop: false, playbackGap: 2000, // In ms - time to wait in between clip plays - playbackGapRange: 0 // In ms - the range to wait in between clip plays + playbackGapRange: 500 // In ms - the range to wait in between clip plays } } From 3acc077bbd45f4ec637c54ea316d115e2ed86cb9 Mon Sep 17 00:00:00 2001 From: ericrius1 Date: Mon, 8 Feb 2016 17:47:57 -0800 Subject: [PATCH 37/37] replaced sound url for example entity --- .../audioExamples/acAudioSearching/ACAudioSearchAndInject.js | 1 + .../acAudioSearching/acAudioSearchCompatibleEntitySpawner.js | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/examples/audioExamples/acAudioSearching/ACAudioSearchAndInject.js b/examples/audioExamples/acAudioSearching/ACAudioSearchAndInject.js index f7fbb2140b..f7e983d683 100644 --- a/examples/audioExamples/acAudioSearching/ACAudioSearchAndInject.js +++ b/examples/audioExamples/acAudioSearching/ACAudioSearchAndInject.js @@ -178,6 +178,7 @@ function checkForSoundPropertyChanges(currentProps, newProps) { currentProps.playbackGapRange = newProps.playbackGapRange; currentProps.currentPlaybackGap = currentProps.playbackGap + randFloat(-currentProps.playbackGapRange, currentProps.playbackGapRange); currentProps.currentPlaybackGap = Math.max(MIN_PLAYBACK_GAP, currentProps.currentPlaybackGap); + currentProps.readyToPlay = true; } if (currentProps.volume !== newProps.volume) { currentProps.volume = newProps.volume; diff --git a/examples/audioExamples/acAudioSearching/acAudioSearchCompatibleEntitySpawner.js b/examples/audioExamples/acAudioSearching/acAudioSearchCompatibleEntitySpawner.js index 96516af45f..126635ee7a 100644 --- a/examples/audioExamples/acAudioSearching/acAudioSearchCompatibleEntitySpawner.js +++ b/examples/audioExamples/acAudioSearching/acAudioSearchCompatibleEntitySpawner.js @@ -23,7 +23,7 @@ var center = Vec3.sum(MyAvatar.position, Vec3.multiply(3, Quat.getFront(orientat var SOUND_DATA_KEY = "soundKey"; var userData = { soundKey: { - url: "https://s3-us-west-1.amazonaws.com/hifi-content/eric/Sounds/dove2.wav", + url: "http://hifi-content.s3.amazonaws.com/DomainContent/Junkyard/Sounds/ClothSail/cloth_sail3.L.wav", volume: 0.3, loop: false, playbackGap: 2000, // In ms - time to wait in between clip plays