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
- 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
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.