Sound caching, maintenance ambience improvements (#88752)

## About The Pull Request
ports https://github.com/DaedalusDock/daedalusdock/pull/1123
credit to kapu for the code, I just adapted some of it for us
While testing this I noticed that some ambience sounds have no fades, so
I added them, you can see comparisons here:
<details>
<summary> Click me for comparisons! </summary>


https://github.com/user-attachments/assets/0a93ec2f-7600-4510-9773-e2c721f06613


https://github.com/user-attachments/assets/3328a097-5dbc-402f-9dee-ece5aa7f9479


https://github.com/user-attachments/assets/b94157d4-a8a6-4877-94f6-1f07dc6ba860


https://github.com/user-attachments/assets/dc326c0c-7c8c-46ab-8149-97fd02dcc7f7


https://github.com/user-attachments/assets/e3309d6f-6d8d-4595-8c88-172c406f577d


https://github.com/user-attachments/assets/64109759-cbf6-446f-baf9-5705e1c81662


https://github.com/user-attachments/assets/28c0a112-a758-49d6-9f44-8e451a895d7a


https://github.com/user-attachments/assets/fec33b2e-6704-4d97-9c73-d0e58fef52ef


https://github.com/user-attachments/assets/4dc780bf-3fb4-402a-8803-7aef2968e012


https://github.com/user-attachments/assets/93d63a31-36aa-437f-95bc-840427155701


https://github.com/user-attachments/assets/59fd09d4-207d-4f7c-8355-34fb37981df4


https://github.com/user-attachments/assets/8c14e1e8-75be-4081-acac-d2cea05f8638


https://github.com/user-attachments/assets/3dac481c-62ea-4fd9-93c5-36f8cbbfab9b


https://github.com/user-attachments/assets/c92dd2aa-93f8-4c2e-9e00-7dbef3146280


https://github.com/user-attachments/assets/02baae83-2e51-4d83-8d97-be15bc58c6c9


https://github.com/user-attachments/assets/fcd969ac-7f29-4bb4-873c-30874e13516e


https://github.com/user-attachments/assets/24a053a3-1a71-4758-bb90-149ebc6b50b6


https://github.com/user-attachments/assets/40e7adee-d0bf-4636-b4d0-bc1c5c17688f


</details>

## Why It's Good For The Game

- sound caching will open possibilities for seamless sound loops and
overall knowing the length of a sound file is very useful
- closes https://github.com/tgstation/tgstation/issues/87054
- fade ins and fade outs prevent audio glitches on abrupt audio ends and
are nicer for the ears

## Changelog
🆑 kapu and grungussuss
fix: fixed ambience sounds getting cut off mid play
sound: addes fades for maintenance ambiences
refactor: changed the way maintenance sounds are 
/🆑

---------

Co-authored-by: Kapu1178 <75460809+Kapu1178@users.noreply.github.com>
This commit is contained in:
grungussuss
2025-01-04 17:55:49 -08:00
committed by GitHub
co-authored by Kapu1178
parent 9813815fa9
commit 8603a6ef99
17 changed files with 74 additions and 22 deletions
+3 -4
View File
@@ -34,7 +34,7 @@ SUBSYSTEM_DEF(ambience)
var/area/current_area = get_area(client_mob)
if(!current_area) //Something's gone horribly wrong
stack_trace("[key_name(client_mob)] has somehow ended up in nullspace. WTF did you do")
ambience_listening_clients -= client_iterator
remove_ambience_client(client_iterator)
continue
if(ambience_listening_clients[client_iterator] > world.time)
@@ -59,7 +59,8 @@ SUBSYSTEM_DEF(ambience)
new_sound = sound(new_sound, repeat = 0, wait = 0, volume = volume*volume_modifier, channel = CHANNEL_AMBIENCE)
SEND_SOUND(M, new_sound)
return rand(min_ambience_cooldown, max_ambience_cooldown)
var/sound_length = SSsounds.get_sound_length(new_sound.file)
return sound_length + rand(min_ambience_cooldown, max_ambience_cooldown)
/datum/controller/subsystem/ambience/proc/remove_ambience_client(client/to_remove)
ambience_listening_clients -= to_remove
@@ -67,8 +68,6 @@ SUBSYSTEM_DEF(ambience)
currentrun -= to_remove
/area/station/maintenance
min_ambience_cooldown = 20 SECONDS
max_ambience_cooldown = 35 SECONDS
///A list of rare sound effects to fuck with players. No, it does not contain actual minecraft sounds anymore.
var/static/list/minecraft_cave_noises = list(
+69
View File
@@ -26,9 +26,28 @@ SUBSYSTEM_DEF(sounds)
/// All valid sound files in the sound directory
var/list/all_sounds
// || Sound caching ||
/// k:v list of file_path : length
VAR_PRIVATE/list/sound_lengths
/// A list of sounds to cache upon initialize.
VAR_PRIVATE/list/sounds_to_precache = list()
/// Any errors from precaching.
VAR_PRIVATE/list/precache_errors = list()
/datum/controller/subsystem/sounds/Initialize()
setup_available_channels()
find_all_available_sounds()
if(!(RUST_G))
to_chat(world, span_boldnotice("Sounds subsystem: No rust_g detected."))
return ..()
// Precache ambience sounds
for(var/key in GLOB.ambience_assoc)
sounds_to_precache |= GLOB.ambience_assoc[key]
precache_sounds()
return SS_INIT_SUCCESS
/datum/controller/subsystem/sounds/proc/setup_available_channels()
@@ -156,4 +175,54 @@ SUBSYSTEM_DEF(sounds)
/datum/controller/subsystem/sounds/proc/available_channels_left()
return length(channel_list) - random_channels_min
/datum/controller/subsystem/sounds/proc/precache_sounds()
if(!length(sounds_to_precache))
return
var/list/lengths = rustg_sound_length_list(sounds_to_precache)
precache_errors = lengths[RUSTG_SOUNDLEN_ERRORS]
sound_lengths = lengths[RUSTG_SOUNDLEN_SUCCESSES]
for(var/sound_path in sound_lengths)
sound_lengths[sound_path] = text2num(sound_lengths[sound_path])
sounds_to_precache = null
/// Cache a list of sound lengths.
/datum/controller/subsystem/sounds/proc/cache_sounds(list/paths)
var/list/reconstructed = list()
reconstructed.len = length(paths)
for(var/i in 1 to length(paths))
reconstructed[i] = "[paths[i]]"
var/list/out = rustg_sound_length_list(paths)
var/list/successes = out[RUSTG_SOUNDLEN_SUCCESSES]
for(var/sound_path in successes)
sound_lengths[sound_path] = text2num(successes[sound_path])
/// Cache and return a single sound.
/datum/controller/subsystem/sounds/proc/get_sound_length(file_path)
. = 0
if(!istext(file_path))
if(!isfile(file_path))
CRASH("rustg_sound_length error: Passed non-text object")
if(length("[file_path]")) // Runtime generated RSC references stringify into 0-length strings.
file_path = "[file_path]"
else
CRASH("rustg_sound_length does not support non-static file refs.")
var/cached_length = sound_lengths[file_path]
if(!isnull(cached_length))
return cached_length
var/ret = RUSTG_CALL(RUST_G, "sound_len")(file_path)
var/as_num = text2num(ret)
if(isnull(ret))
. = 0
CRASH("rustg_sound_length error: [ret]")
sound_lengths[file_path] = as_num
return as_num
#undef DATUMLESS
+2 -2
View File
@@ -95,9 +95,9 @@
///The volume of the ambient buzz
var/ambient_buzz_vol = 35
///Used to decide what the minimum time between ambience is
var/min_ambience_cooldown = 30 SECONDS
var/min_ambience_cooldown = 4 SECONDS
///Used to decide what the maximum time between ambience is
var/max_ambience_cooldown = 60 SECONDS
var/max_ambience_cooldown = 10 SECONDS
flags_1 = CAN_BE_DIRTY_1
-2
View File
@@ -278,8 +278,6 @@
ambience_index = AMBIENCE_MINING
flags_1 = CAN_BE_DIRTY_1
sound_environment = SOUND_AREA_ASTEROID
min_ambience_cooldown = 70 SECONDS
max_ambience_cooldown = 220 SECONDS
/area/centcom/asteroid/nearstation
static_lighting = TRUE
-8
View File
@@ -146,8 +146,6 @@
requires_power = TRUE
ambience_index = AMBIENCE_MINING
area_flags = VALID_TERRITORY | UNIQUE_AREA
min_ambience_cooldown = 70 SECONDS
max_ambience_cooldown = 220 SECONDS
/area/lavaland/underground
name = "Lavaland Caves"
@@ -159,8 +157,6 @@
power_light = FALSE
ambience_index = AMBIENCE_MINING
area_flags = VALID_TERRITORY | UNIQUE_AREA | FLORA_ALLOWED
min_ambience_cooldown = 70 SECONDS
max_ambience_cooldown = 220 SECONDS
/area/lavaland/surface/outdoors
name = "Lavaland Wastes"
@@ -206,8 +202,6 @@
power_light = FALSE
requires_power = TRUE
area_flags = UNIQUE_AREA | FLORA_ALLOWED
min_ambience_cooldown = 70 SECONDS
max_ambience_cooldown = 220 SECONDS
/area/icemoon/surface/outdoors // parent that defines if something is on the exterior of the station.
name = "Icemoon Wastes"
@@ -269,8 +263,6 @@
power_equip = FALSE
power_light = FALSE
area_flags = UNIQUE_AREA | FLORA_ALLOWED
min_ambience_cooldown = 70 SECONDS
max_ambience_cooldown = 220 SECONDS
/area/icemoon/underground/unexplored // mobs and megafauna and ruins spawn here
name = "Icemoon Caves"
-2
View File
@@ -16,8 +16,6 @@
flags_1 = CAN_BE_DIRTY_1
sound_environment = SOUND_AREA_SPACE
ambient_buzz = null //Space is deafeningly quiet
min_ambience_cooldown = 195 SECONDS //length of ambispace.ogg
max_ambience_cooldown = 200 SECONDS
/area/space/nearstation
icon_state = "space_near"
@@ -31,8 +31,6 @@
sound_environment = SOUND_AREA_SPACE
ambience_index = AMBIENCE_SPACE
ambient_buzz = null //Space is deafeningly quiet
min_ambience_cooldown = 195 SECONDS //length of ambispace.ogg
max_ambience_cooldown = 200 SECONDS
/area/station/engineering/atmos/project
name = "\improper Atmospherics Project Room"
-2
View File
@@ -4,8 +4,6 @@
ambience_index = AMBIENCE_MEDICAL
airlock_wires = /datum/wires/airlock/medbay
sound_environment = SOUND_AREA_STANDARD_STATION
min_ambience_cooldown = 90 SECONDS
max_ambience_cooldown = 180 SECONDS
/area/station/medical/abandoned
name = "\improper Abandoned Medbay"
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.