Skip to content

Commit 783bfa9

Browse files
committed
Add SDL audio device example
1 parent b399f48 commit 783bfa9

File tree

2 files changed

+49
-0
lines changed

2 files changed

+49
-0
lines changed

examples/audio_tone.py

Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,48 @@
1+
#!/usr/bin/env python3
2+
"""Shows how to use tcod.sdl.audio to play a custom-made audio stream.
3+
4+
Opens an audio device using SDL and plays a square wave for 1 second.
5+
"""
6+
import math
7+
import time
8+
from typing import Any
9+
10+
import attrs
11+
import numpy as np
12+
from numpy.typing import NDArray
13+
from scipy import signal # type: ignore
14+
15+
import tcod.sdl.audio
16+
17+
VOLUME = 10 ** (-12 / 10) # -12dB, square waves can be loud
18+
19+
20+
@attrs.define
21+
class PullWave:
22+
"""Square wave stream generator for an SDL audio device in pull mode."""
23+
24+
time: float = 0.0
25+
26+
def __call__(self, device: tcod.sdl.audio.AudioDevice, stream: NDArray[Any]) -> None:
27+
"""Stream a square wave to SDL on demand.
28+
29+
This function must run faster than the stream duration.
30+
Numpy is used to keep performance within these limits.
31+
"""
32+
sample_rate = device.frequency
33+
n_samples = device.buffer_samples
34+
duration = n_samples / sample_rate
35+
print(f"{duration=} {self.time=}")
36+
37+
t = np.linspace(self.time, self.time + duration, n_samples, endpoint=False)
38+
self.time += duration
39+
wave = signal.square(t * (math.tau * 440)).astype(np.float32)
40+
wave *= VOLUME
41+
42+
stream[:] = device.convert(wave)
43+
44+
45+
if __name__ == "__main__":
46+
with tcod.sdl.audio.open(callback=PullWave()) as device:
47+
print(device)
48+
time.sleep(1)

requirements.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
attrs>=23.1.0
12
cffi>=1.15
23
numpy>=1.21.4
34
pycparser>=2.14

0 commit comments

Comments
 (0)