Sound

class waves.Sound

Main class for all sounds.

Its import is very simple:

>>> from waves import Sound
>>> import waves
>>> waves.Sound
<class 'waves.sound.main.Sound'>

The class waves.Sound is not intended to be built using their initialization method, instead must be used one of the opener or generators class methods.


OPENERS

Openers class methods creates a waves.Sound instance from a file in the disk or a buffer in memory:

classmethod from_file(filename)

Open a sound from a file.

Parameters

filename (str) – File path in the disk to open.

Returns

waves.Sound instance.

Return type

waves.Sound

Raises
  • FileNotFoundError – If the file does not exists in the provided path.

  • IsADirectoryError – If the provided path points to a directory.

Examples

>>> from waves import Sound
>>>
>>> Sound.from_file("tests/files/stereo.wav")
<waves.sound.main.Sound object at ...>
>>>
>>> Sound.from_file("tests/files/mono.wav")
<waves.sound.main.Sound object at ...>
classmethod from_sndbuffer(f)

Open a sound file from a pysndfile.PySndfile instance.

Parameters

f (pysndfile.PySndfile) – Opened instance of wrapper reading and writing class of pysndfile.

Returns

waves.Sound instance.

Return type

waves.Sound

Examples

>>> import pysndfile as snd
>>> from waves import Sound
>>>
>>> Sound.from_sndbuffer(snd.PySndfile("tests/files/stereo.wav", "r"))
<waves.sound.main.Sound object at ...>
>>>
>>> Sound.from_sndbuffer(snd.PySndfile("tests/files/mono.wav", "r"))
<waves.sound.main.Sound object at ...>

SOUND GENERATORS

Generator class methods creates a waves.Sound instance using an interpolator function which build the array of values for the sound for each frame.

By convenience, the next rule is follow:

  • If the sound is mono, the generator function must return one value at a time or frame.

  • If the sound is stereo, the generator function must return one array for each time or frame whose length will determine the number of channels.

classmethod from_datatimes(time_to_frame, fps=44100, **kwargs)

Build a sound object reading from frames arrays data, one array data by frame given a time.

Parameters
  • time_to_frame (function) – Function that takes an argument t which refers to the second of the frame and returns the numerical data for that frame. The returned value must be a subscriptable object with the data for the frame at given time for each channel.

  • fps (int, optional) – Number of frames per second of the resulting sound.

Examples

>>> # mono generating sine wave
>>> import numpy as np
>>> from waves import Sound
>>>
>>> duration, fps, frequency, volume = (3, 44100, 110, 0.5)
>>> amplitude = np.iinfo(np.int16).max * volume
>>>
>>> def time_to_frame(t):
...     return (np.sin(frequency * 2 * np.pi * t) * amplitude).astype(
...         np.int16
...     )
>>>
>>> Sound.from_datatimes(time_to_frame, fps=fps).with_duration(duration)
<waves.sound.main.Sound object at ...>
>>> # stereo generating sine waves
>>> import numpy as np
>>> from waves import Sound
>>>
>>> duration, fps, frequencies, volume = (3, 44100, (110, 440), 0.5)
>>> amplitude = np.iinfo(np.int16).max * volume
>>>
>>> def time_to_frame(t):
...     return [
...         (np.sin(frequencies[0] * 2 * np.pi * t) * amplitude).astype(
...             np.int16
...         ),
...         (np.sin(frequencies[1] * 2 * np.pi * t) * amplitude).astype(
...             np.int16
...         ),
...     ]
>>>
>>> Sound.from_datatimes(time_to_frame, fps=fps).with_duration(duration)
<waves.sound.main.Sound object at ...>
classmethod from_dataframes(index_to_frame, fps=44100, **kwargs)

Build a sound object reading from frames arrays data, one array of data by frame index.

Parameters
  • index_to_frame (function) – Function that takes an argument i, which refers to the index of the frame starting at 0 and returns the numerical data for that frame. The returned value must be a subscriptable object with the data for the frame for each channel.

  • fps (int, optional) – Number of frames per second of the resulting sound.

Examples

>>> # mono from file
>>> import wave
>>> import numpy as np
>>> from waves import Sound
>>>
>>> f = wave.open("tests/files/mono.wav", "rb")
>>> hexdata = f.readframes(-1)
>>> data = np.frombuffer(hexdata, getattr(np, f"int{f.getsampwidth() << 3}"))
>>>
>>> def index_to_frame(i):
...     try:
...         return data[i]
...     except IndexError:
...         raise StopIteration
>>>
>>> Sound.from_dataframes(index_to_frame, f.getframerate())
<waves.sound.main.Sound object at ...>
>>> f.close()
>>> # mono from generated data
>>> import numpy as np
>>> from waves import Sound
>>>
>>> duration, fps, frequency, volume = (3, 44100, 110, 0.5)
>>> t = np.linspace(0., duration, duration * fps)
>>> amplitude = np.iinfo(np.int16).max * volume
>>> data = (amplitude * np.sin(frequency * 2. * np.pi * t)).astype(np.int16)
>>> Sound.from_dataframes(lambda i: data[i], fps=fps)
<waves.sound.main.Sound object at ...>
>>> # stereo from file
>>> import wave
>>> import numpy as np
>>> from waves import Sound
>>>
>>> f = wave.open("tests/files/stereo.wav", "rb")
>>> hexdata = f.readframes(-1)
>>> data = np.frombuffer(hexdata, getattr(np, f"int{f.getsampwidth() << 3}"))
>>> data.shape = (-1, f.getnchannels())
>>>
>>> def index_to_frame(i):
...     try:
...         return data[i]
...     except IndexError:
...         raise StopIteration
>>>
>>> Sound.from_dataframes(index_to_frame, f.getframerate())
<waves.sound.main.Sound object at ...>
>>> f.close()
>>> # stereo from generated data
>>> import numpy as np
>>> from waves import Sound
>>>
>>> duration, fps, frequencies, volume = (3, 44100, (110, 440), 0.4)
>>> t = np.linspace(0., duration, duration * fps)
>>> amplitude = np.iinfo(np.int16).max * volume
>>> data_left = (
...     amplitude * np.sin(frequencies[0] * 2. * np.pi * t)
... ).astype(np.int16)
>>> data_right = (
...     amplitude * np.sin(frequencies[1] * 2. * np.pi * t)
... ).astype(np.int16)
>>> Sound.from_dataframes(
...     lambda i: np.array([data_left[i], data_right[i]]), fps=fps
... )
<waves.sound.main.Sound object at ...>
classmethod from_bytetimes(time_to_hexframe, fps=44100, **kwargs)

Build a sound object reading from frames bytes, one hex data chunk by frame at a time.

Parameters
  • time_to_hexframe (function) – Function that takes an argument t, which refers to the second of the frame starting at 0 and returns the bytes object for that frame. The returned value must be a subscriptable object with the bytes for the frame for each channel.

  • fps (int, optional) – Number of frames per second of the resulting sound.

Examples

>>> # mono from file
>>> import wave, struct
>>> from waves import Sound
>>>
>>> f = wave.open("tests/files/mono.wav", "rb")
>>> fps = f.getframerate()
>>> hexdata = f.readframes(-1)
>>> hexframes = []
>>> for bytes_frame in struct.iter_unpack(f"{f.getsampwidth()}c", hexdata):
...     hexframes.append(b"".join(bytes_frame))
>>>
>>> Sound.from_bytetimes(lambda t: hexframes[int(round(t * fps))], fps=fps)
<waves.sound.main.Sound object at ...>
>>> f.close()
>>> # stereo from file
>>> import wave, struct
>>> from waves import Sound
>>>
>>> f = wave.open("tests/files/stereo.wav", "rb")
>>> hexdata, fps = (f.readframes(-1), f.getframerate())
>>> n_channels, n_bytes = (f.getnchannels(), f.getsampwidth())
>>>
>>> hexframes = []
>>> for bytes_frame in struct.iter_unpack(f"{n_bytes * n_channels}c", hexdata):
...     hexframe = []
...     for channel_index in range(n_channels):
...         start = channel_index * n_bytes
...         end = start + n_bytes
...         hexframe.append(b"".join(bytes_frame[start: end]))
...     hexframes.append(hexframe)
>>> Sound.from_bytetimes(lambda t: hexframes[int(round(t * fps))], fps=fps)
<waves.sound.main.Sound object at ...>
>>> f.close()
classmethod from_byteframes(index_to_hexframe, fps=44100, **kwargs)

Build a sound object reading from frames bytes, one hex data chunk by frame index.

Parameters
  • index_to_hexframe (function) – Function that takes an argument i, which refers to the index of the frame starting at 0 and returns the bytes object for that frame. The returned value must be a subscriptable object with the bytes for the frame for each channel.

  • fps (int, optional) – Number of frames per second of the resulting sound.

Examples

>>> # mono from file
>>> import wave, struct
>>> from waves import Sound
>>>
>>> f = wave.open("tests/files/mono.wav", "rb")
>>> hexdata = f.readframes(-1)
>>> hexframes = []
>>> for bytes_frame in struct.iter_unpack(f"{f.getsampwidth()}c", hexdata):
...     hexframes.append(b"".join(bytes_frame))
>>>
>>> def index_to_hexframe(i):
...     try:
...         return hexframes[i]
...     except IndexError:
...         raise StopIteration
>>>
>>> Sound.from_byteframes(index_to_hexframe, fps=f.getframerate())
<waves.sound.main.Sound object at ...>
>>> f.close()
>>> # stereo from file
>>> import wave, struct
>>> from waves import Sound
>>>
>>> f = wave.open("tests/files/stereo.wav", "rb")
>>> hexdata = f.readframes(-1)
>>> n_channels, n_bytes = (f.getnchannels(), f.getsampwidth())
>>>
>>> hexframes = []
>>> for bytes_frame in struct.iter_unpack(f"{n_bytes * n_channels}c", hexdata):
...     hexframe = []
...     for channel_index in range(n_channels):
...         start = channel_index * n_bytes
...         end = start + n_bytes
...         hexframe.append(b"".join(bytes_frame[start: end]))
...     hexframes.append(hexframe)
>>>
>>> def index_to_hexframe(i):
...     try:
...         return hexframes[i]
...     except IndexError:
...         raise StopIteration
>>>
>>> Sound.from_byteframes(index_to_hexframe, fps=f.getframerate())
<waves.sound.main.Sound object at ...>
>>> f.close()

GETTERS

n_frames int

Number of frames of the audio data.

n_bytes int

Sample width of the sound.

n_channels int

Number of channels of the sound.

fps int

Number of frames per second, also known as framerate or sampling rate.

dtype type

Type of the data used to decode the sound as a Numpy array.

filename str

Path to the file located in disk which stores the raw sound data.

time_to_frame function

Function which takes a time t for each frame of the sound and renders the Numpy array data of the sound for each frame. Only defined if the sound has been created an interpolator function.

metadata dict

Dictionary with metadata about the sound.

data: np.ndarray

Numpy data array of the sound. If the sound is stereo, returns one Numpy array per channel, but if the sound is mono returns one Numpy array with the values of the sound for the channel.

dataframes: np.ndarray

Numpy data array of the sound for each frame. If the sound is stereo, returns one Numpy array per frame, but if the sound is mono returns one Numpy array with the values of the sound for the channel, one array for each frame.

property iter_dataframes

Generates each frame of the sound data.

If the sound has beeen built using a generator function and its duration hasn’t been set, this will produce an infinite loop.

property iter_datatimes

Generates each frame of the sound data, yielding a tuple with the time of the frame as first value and the data of the sound as second.

If the sound has beeen built using a generator function and its duration hasn’t been set, this will produce an infinite loop.

property iter_chunks

Generates each chunk of the sound data, being read at the moment of yielding.

Parameters

buffersize (int, optional) – Number of frames generated at each chunk.


WRITERS

save(filename, buffersize=1024)

Saves an audio instance to a file.

Parameters
  • filename (str) – System disk path in which the file will be saved.

  • buffsize (int, optional) – Number of bytes stored in memory buffer while reading and writing. Only used if the filename to write has been created opening from a file in disk.


INTERACTIVE

play(wait=True, **kwargs)

Plays a sound using pygame.

waitbool or Number, optional

Waits for the ending of the playing to return. Disable it if you want an asynchronous playing. Pass a number if you want to wait an exact time instead of the duration of the sound.

plot(show=True, **kwargs)

Plots the figure that represents the sound using matplotlib.

showbool, optional

Shows the figure using plt.show.

figure(title='Sound data')

Returns a basic matplotlib figure with the channels of the sound plotted.

titlestr, optional

Figure title.