From c600e0a3e0f00a57ba9008b382cf428e06bc2f57 Mon Sep 17 00:00:00 2001 From: janwas Date: Sun, 8 Jan 2006 02:05:44 +0000 Subject: [PATCH] design notes from meeting: ambient sound This was SVN commit r3336. --- source/sound/ambient_design.txt | 85 +++++++++++++++++++++++++++++++++ 1 file changed, 85 insertions(+) create mode 100644 source/sound/ambient_design.txt diff --git a/source/sound/ambient_design.txt b/source/sound/ambient_design.txt new file mode 100644 index 0000000000..d66cf8f1d4 --- /dev/null +++ b/source/sound/ambient_design.txt @@ -0,0 +1,85 @@ +PLAYING AMBIENT SOUND WHEN CAMERA IS OVER BUILDING +================================================== + +data flow: +C++ JS +> list of visible entities (1) + < list of sound requests and their weights +list of changed sounds + +C++ code generates list of entities on screen + rationale: done in C++ for performance and to avoid having to expose the "patch" subdivision scheme to JS. + UPDATE: this is much thornier than expected. + 1) we only want stuff that is visible to be played. hearing things off screen would be distressing and weird + 2) don't play sound for buildings in FoW, to prevent "audio spying" + most straightforward way is simply scan all entities; if building, check against visible frustum. + if inside AND within 3d distance cutoff of viewer pos, add to visible_building + optimization for later: get all patches within 3d distance cutoff; discard all not within frustum; only test + entities within those remaining patches. +pass that to JS decideWhatToPlay +it returns list of sounds it wants playing + format: see AmbientSoundReq below +C++ sound engine compares its list of currently sounds; + fades out those no longer wanted and starts new ones immediately + + +new entity properties needed: +----------------------------- +- ambientGroup: a soundGroup of several sounds; one is picked at random to be played (see below) +- priority: to determine which entity should trump the others in a crowded city. + + +// weight is so that we can play several ambient sounds at a time, but ones for buildings at edge of screen are quieter +// values: 0..1; probably calculated from distance to camera +type AmbientSoundReq = (SoundGroupString, weight) + +// (suggestion only; may be revised if too much cacophony/constant sound results) +JS_decideWhatToPlay(in HEntity visible_ents[], out AmbientSoundReq desired_ambient_sounds[]) +{ +// * "important" means the building is at center of attention and should mostly override the other sounds. +// this is complicated as well. the camera may have any orientation, especially in cinematic mode; +// that means we can't just rely on casting a ray from viewer through middle screen pixel to terrain. +// our building list already covers only the visible ones, so we can use 3d distance from viewer +// (without worrying about including buildings behind us i.e. out of sight). +// important := fairly small distance (covers the case where users zoom really close to a building) OR +// building is close to center of screen (as determined via ray cast method; skip this if the camera +// is weird, i.e. looking above the horizon, in which case the ray cast would fail). +// note: not playing sounds when looking down vertically at the town but zoomed out very far is ok (desirable even). + if an entity is important(*) + desired_ambient_sounds[i++] = ent.ambientGroup + + forall ambient types (farm, dock etc.) in decreasing order of priority + stop if >= 3 sounds in list + if enough buildings on screen + desired_ambient_sounds[i++] = ent.ambientGroup + +maybe add some random variation to spice things up? (i.e. also play some other building sounds; +don't always have one building override the others) +} + + +C++ code keeps a list of all active sounds: +type ActiveSound = (Handle, SoundGroupString) +ActiveSound active_sound_list[] + +Handle startPlayingAmbient(soundGroup, weight) +{ + filename = soundGroup.pickRandom() + return snd_play(filename, globalAmbientVolume*soundGroup.volume*weight) +} + +updateAmbientSounds(desired_ambient_sounds) +{ + for all in desired_ambient_sounds but not active_sound_list: + handle = startPlayingAmbient(amb.group, amb.weight) + active_sound_list[i++] = (handle, amb.group) + + for all in active_sound_list but not desired_ambient_sounds: + snd_fade(OUT, active.handle) +} + + + +RANDOMIZED SOUNDS +================================================== +(needed for ambient and normal battle sounds) \ No newline at end of file