earwax.sound module

Provides sound-related functions and classes.

exception earwax.sound.AlreadyDestroyed

Bases: earwax.sound.SoundError

This sound has already been destroyed.

class earwax.sound.BufferCache(max_size: int)

Bases: object

A cache for buffers.

Variables:
  • max_size

    The maximum size (in bytes) the cache will be allowed to grow before pruning.

    For reference, 1 KB is 1024, 1 MB is 1024 ** 2, and 1 GB is 1024 ** 3.

  • buffer_uris – The URIs of the buffers that are loaded. Least recently used first.
  • buffers – The loaded buffers.
  • current_size – The current size of the cache.
destroy_all() → None

Destroy all the buffers cached by this instance.

get_buffer(protocol: str, path: str) → object

Load and return a Buffer instance.

Buffers are cached in the buffers dictionary, so if there is already a buffer with the given protocol and path, it will be returned. Otherwise, a new buffer will be created, and added to the dictionary:

cache: BufferCache = BufferCache(1024 ** 2 * 512)  # 512 MB max.
assert isinstance(
    cache.get_buffer('file', 'sound.wav'), synthizer.Buffer
)
# True.
# Now it is cached:
assert cache.get_buffer(
    'file', 'sound.wav'
) is cache.get_buffer(
    'file', 'sound.wav'
)
# True.

If getting a new buffer would grow the cache past the point of max_size, the least recently used buffer will be removed and destroyed.

It is not recommended that you destroy buffers yourself. Let the cache do that for you.

At present, both arguments are passed to synthizer.Buffer.from_stream.

Parameters:
  • protocol

    One of the protocols supported by Synthizer.

    As far as I know, currently only 'file' works.

  • path – The path to whatever data your buffer will contain.
get_size(buffer: object) → int

Return the size of the provided buffer.

Parameters:buffer – The buffer to get the size of.
get_uri(protocol: str, path: str) → str

Return a URI for the given protocol and path.

This meth is used by get_buffer(). :param protocol: The protocol to use.

Parameters:path – The path to use.
pop_buffer() → object

Remove and return the least recently used buffer.

prune_buffers() → None

Prune old buffers.

This function will keep going, until either there is only ` buffer left, or current_size has shrunk to less than max_size.

class earwax.sound.BufferDirectory(buffer_cache: earwax.sound.BufferCache, path: pathlib.Path, glob: Optional[str] = None, thread_pool: Optional[concurrent.futures._base.Executor] = None)

Bases: object

An object which holds a directory of synthizer.Buffer instances.

For example:

b: BufferDirectory = BufferDirectory(
    cache, Path('sounds/weapons/cannons'), glob='*.wav'
)
# Get a random cannon buffer:
print(b.random_buffer())
# Get a random fully qualified path from the directory.
print(b.random_path())

You can select single buffer instances from the buffers dictionary, or a random buffer with the random_buffer() method.

You can select single Path instances from the paths dictionary, or a random path with the random_path() method.

Variables:
  • cache – The buffer cache to use.
  • path – The path to load audio files from.
  • glob – The glob to use when loading files.
  • buffers – A dictionary of of filename: Buffer pairs.
  • paths – A dictionary of filename: Path pairs.
buffers_default() → Dict[str, object]

Return the default value.

Populates the buffers and paths dictionaries.

random_buffer() → object

Return a random buffer.

Returns a random buffer from self.buffers.

random_path() → pathlib.Path

Return a random path.

Returns a random path from self.paths.

exception earwax.sound.NoCache

Bases: earwax.sound.SoundManagerError

This sound manager was created with no cache.

class earwax.sound.Sound(context: object, generator: object, buffer: Optional[object] = None, gain: float = 1.0, looping: bool = False, position: Union[float, earwax.point.Point, None] = None, reverb: Optional[object] = None, on_destroy: Optional[Callable[[Sound], None]] = None, on_finished: Optional[Callable[[Sound], None]] = None, on_looped: Optional[Callable[[Sound], None]] = None, keep_around: bool = NOTHING)

Bases: object

The base class for all sounds.

Variables:
  • context – The synthizer context to connect to.
  • generator – The sound generator.
  • buffer

    The buffer that feeds generator.

    If this value is None, then this sound is a stream.

  • gain – The gain of the new sound.
  • loop – Whether or not this sound should loop.
  • position

    The position of this sound.

    If this value is None, this sound will not be panned.

    If this value is an earwax.Point value, then this sound will be a 3d sound, and the position of its source will be set to the coordinates of the given point.

    If this value is a number, this sound will be panned in 2d, and the value will be a panning scalar, which should range between -1.0 (hard left), and 1.0 (hard right).

  • on_destroy – A function to be called when this sound is destroyed.
  • on_finished

    A function to be called when this sound has finished playing, and looping evaluates to False.

    The timing of this event should not be relied upon.

  • on_looped

    A function to be called each time this sound loops.

    The timing of this event should not be relied upon.

  • keep_around

    Whether or not this sound should be kept around when it has finished playing.

    If this value evaluates to True, it is the same as setting the on_finished attribute to destroy().

  • source – The synthizer source to play through.
check_destroyed() → None

Do nothing if this sound has not yet been destroyed.

If it has been destroyed, AlreadyDestroyed will be raised.

connect_reverb(reverb: object) → None

Connect a reverb to the source of this sound.

Parameters:reverb – The reverb object to connect.
destroy() → None

Destroy this sound.

This method will destroy the attached generator and source.

If this sound has already been destroyed, then AlreadyDestroyed will be raised.

destroy_generator() → None

Destroy the generator.

This method will leave the source intact, and will raise AlreadyDestroyed if the generator is still valid.

destroy_source() → None

Destroy the attached source.

If the source has already been destroyed, AlreadyDestroyed will be raised.

destroyed

Return whether or not this sound has been destroyed.

disconnect_reverb() → None

Disconnect the connected reverb object.

classmethod from_path(context: object, buffer_cache: earwax.sound.BufferCache, path: pathlib.Path, **kwargs) → earwax.sound.Sound

Create a sound that plays the given path.

Parameters:
  • context – The synthizer context to use.
  • cache – The buffer cache to load buffers from.
  • path

    The path to play.

    If the given path is a directory, then a random file from that directory will be chosen.

Parm kwargs:

Extra keyword arguments to pass to the Sound constructor.

classmethod from_stream(context: object, protocol: str, path: str, **kwargs) → earwax.sound.Sound

Create a sound that streams from the given arguments.

Parameters:
  • context – The synthizer context to use.
  • protocol – The protocol argument for synthizer.StreamingGenerator.
  • path – The path parameter for synthizer.StreamingGenerator.
is_stream

Return True if this sound is being streamed.

To determine whether or not a sound is being streamed, we check if self.buffer is None.

pause() → None

Pause this sound.

paused

Return whether or not this sound is paused.

play() → None

Resumes this sound after a call to pause().

reset_source() → object

Return an appropriate source.

restart() → None

Start this sound playing from the beginning.

set_gain(gain: float) → None

Change the gain of this sound.

Parameters:gain – The new gain value.
set_looping(looping: bool) → None

Set whether or not this sound should loop.

Parameters:looping – Whether or not to loop.
set_position(position: Union[float, earwax.point.Point, None]) → None

Change the position of this sound.

If the provided position is of a different type than the current one, then the underlying source object will need to changee. This will probably cause audio stuttering.

Parameters:position – The new position.
exception earwax.sound.SoundError

Bases: Exception

The base exception for all sounds exceptions.

class earwax.sound.SoundManager(context: object, buffer_cache: Optional[earwax.sound.BufferCache] = NOTHING, name: str = 'Untitled sound manager', default_gain: float = 1.0, default_looping: bool = False, default_position: Union[float, earwax.point.Point, None] = None, default_reverb: Optional[object] = None)

Bases: object

An object to hold sounds.

Variables:
  • context – The synthizer context to use.
  • cache – The buffer cache to get buffers from.
  • name – An optional name to set this manager aside from other sound managers when debugging.
  • default_gain – The default gain attribute for sounds created by this manager.
  • default_looping – The default looping attribute for sounds created by this manager.
  • default_position – The default position attribute for sounds created by this manager.
  • default_reverb – The default reverb attribute for sounds created by this manager.
  • sounds – A list of sounds that are playing.
destroy_all() → None

Destroy all the sounds associated with this manager.

play_path(path: pathlib.Path, **kwargs) → earwax.sound.Sound

Play a sound from a path.

The resulting sound will be added to sounds and returned.

Parameters:
  • path – The path to play.
  • kwargs

    Extra keyword arguments to pass to the constructor of earwax.Sound.

    This value will be updated by the update_kwargs() method.

play_stream(protocol: str, path: str, **kwargs) → earwax.sound.Sound

Stream a sound.

The resulting sound will be added to sounds and returned.

For full descriptions of the protocol, and path arguments, check the synthizer documentation for StreamingGenerator.

Parameters:
  • protocol – The protocol to use.
  • path – The path to use.
  • kwargs

    Extra keyword arguments to pass to the constructor of the earwax.Sound class.

    This value will be updated by the update_kwargs() method.

register_sound(sound: earwax.sound.Sound) → None

Register a sound with this instance.

Parameters:sound – The sound to register.
remove_sound(sound: earwax.sound.Sound) → None

Remove a sound from the sounds list.

Parameters:sound – The sound that will be removed
update_kwargs(kwargs: Dict[str, Any]) → None

Update the passed kwargs with the defaults from this manager.

Parameters:kwargs

The dictionary of keyword arguments to update.

The setdefault method will be used with each of the default values from this object..

exception earwax.sound.SoundManagerError

Bases: Exception

The base class for all sound manager errors.