def test_from_byteframes_stereo(stereo_filepath): with wave.open(stereo_filepath, "rb") as f: hexdata, fps, n_frames = (f.readframes(-1), f.getframerate(), f.getnframes()) 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) index_to_hexframe = lambda i: hexframes[i] sound = Sound.from_byteframes(index_to_hexframe, fps=fps) for i, t in enumerate(sound.time_sequence): try: frame = sound.time_to_frame(t) except IndexError: assert i == n_frames break hexframe = index_to_hexframe(i) assert frame[0] == np.frombuffer(hexframe[0], dtype=np.int16)[0] assert frame[1] == np.frombuffer(hexframe[1], dtype=np.int16)[0]
def test_save_mono_from_function(tmp_path): fps, frequency, volume = (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) mono_sound = Sound.from_datatimes(time_to_frame, fps=fps).with_duration(0.5) filename = tmp_path / "save_mono_from_function.wav" mono_sound.save(filename) assert filename.exists() resulting_sound = Sound.from_file(filename) assert np.array_equal(resulting_sound.data, mono_sound.data)
def test_save_mono_from_file(mono_sound, tmp_path): filename = tmp_path / "save_mono_from_file.wav" mono_sound.save(filename) assert filename.exists() resulting_sound = Sound.from_file(filename.as_posix()) assert np.array_equal(resulting_sound.data, mono_sound.data)
def test_iter_dataframes_mono_from_function(mono_ttf_gen): fps, frequency, volume = (44100, 110, 0.5) time_to_frame = mono_ttf_gen(fps=fps, frequency=frequency, volume=volume) t_fps = 1 / fps sound = Sound.from_datatimes(time_to_frame, fps=fps).with_duration(0.5) for i, frame in enumerate(sound.iter_dataframes): assert frame == time_to_frame(i * t_fps)
def test_iter_datatimes_mono_from_function(mono_ttf_gen): fps, frequency, volume = (44100, 110, 0.5) time_to_frame = mono_ttf_gen(fps=fps, frequency=frequency, volume=volume) sound = Sound.from_datatimes(time_to_frame, fps=fps).with_duration(0.5) zipped = zip(sound.iter_datatimes, sound.time_sequence) for (id_t, frame), ts_t in zipped: assert id_t == ts_t assert time_to_frame(ts_t) == frame
def test_save_stereo_from_function(tmp_path): fps, frequencies, volume = (44100, (110, 440), 0.5) amplitude = np.iinfo(np.int16).max * volume time_to_frame_left = lambda t: (np.sin(frequencies[0] * 2 * np.pi * t) * amplitude).astype(np.int16) time_to_frame_right = lambda t: (np.sin(frequencies[1] * 2 * np.pi * t) * amplitude).astype(np.int16) stereo_sound = Sound.from_datatimes( lambda t: [time_to_frame_left(t), time_to_frame_right(t)], fps=fps).with_duration(0.5) filename = tmp_path / "save_stereo_from_function.wav" stereo_sound.save(filename) assert filename.exists() resulting_sound = Sound.from_file(filename) assert np.array_equal(resulting_sound.data, stereo_sound.data)
def test_from_datatimes_mono(mono_ttf_gen): fps, frequency, volume = (44100, 110, 0.5) time_to_frame = mono_ttf_gen(fps=fps, frequency=frequency, volume=volume) sound = Sound.from_datatimes(time_to_frame, fps=fps) assert sound.n_bytes == 2 assert sound.n_frames is None assert sound.duration == math.inf times = [random.uniform(0, 5) for i in range(10)] for t in times: assert time_to_frame(t) == sound.time_to_frame(t)
def test_mono_ttf_gen(mono_ttf_gen, fps, frequency, volume, sample_width): time_to_frame = mono_ttf_gen( fps=fps, frequency=frequency, volume=volume, sample_width=sample_width, ) sound = Sound.from_datatimes(time_to_frame, fps=fps).with_duration(1) assert sound.fps == fps assert sound.n_channels == 1 assert sound.duration == 1 assert sound.dtype is getattr(np, f"int{sample_width << 3}")
def test_iter_dataframes_stereo_from_function(): fps, frequencies, volume = (44100, (110, 440), 0.5) amplitude, t_fps = (np.iinfo(np.int16).max * volume, 1 / fps) time_to_frame_left = lambda t: (np.sin(frequencies[0] * 2 * np.pi * t) * amplitude).astype(np.int16) time_to_frame_right = lambda t: (np.sin(frequencies[1] * 2 * np.pi * t) * amplitude).astype(np.int16) sound = Sound.from_datatimes( lambda t: [time_to_frame_left(t), time_to_frame_right(t)], fps=fps).with_duration(0.5) for i, frame in enumerate(sound.iter_dataframes): assert frame[0] == time_to_frame_left(i * t_fps) assert frame[1] == time_to_frame_right(i * t_fps)
def test_from_file_stereo(stereo_filepath): sound = Sound.from_file(stereo_filepath) assert sound.n_frames == 55216 assert sound.n_bytes == 2 assert sound.n_bits == 16 assert sound.fps == 44100 assert sound.n_channels == 2 assert sound.dtype is np.int16 assert sound.time_to_frame is None assert sound.filename == stereo_filepath.encode("utf-8") assert isinstance(sound.f, snd.PySndfile) assert isinstance(sound.metadata, dict) assert sound.metadata["SF_STR_TITLE"] == b"Bass Drum 1" assert sound.metadata["SF_STR_ARTIST"] == b"freewavesamples.com" assert sound.metadata["SF_STR_DATE"] == b"2015"
def test_from_file_mono(mono_filepath): sound = Sound.from_file(mono_filepath) assert sound.n_frames == 106022 assert sound.n_bytes == 2 assert sound.n_bits == 16 assert sound.fps == 44100 assert sound.n_channels == 1 assert sound.dtype is np.int16 assert sound.time_to_frame is None assert sound.filename == mono_filepath.encode("utf-8") assert isinstance(sound.f, snd.PySndfile) assert isinstance(sound.metadata, dict) assert sound.metadata["SF_STR_SOFTWARE"] == ( b"Adobe Soundbooth CS5 (XMPDocOpsTemporal:2008.08.26)") assert sound.metadata["SF_STR_ARTIST"] == b"freewavesamples.com" assert sound.metadata["SF_STR_DATE"] == b"2015-05-06T19:28:12-07:00"
def test_iter_datatimes_stereo_from_function(): fps, frequencies, volume = (44100, (110, 440), 0.5) amplitude = np.iinfo(np.int16).max * volume time_to_frame_left = lambda t: (np.sin(frequencies[0] * 2 * np.pi * t) * amplitude).astype(np.int16) time_to_frame_right = lambda t: (np.sin(frequencies[1] * 2 * np.pi * t) * amplitude).astype(np.int16) sound = Sound.from_datatimes( lambda t: [time_to_frame_left(t), time_to_frame_right(t)], fps=fps).with_duration(0.5) zipped = zip(sound.iter_datatimes, sound.time_sequence) for (id_t, frame), ts_t in zipped: assert id_t == ts_t assert time_to_frame_left(ts_t) == frame[0] assert time_to_frame_right(ts_t) == frame[1]
def test_from_byteframes_mono(mono_filepath): with wave.open(mono_filepath, "rb") as f: hexdata, fps, n_frames = (f.readframes(-1), f.getframerate(), f.getnframes()) hexframes = [] for bytes_frame in struct.iter_unpack(f"{f.getsampwidth()}c", hexdata): hexframes.append(b"".join(bytes_frame)) index_to_hexframe = lambda i: hexframes[i] sound = Sound.from_byteframes(index_to_hexframe, fps=fps) for i, t in enumerate(sound.time_sequence): try: frame = sound.time_to_frame(t) except IndexError: assert i == n_frames break hexframe = index_to_hexframe(i) assert frame == np.frombuffer(hexframe, dtype=np.int16)[0]
def test_from_dataframes_mono(mono_sound, explicit_n_frames): frames = mono_sound.data if explicit_n_frames: index_to_frame = lambda i: frames[i] else: def index_to_frame(i): try: return frames[i] except IndexError: raise StopIteration sound = Sound.from_dataframes( index_to_frame, fps=mono_sound.fps, n_frames=mono_sound.n_frames if explicit_n_frames else None, ) assert np.array_equal(frames, sound.data) assert mono_sound.n_frames == sound.n_frames
def test_from_datatimes_stereo(): fps, frequencies, volume = (44100, (110, 440), 0.5) amplitude = np.iinfo(np.int16).max * volume time_to_frame_left = lambda t: (np.sin(frequencies[0] * 2 * np.pi * t) * amplitude).astype(np.int16) time_to_frame_right = lambda t: (np.sin(frequencies[1] * 2 * np.pi * t) * amplitude).astype(np.int16) sound = Sound.from_datatimes( lambda t: [time_to_frame_left(t), time_to_frame_right(t)], fps=fps) assert sound.n_bytes == 2 assert sound.n_frames is None assert sound.duration == math.inf times = [random.uniform(0, 5) for i in range(10)] for t in times: frame = sound.time_to_frame(t) assert frame[0] == time_to_frame_left(t) assert frame[1] == time_to_frame_right(t)
def stereo_sound(stereo_filepath): return Sound.from_file(stereo_filepath)
def mono_sound(mono_filepath): return Sound.from_file(mono_filepath)