Skip to content

Commit

Permalink
Add SDL audio device example
Browse files Browse the repository at this point in the history
  • Loading branch information
HexDecimal committed Oct 25, 2023
1 parent b399f48 commit 783bfa9
Show file tree
Hide file tree
Showing 2 changed files with 49 additions and 0 deletions.
48 changes: 48 additions & 0 deletions examples/audio_tone.py
@@ -0,0 +1,48 @@
#!/usr/bin/env python3
"""Shows how to use tcod.sdl.audio to play a custom-made audio stream.
Opens an audio device using SDL and plays a square wave for 1 second.
"""
import math
import time
from typing import Any

import attrs
import numpy as np
from numpy.typing import NDArray
from scipy import signal # type: ignore

import tcod.sdl.audio

VOLUME = 10 ** (-12 / 10) # -12dB, square waves can be loud


@attrs.define
class PullWave:
"""Square wave stream generator for an SDL audio device in pull mode."""

time: float = 0.0

def __call__(self, device: tcod.sdl.audio.AudioDevice, stream: NDArray[Any]) -> None:
"""Stream a square wave to SDL on demand.
This function must run faster than the stream duration.
Numpy is used to keep performance within these limits.
"""
sample_rate = device.frequency
n_samples = device.buffer_samples
duration = n_samples / sample_rate
print(f"{duration=} {self.time=}")

t = np.linspace(self.time, self.time + duration, n_samples, endpoint=False)
self.time += duration
wave = signal.square(t * (math.tau * 440)).astype(np.float32)
wave *= VOLUME

stream[:] = device.convert(wave)


if __name__ == "__main__":
with tcod.sdl.audio.open(callback=PullWave()) as device:
print(device)
time.sleep(1)
1 change: 1 addition & 0 deletions requirements.txt
@@ -1,3 +1,4 @@
attrs>=23.1.0
cffi>=1.15
numpy>=1.21.4
pycparser>=2.14
Expand Down

0 comments on commit 783bfa9

Please sign in to comment.