SDL Audio tcod.sdl.audio
¶
SDL2 audio playback and recording tools.
This module includes SDL’s low-level audio API and a naive implementation of an SDL mixer. If you have experience with audio mixing then you might be better off writing your own mixer or modifying the existing one which was written using Python/Numpy.
This module is designed to integrate with the wider Python ecosystem. It leaves the loading to sound samples to other libraries like SoundFile.
Example:
# Synchronous audio example using SDL's low-level API.
import time
import soundfile # pip install soundfile
import tcod.sdl.audio
device = tcod.sdl.audio.open() # Open the default output device.
sound, sample_rate = soundfile.read("example_sound.wav", dtype="float32") # Load an audio sample using SoundFile.
converted = device.convert(sound, sample_rate) # Convert this sample to the format expected by the device.
device.queue_audio(converted) # Play audio synchronously by appending it to the device buffer.
while device.queued_samples: # Wait until device is done playing.
time.sleep(0.001)
Example:
# Asynchronous audio example using BasicMixer.
import time
import soundfile # pip install soundfile
import tcod.sdl.audio
mixer = tcod.sdl.audio.BasicMixer(tcod.sdl.audio.open()) # Setup BasicMixer with the default audio output.
sound, sample_rate = soundfile.read("example_sound.wav") # Load an audio sample using SoundFile.
sound = mixer.device.convert(sound, sample_rate) # Convert this sample to the format expected by the device.
channel = mixer.play(sound) # Start asynchronous playback, audio is mixed on a separate Python thread.
while channel.busy: # Wait until the sample is done playing.
time.sleep(0.001)
Added in version 13.5.
- class tcod.sdl.audio.AllowedChanges(value, names=None, *, module=None, qualname=None, type=None, start=1, boundary=None)[source]¶
Which parameters are allowed to be changed when the values given are not supported.
- ANY = 15¶
- CHANNELS = 4¶
- FORMAT = 2¶
- FREQUENCY = 1¶
- NONE = 0¶
- SAMPLES = 8¶
- class tcod.sdl.audio.AudioDevice(device_id: int, capture: bool, spec: Any)[source]¶
An SDL audio device.
Open new audio devices using
tcod.sdl.audio.open
.When you use this object directly the audio passed to
queue_audio
is always played synchronously. For more typical asynchronous audio you should pass an AudioDevice toBasicMixer
.Changed in version 16.0: Can now be used as a context which will close the device on exit.
- __exit__(type: type[BaseException] | None, value: BaseException | None, traceback: TracebackType | None) None [source]¶
Close the device when exiting the context.
- close() None [source]¶
Close this audio device. Using this object after it has been closed is invalid.
- convert(sound: ArrayLike, rate: int | None = None) NDArray[Any] [source]¶
Convert an audio sample into a format supported by this device.
Returns the converted array. This might be a reference to the input array if no conversion was needed.
- Parameters:
sound – An ArrayLike sound sample.
rate – The sample-rate of the input array. If None is given then it’s assumed to be the same as the device.
Added in version 13.6.
See also
- queue_audio(samples: numpy.typing.ArrayLike) None [source]¶
Append audio samples to the audio data queue.
- property callback: Callable[[AudioDevice, NDArray[Any]], None]¶
If the device was opened with a callback enabled, then you may get or set the callback with this attribute.
- format: Final[np.dtype[Any]]¶
The format used for audio samples with this device.
- spec: Final[Any]¶
The SDL_AudioSpec as a CFFI object.
- class tcod.sdl.audio.BasicMixer(device: AudioDevice)[source]¶
An SDL sound mixer implemented in Python and Numpy.
Added in version 13.6.
- get_channel(key: Hashable) Channel [source]¶
Return a channel tied to with the given key.
Channels are initialized as you access them with this function.
int
channels starting from zero are used internally.This can be used to generate a
"music"
channel for example.
- play(sound: numpy.typing.ArrayLike, *, volume: float | tuple[float, ...] = 1.0, loops: int = 0, on_end: Callable[[Channel], None] | None = None) Channel [source]¶
Play a sound, return the channel the sound is playing on.
- Parameters:
sound – The sound to play. This a Numpy array matching the format of the loaded audio device.
volume – The volume to play the sound at. You can also pass a tuple of floats to set the volume for each channel/speaker.
loops – How many times to play the sound, -1 can be used to loop the sound forever.
on_end – A function to call when this sound has ended. This is called with the
Channel
which was playing the sound.
- run() None [source]¶
Method representing the thread’s activity.
You may override this method in a subclass. The standard run() method invokes the callable object passed to the object’s constructor as the target argument, if any, with sequential and keyword arguments taken from the args and kwargs arguments, respectively.
- device¶
The
AudioDevice
- class tcod.sdl.audio.Channel[source]¶
An audio channel for
BasicMixer
. UseBasicMixer.get_channel
to initialize this object.Added in version 13.6.
- play(sound: numpy.typing.ArrayLike, *, volume: float | tuple[float, ...] = 1.0, loops: int = 0, on_end: Callable[[Channel], None] | None = None) None [source]¶
Play an audio sample, stopping any audio currently playing on this channel.
Parameters are the same as
BasicMixer.play
.
- mixer: BasicMixer¶
The
BasicMixer
is channel belongs to.
- tcod.sdl.audio.convert_audio(in_sound: ArrayLike, in_rate: int, *, out_rate: int, out_format: DTypeLike, out_channels: int) NDArray[Any] [source]¶
Convert an audio sample into a format supported by this device.
Returns the converted array. This might be a reference to the input array if no conversion was needed.
- Parameters:
in_sound – The input ArrayLike sound sample. Input format and channels are derived from the array.
in_rate – The sample-rate of the input array.
out_rate – The sample-rate of the output array.
out_format – The output format of the converted array.
out_channels – The number of audio channels of the output array.
Added in version 13.6.
Changed in version 16.0: Now converts floating types to np.float32 when SDL doesn’t support the specific format.
See also
- tcod.sdl.audio.get_capture_devices() Iterator[str] [source]¶
Iterate over the available audio capture devices.
- tcod.sdl.audio.get_devices() Iterator[str] [source]¶
Iterate over the available audio output devices.
- tcod.sdl.audio.open(name: str | None = None, capture: bool = False, *, frequency: int = 44100, format: DTypeLike = <class 'numpy.float32'>, channels: int = 2, samples: int = 0, allowed_changes: AllowedChanges = <AllowedChanges.NONE: 0>, paused: bool = False, callback: None | Literal[True] | Callable[[AudioDevice, NDArray[Any]], None] = None) AudioDevice [source]¶
Open an audio device for playback or capture and return it.
- Parameters:
name – The name of the device to open, or None for the most reasonable default.
capture – True if this is a recording device, or False if this is an output device.
frequency – The desired sample rate to open the device with.
format – The data format to use for samples as a NumPy dtype.
channels – The number of speakers for the device. 1, 2, 4, or 6 are typical options.
samples – The desired size of the audio buffer, must be a power of two.
allowed_changes – By default if the hardware does not support the desired format than SDL will transparently convert between formats for you. Otherwise you can specify which parameters are allowed to be changed to fit the hardware better.
paused – If True then the device will begin in a paused state. It can then be unpaused by assigning False to
AudioDevice.paused
.callback – If None then this device will be opened in push mode and you’ll have to use
AudioDevice.queue_audio
to send audio data orAudioDevice.dequeue_audio
to receive it. If a callback is given then you can change it later, but you can not enable or disable the callback on an opened device. If True then a default callback which plays silence will be used, this is useful if you need the audio device before your callback is ready.
If a callback is given then it will be called with the AudioDevice and a Numpy buffer of the data stream. This callback will be run on a separate thread. Exceptions not handled by the callback become unraiseable and will be handled by
sys.unraisablehook
.