Skip to content

Instantly share code, notes, and snippets.

@cozza13
Created December 19, 2016 21:28
Show Gist options
  • Save cozza13/ef9cfa73b49a07e5fc2e1caa603134f5 to your computer and use it in GitHub Desktop.
Save cozza13/ef9cfa73b49a07e5fc2e1caa603134f5 to your computer and use it in GitHub Desktop.
// ambientSound.js
//
// This entity script will allow you to create an ambient sound that loops when a person is within a given
// range of this entity. Great way to add one or more ambisonic soundfields to your environment.
//
// In the userData section for the entity, add two values:
// userData.SoundURL should be a string giving the URL to the sound file. Defaults to 100 meters if not set.
// userData.range should be an integer for the max distance away from the entity where the sound will be audible.
// userData.volume is the max volume at which the clip should play.
//
// Note: When you update the above values, you need to reload the entity script for it to see the changes. Also,
// remember that the entity has to be visible to the user for the sound to play at all, so make sure the entity is
// large enough to be loaded at the range you set, particularly for large ranges.
//
// Copyright 2016 High Fidelity, Inc.
//
// Distributed under the Apache License, Version 2.0.
// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
//
(function(){
// This sample clip and range will be used if you don't add userData to the entity (see above)
var DEFAULT_RANGE = 100;
var DEFAULT_URL = "http://hifi-content.s3.amazonaws.com/ken/samples/forest_ambiX.wav";
var DEFAULT_VOLUME = 1.0;
var soundURL = DEFAULT_URL;
var range = DEFAULT_RANGE;
var maxVolume = DEFAULT_VOLUME;
var UPDATE_INTERVAL_MSECS = 100;
var entity;
var ambientSound;
var center;
var soundPlaying = false;
var updateTimer = false;
var WANT_DEBUG = false;
function debugPrint(string) {
if (WANT_DEBUG) {
print(string);
}
}
this.preload = function(entityID) {
// Load the sound and range from the entity userData fields, and note the position of the entity.
debugPrint("Ambient sound preload");
entity = entityID;
var props = Entities.getEntityProperties(entityID, [ "userData" ]);
var data = JSON.parse(props.userData);
if (data.soundURL) {
soundURL = data.soundURL;
debugPrint("Read ambient sound URL: " + soundURL);
}
ambientSound = SoundCache.getSound(soundURL);
if (data.range) {
range = data.range;
debugPrint("Read ambient sound range: " + range);
}
if (data.volume) {
maxVolume = data.volume;
debugPrint("Read ambient sound volume: " + maxVolume);
}
updateTimer = Script.setInterval(this.update, UPDATE_INTERVAL_MSECS);
};
this.update = function() {
// Every UPDATE_INTERVAL_MSECS, update the volume of the ambient sound based on distance from my avatar
var HYSTERESIS_FRACTION = 0.1;
var props = Entities.getEntityProperties(entity, [ "position" ]);
center = props.position;
var distance = Vec3.length(Vec3.subtract(MyAvatar.position, center));
if (distance <= range) {
var volume = (1.0 - distance / range) * maxVolume;
if (!soundPlaying && ambientSound.downloaded) {
soundPlaying = Audio.playSound(ambientSound, { loop: true, volume: volume });
debugPrint("Starting ambient sound, volume: " + volume);
Entities.editEntity(entity, { color: { red: 255, green: 0, blue: 0 }});
} else if (soundPlaying && soundPlaying.playing) {
soundPlaying.setOptions( { volume: volume } );
}
} else if (soundPlaying && soundPlaying.playing && (distance > range * HYSTERESIS_FRACTION)) {
soundPlaying.stop();
soundPlaying = false;
Entities.editEntity(entity, { color: { red: 128, green: 128, blue: 128 }});
debugPrint("Out of range, stopping ambient sound");
}
}
this.unload = function(entityID) {
debugPrint("Ambient sound unload");
if (updateTimer) {
Script.clearInterval(updateTimer);
}
if (soundPlaying && soundPlaying.playing) {
soundPlaying.stop();
}
};
})
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment