2025-03-24 18:13:08 +01:00
|
|
|
class_name Music
|
2025-02-23 10:59:42 +01:00
|
|
|
extends Node
|
|
|
|
|
2025-03-24 18:13:08 +01:00
|
|
|
## While the instruments are manipulated individually to match the gameplay,
|
|
|
|
## they are all regrouped in a single bus dedicated to this specific music.
|
|
|
|
## So we also manipulate the bus itself for the purposes of applying
|
|
|
|
## audio balance and settings and the such more efficiently.
|
|
|
|
|
|
|
|
var bus_index: int = -1
|
|
|
|
var instruments: Array[AudioStreamPlayer] = []
|
|
|
|
|
2025-02-23 10:59:42 +01:00
|
|
|
func _ready() -> void:
|
2025-03-24 18:13:08 +01:00
|
|
|
bus_index = AudioServer.get_bus_index(self.name)
|
|
|
|
if bus_index == -1:
|
|
|
|
AudioServer.add_bus()
|
|
|
|
AudioServer.set_bus_name(AudioServer.bus_count - 1, self.name)
|
|
|
|
bus_index = AudioServer.get_bus_index(self.name)
|
|
|
|
|
|
|
|
var current_effects = AudioServer.get_bus_effect_count(bus_index)
|
|
|
|
for i in current_effects:
|
|
|
|
AudioServer.remove_bus_effect(bus_index, i)
|
|
|
|
|
|
|
|
var children = get_children()
|
|
|
|
for child in children:
|
|
|
|
if child is AudioStreamPlayer:
|
|
|
|
instruments.push_back(child)
|
|
|
|
child.bus = AudioServer.get_bus_name(bus_index)
|
|
|
|
child.volume_db = -50
|
|
|
|
var stream: AudioStreamOggVorbis = child.stream
|
2025-02-23 10:59:42 +01:00
|
|
|
if stream is AudioStreamOggVorbis:
|
|
|
|
stream.loop = true
|
|
|
|
stream.bpm = 124
|
|
|
|
|
2025-03-24 18:13:08 +01:00
|
|
|
for instrument in instruments:
|
|
|
|
if instrument is AudioStreamPlayer:
|
|
|
|
instrument.play()
|
|
|
|
|
|
|
|
func changeVolume(db: float) -> void:
|
|
|
|
AudioServer.set_bus_volume_db(bus_index, db)
|
|
|
|
|
|
|
|
func adaptInstrumentsToVelocity(velocity: float, delta: float) -> void:
|
|
|
|
var instruments_needed = floor(velocity / 8)
|
|
|
|
var instruments_playing = instruments.filter(func(i: AudioStreamPlayer): return i.volume_db > -50)
|
|
|
|
|
|
|
|
for index_p in len(instruments_playing):
|
|
|
|
var playing = instruments_playing[index_p]
|
|
|
|
if index_p + 1 > instruments_needed:
|
|
|
|
playing.volume_db = max(playing.volume_db - (delta * 32), -50)
|
|
|
|
elif playing.volume_db <= 0:
|
|
|
|
playing.volume_db = min(playing.volume_db + (delta * 8), 0)
|
|
|
|
|
|
|
|
if instruments_needed > len(instruments_playing):
|
|
|
|
var instruments_not_playing = instruments.filter(func(i: AudioStreamPlayer): return i.volume_db <= -50)
|
|
|
|
if len(instruments_not_playing):
|
|
|
|
var to_play = instruments_not_playing.pick_random()
|
|
|
|
if is_instance_valid(to_play):
|
|
|
|
to_play.volume_db = min(to_play.volume_db + (delta * 16), 0)
|
|
|
|
|
|
|
|
func fadeOut(seconds: float) -> void:
|
|
|
|
var tween: Tween = create_tween()
|
|
|
|
# https://github.com/godotengine/godot/issues/32882
|
|
|
|
AudioServer.add_bus_effect(bus_index, AudioEffectAmplify.new())
|
|
|
|
var effect_index: int = AudioServer.get_bus_effect_count(bus_index) - 1
|
|
|
|
var effect: AudioEffectAmplify = AudioServer.get_bus_effect(bus_index, effect_index)
|
|
|
|
tween.tween_property(effect, "volume_linear", 0, seconds)
|