59 lines
1.8 KiB
GDScript
59 lines
1.8 KiB
GDScript
class_name AudioFactory
|
|
extends RefCounted
|
|
## Factory condivisa per suoni procedurali morbidi e sensory-friendly.
|
|
|
|
|
|
static func create_tone(freq: float, duration: float, amp: float = 0.3) -> AudioStreamWAV:
|
|
var sample_rate := 22050
|
|
var num_samples := int(sample_rate * duration)
|
|
var data := PackedByteArray()
|
|
data.resize(num_samples)
|
|
var attack := int(sample_rate * 0.01)
|
|
for i in num_samples:
|
|
var t := float(i) / sample_rate
|
|
var env := 1.0
|
|
if i < attack:
|
|
env = float(i) / attack
|
|
env *= exp(-3.0 * t / duration)
|
|
var value := int(clampf(sin(t * freq * TAU) * env * amp * 127.0, -128.0, 127.0))
|
|
data[i] = value & 0xff
|
|
var stream := AudioStreamWAV.new()
|
|
stream.format = AudioStreamWAV.FORMAT_8_BITS
|
|
stream.mix_rate = sample_rate
|
|
stream.data = data
|
|
return stream
|
|
|
|
|
|
static func create_arpeggio(freqs: Array[float], note_duration: float = 0.12, amp: float = 0.3) -> AudioStreamWAV:
|
|
var sample_rate := 22050
|
|
var samples_per_note := int(sample_rate * note_duration)
|
|
var data := PackedByteArray()
|
|
data.resize(samples_per_note * freqs.size())
|
|
var index := 0
|
|
var attack := int(sample_rate * 0.01)
|
|
for freq in freqs:
|
|
for i in samples_per_note:
|
|
var t := float(i) / sample_rate
|
|
var env := 1.0
|
|
if i < attack:
|
|
env = float(i) / attack
|
|
env *= exp(-3.0 * t / note_duration)
|
|
var value := int(clampf(sin(t * freq * TAU) * env * amp * 127.0, -128.0, 127.0))
|
|
data[index] = value & 0xff
|
|
index += 1
|
|
var stream := AudioStreamWAV.new()
|
|
stream.format = AudioStreamWAV.FORMAT_8_BITS
|
|
stream.mix_rate = sample_rate
|
|
stream.data = data
|
|
return stream
|
|
|
|
|
|
static func play_once(parent: Node, stream: AudioStream, volume_db: float = 0.0) -> AudioStreamPlayer:
|
|
var player := AudioStreamPlayer.new()
|
|
player.stream = stream
|
|
player.volume_db = volume_db
|
|
parent.add_child(player)
|
|
player.finished.connect(player.queue_free)
|
|
player.play()
|
|
return player
|