This commit is contained in:
elwrcl committed 2026-09-11 18:39:50 +03:00
1 parent 13bc4606f7
commit 5a4ee25fbd
1 file changed
+24 -12
+24 -12
View File
@@ -78,7 +78,9 @@ def synth(duration, rng):
# warble, itself slowly wandering # warble, itself slowly wandering
ph_wander += wander_hz * scale ph_wander += wander_hz * scale
ph_warble += (warble_hz + wander_depth * SINE[int(ph_wander) & TABLE_MASK]) * scale ph_warble += (
warble_hz + wander_depth * SINE[int(ph_wander) & TABLE_MASK]
) * scale
warble = 1.0 - warble_depth + warble_depth * SINE[int(ph_warble) & TABLE_MASK] warble = 1.0 - warble_depth + warble_depth * SINE[int(ph_warble) & TABLE_MASK]
# envelope: near-instant attack, exponential decay # envelope: near-instant attack, exponential decay
@@ -86,11 +88,15 @@ def synth(duration, rng):
if second_kick: if second_kick:
d = t - kick_at d = t - kick_at
if d > 0.0: if d > 0.0:
env += kick_amt * math.exp(-decay * 1.6 * d) * (1.0 - math.exp(-160.0 * d)) env += (
kick_amt * math.exp(-decay * 1.6 * d) * (1.0 - math.exp(-160.0 * d))
)
# opening clunk # opening clunk
ph_thump += thump_f * scale ph_thump += thump_f * scale
thump = thump_amt * SINE[int(ph_thump) & TABLE_MASK] * math.exp(-thump_decay * t) thump = (
thump_amt * SINE[int(ph_thump) & TABLE_MASK] * math.exp(-thump_decay * t)
)
# shadow-mask rattle # shadow-mask rattle
rattle = rattle_amt * (rng.random() * 2.0 - 1.0) * math.exp(-rattle_decay * t) rattle = rattle_amt * (rng.random() * 2.0 - 1.0) * math.exp(-rattle_decay * t)
@@ -98,8 +104,7 @@ def synth(duration, rng):
s = tone * warble * env + thump + rattle s = tone * warble * env + thump + rattle
out[i] = s out[i] = s
a = s if s >= 0.0 else -s a = s if s >= 0.0 else -s
if a > peak: peak = max(peak, a)
peak = a
# normalize, then fade the tail so it never clicks # normalize, then fade the tail so it never clicks
gain = 0.85 / peak if peak > 0.0 else 0.0 gain = 0.85 / peak if peak > 0.0 else 0.0
@@ -110,7 +115,7 @@ def synth(duration, rng):
if i >= n - fade: if i >= n - fade:
s *= (n - i) / fade s *= (n - i) / fade
v = int(s * 32767.0) v = int(s * 32767.0)
pcm[i] = 32767 if v > 32767 else (-32768 if v < -32768 else v) pcm[i] = 32767 if v > 32767 else (max(v, -32768))
return pcm return pcm
@@ -123,11 +128,13 @@ def write_wav(path, pcm):
def play(path, volume): def play(path, volume):
for cmd in (["pw-play", "--volume=%s" % volume, path], for cmd in (
["paplay", path], ["pw-play", f"--volume={volume}", path],
["aplay", "-q", path]): ["paplay", path],
["aplay", "-q", path],
):
try: try:
return subprocess.run(cmd, stderr=subprocess.DEVNULL).returncode return subprocess.run(cmd, stderr=subprocess.DEVNULL).returncode # noqa: PLW1510
except FileNotFoundError: except FileNotFoundError:
continue continue
print("degauss-sound: no player found (pw-play/paplay/aplay)", file=sys.stderr) print("degauss-sound: no player found (pw-play/paplay/aplay)", file=sys.stderr)
@@ -137,8 +144,13 @@ def play(path, volume):
def main(): def main():
ap = argparse.ArgumentParser() ap = argparse.ArgumentParser()
ap.add_argument("-o", "--out", help="write a wav here instead of playing") ap.add_argument("-o", "--out", help="write a wav here instead of playing")
ap.add_argument("-d", "--duration", type=float, default=1.5, ap.add_argument(
help="seconds; match your shader's DURATION (default 1.5)") "-d",
"--duration",
type=float,
default=1.5,
help="seconds; match your shader's DURATION (default 1.5)",
)
ap.add_argument("-s", "--seed", type=int, help="reproducible output") ap.add_argument("-s", "--seed", type=int, help="reproducible output")
ap.add_argument("-v", "--volume", default="0.5", help="pw-play volume") ap.add_argument("-v", "--volume", default="0.5", help="pw-play volume")
args = ap.parse_args() args = ap.parse_args()