changeset 1116:799ba869055d

add: fading for audio tracks
author sam <sam@basx.dev>
date Mon, 15 Apr 2024 22:33:24 +0700
parents a3ab99155209
children f951a42dbb5b
files semicongine/audio.nim
diffstat 1 files changed, 22 insertions(+), 0 deletions(-) [+]
line wrap: on
line diff
--- a/semicongine/audio.nim	Mon Apr 15 20:22:16 2024 +0700
+++ b/semicongine/audio.nim	Mon Apr 15 22:33:24 2024 +0700
@@ -1,3 +1,5 @@
+import std/monotimes
+import std/times
 import std/tables
 import std/locks
 import std/logging except Level
@@ -27,6 +29,9 @@
   Track = object
     playing: Table[uint64, Playback]
     level: Level
+    targetLevel: Level
+    fadeTime: float
+    fadeStep: float
   Mixer* = object
     playbackCounter: uint64
     tracks: Table[string, Track]
@@ -36,6 +41,7 @@
     lock: Lock
     buffers: seq[SoundData]
     currentBuffer: int
+    lastUpdate: MonoTime
 
 proc initMixer*(): Mixer =
   result = Mixer(
@@ -159,6 +165,11 @@
 proc unpause*(mixer: var Mixer, track: string) = mixer.pause(track, false)
 proc unpause*(mixer: var Mixer, playbackId: uint64) = mixer.pause(playbackId, false)
 
+proc fadeTo*(mixer: var Mixer, track: string, level: Level, time: float) =
+  mixer.tracks[track].targetLevel = level
+  mixer.tracks[track].fadeTime = time
+  mixer.tracks[track].fadeStep = level.float - mixer.tracks[track].level.float / time
+
 proc isPlaying*(mixer: var Mixer): bool =
   mixer.lock.withLock():
     for track in mixer.tracks.mvalues:
@@ -189,6 +200,17 @@
   ]
 
 proc updateSoundBuffer(mixer: var Mixer) =
+  let t = getMonoTime()
+  let dt = (t - mixer.lastUpdate).inNanoseconds.float64 / 1_000_000_000'f64
+  mixer.lastUpdate = t
+
+  # update fadings
+  for track in mixer.tracks.mvalues:
+    if track.fadeTime > 0:
+      track.fadeTime -= dt
+      track.level = (track.level.float64 + track.fadeStep.float64 * dt).clamp(Level.low, Level.high)
+      if track.fadeTime <= 0:
+        track.level = track.targetLevel
   # mix
   for i in 0 ..< mixer.buffers[mixer.currentBuffer].len:
     var mixedSample = [0'i16, 0'i16]