def test_mono_audio_file_construction(self, shared_datadir): file_name = (shared_datadir / 'audio/test_sine.wav').resolve() audio = AudioBuffer(file_name) assert audio.get_audio().shape == (44100,) assert audio.get_sample_rate() == 44100 assert audio.channels == 1 assert audio.file_name == file_name
def test_list_construction_stereo(self): samples = [[1,2,3,4,5],[6,7,8,9,10]] audio = AudioBuffer(samples, 44100) assert np.array_equal(audio.get_audio(), samples) assert audio.get_sample_rate() == 44100 assert audio.channels == 2 assert audio.file_name == ''
def test_array_construction_mono(self): samples = np.array([1,2,3,4,5,6,7,8,9,10]) audio = AudioBuffer(samples, 44100) assert np.array_equal(audio.get_audio(), samples) assert audio.get_sample_rate() == 44100 assert audio.channels == 1 assert audio.file_name == ''
def test_replace_audio(self): samples = np.array([[1,2,3,4,5],[6,7,8,9,10]]) audio = AudioBuffer(samples, 44100) samplesB = np.array([10,9,8,7,6,5,4,3,2,1]) audio.replace_audio_data(samplesB, 96000) assert np.array_equal(audio.get_audio(), samplesB) assert audio.channels == 1
def test_plot_spectrogram(self): samples = self.make_test_sine(44100, 150, 44100) audio = AudioBuffer(samples, 44100) fig = plt.figure() ax = audio.plot_spectrogram() plt.plot() return fig
def test_sine_wave_stft_complex(self, shared_datadir): file_name = (shared_datadir / 'audio/test_sine.wav').resolve() audio = AudioBuffer() audio.load(file_name) stft = STFT() features = stft(audio) assert features.shape == (513, 87) assert isinstance(features[0][0], np.complex64)
def test_sine_wave_stft_complex_time_major(self, shared_datadir): file_name = (shared_datadir / 'audio/test_sine.wav').resolve() audio = AudioBuffer() audio.load(file_name) stft = STFT(time_major=True, fft_size=2048, hop_size=1024) features = stft(audio) assert features.shape == (44, 1025) assert isinstance(features[0][0], np.complex64)
def test_save_mono_create_dir(self, tmp_path): samples = self.make_test_sine(44100, 440, 44100) audio = AudioBuffer(samples, 44100) file_name = (tmp_path / 'temp_dir/test_save.wav').resolve() audio.save(file_name) audioReload = AudioBuffer(file_name) np.testing.assert_array_almost_equal(audio.get_audio(), audioReload.get_audio()) assert audioReload.get_sample_rate() == 44100 assert audioReload.channels == 1 assert audioReload.file_name == file_name
def test_sine_extraction_scale(self): frame_size = 1024 hop_size = 512 bin_freq = 44100. / float(frame_size) num_frames = 10 batch_size = 10 spectral = SpectralSummarized() features = np.ndarray(( 10, 22, )) for i in range(batch_size): sine = utils.make_test_cosine(22050, bin_freq * (i + 1), 44100) audio = AudioBuffer(sine, 44100) features[i] = spectral(audio) assert features.shape == (10, 22) scaled = spectral.fit_scaler(features) assert scaled.mean() == pytest.approx(0.) assert scaled.std() == pytest.approx(1.) np.testing.assert_array_almost_equal(scaled.mean(0), np.zeros(22)) np.testing.assert_array_almost_equal(scaled.std(0), np.ones(22))
def test_sine_mfcc_time_major(self): sine = utils.make_test_sine(2048, 440, 44100) audio = AudioBuffer(sine, 44100) mfcc = MFCC(hop_size=512, frame_size=1024, time_major=True) features = mfcc(audio) assert features.shape == (5, 20)
def test_load_folder_with_non_audio_stereo(self, shared_datadir): file_name = (shared_datadir / 'audio').resolve() audio = AudioBuffer.load_folder(file_name, mono=False) assert len(audio) == 2 assert audio[0].get_audio().shape == (44100,) assert audio[0].get_sample_rate() == 44100 assert audio[0].file_name == 'test_sine.wav' assert audio[1].get_audio().shape == (2,44100) assert audio[1].get_sample_rate() == 44100 assert audio[1].file_name == 'test_sine_stereo.wav'
def test_sine_wave_fft_magnitude_longer(self): bin_freq = 44100. / 4096. sine = utils.make_test_sine(4096, bin_freq * 10, 44100) audio = AudioBuffer(sine, 44100) fft = FFT(output='magnitude') features = fft(audio) expected = np.zeros(2049) expected[10] = 2048. assert features.shape == (2049, ) assert isinstance(features[0], np.float32) np.testing.assert_array_almost_equal(features, expected)
def test_sine_wave_fft_power(self): bin_freq = 44100. / 1024. sine = utils.make_test_sine(1024, bin_freq * 10, 44100) audio = AudioBuffer(sine, 44100) fft = FFT(output='power') features = fft(audio) expected = np.zeros(513) expected[10] = 512. * 512. assert features.shape == (513, ) assert isinstance(features[0], np.float32) np.testing.assert_array_almost_equal(features, expected)
def match_from_file(self, path): """ Load audio file from disk and perform sound matching on it Args: filepath (str): location of audio file on disk Returns: :ref:`AudioBuffer <audio_buffer>`: audio output from synthesizer after sound matching """ target = AudioBuffer(path, self.features.sample_rate) return self.match(target)
def test_stereo_audio_file_load(self, shared_datadir): file_name = (shared_datadir / 'audio/test_sine_stereo.wav').resolve() audio = AudioBuffer() audio.load(file_name, mono=False) assert audio.get_audio().shape == (2, 44100) assert audio.get_sample_rate() == 44100 assert audio.channels == 2 assert audio.file_name == file_name
def test_audio_file_load_resample(self, shared_datadir): file_name = (shared_datadir / 'audio/test_sine.wav').resolve() audio = AudioBuffer() audio.load(file_name, 88200) assert audio.get_audio().shape == (88200,) assert audio.get_sample_rate() == 88200 assert audio.channels == 1 assert audio.file_name == file_name
def test_load_folder_resample(self, shared_datadir): file_name = (shared_datadir / 'audio/test_folder').resolve() audio = AudioBuffer.load_folder(file_name, sample_rate=22050) assert len(audio) == 3 assert audio[0].get_audio().shape == (22050,) assert audio[0].get_sample_rate() == 22050 assert audio[0].file_name == 'test_1.wav' assert audio[1].get_audio().shape == (22050,) assert audio[1].get_sample_rate() == 22050 assert audio[1].file_name == 'test_2.wav' assert audio[2].get_audio().shape == (22050,) assert audio[2].get_sample_rate() == 22050 assert audio[2].file_name == 'test_3.wav'
def test_batch_scale_magnitude(self): bin_freq = 44100. / 1024. feature_batch = np.zeros((10, 513)) fft = FFT(output='magnitude', scale_axis=None) for i in range(10): bin = (i + 1) * 2 sine = utils.make_test_cosine(1024, bin_freq * bin, 44100) audio = AudioBuffer(sine, 44100) feature_batch[i] = fft(audio) scaled = fft.fit_scaler(feature_batch) expected_mean = (512.0 * 10) / (513.0 * 10) assert fft.scaler.mean == pytest.approx(expected_mean)
def get_audio(self): """ Return monophonic audio from rendered patch :return: An audio buffer of the rendered patch :rtype: :class:`spiegelib.core.audio_buffer.AudioBuffer` """ if self.rendered_patch: audio = AudioBuffer(self.engine.get_audio_frames(), self.sample_rate) return audio else: raise Exception( 'Patch must be rendered before audio can be retrieved')
def test_sine_mfcc_scale(self): batch_size = 10 mfcc = MFCC(hop_size=512, frame_size=1024, scale_axis=(0, 2)) features = np.zeros((batch_size, 20, 5)) for i in range(batch_size): sine = utils.make_test_sine(2048, 100 + (50 * i), 44100) audio = AudioBuffer(sine, 44100) features[i] = mfcc(audio) assert features.shape == (10, 20, 5) scaled = mfcc.fit_scaler(features) assert scaled.mean() == pytest.approx(0.) assert scaled.std() == pytest.approx(1.) np.testing.assert_array_almost_equal(scaled.mean((0, 2)), np.zeros(20)) np.testing.assert_array_almost_equal(scaled.std((0, 2)), np.ones(20))
def test_sine_wave_stft_power(self): bin_freq = 44100. / 1024. sine = utils.make_test_cosine(1024 + 1, bin_freq * 10, 44100) audio = AudioBuffer(sine, 44100) stft = STFT(output='power', fft_size=1024) features = stft(audio) expected = np.zeros((513, 3)) # amplitude is spread out over neighbouring bins expected[9, :] = 128. * 128. expected[10, :] = 256. * 256. expected[11, :] = 128. * 128. assert features.shape == (513, 3) assert isinstance(features[0][0], np.float32) np.testing.assert_array_almost_equal(features, expected)
def test_sine_wave_fft_power_phase(self): bin_freq = 44100. / 1024. # Using a cosine here to get zero initial phase sine = utils.make_test_cosine(1024, bin_freq * 10, 44100) audio = AudioBuffer(sine, 44100) fft = FFT(output='power_phase') features = fft(audio) expected = np.zeros((513, 2)) expected[10][0] = 512. * 512. assert features.shape == (513, 2) assert isinstance(features[0][0], np.float32) assert isinstance(features[0][1], np.float32) # Assert correct magnitude np.testing.assert_array_almost_equal(features[:, 0], expected[:, 0]) # Uncertain about phase, except for 10th bin assert features[10][1] == pytest.approx(0.)
def test_sine_wave_stft_magnitude_scaled(self): bin_freq = 44100. / 1024. length = (1024. * 10) + 1 stft = STFT(output='magnitude', fft_size=1024, hop_size=512, time_major=True, scale_axis=None) batch_size = 10 features = np.zeros((10, 21, 513)) for i in range(batch_size): sine = utils.make_test_cosine(int(length), bin_freq * (i + 10), 44100) audio = AudioBuffer(sine, 44100) features[i] = stft(audio) scaled = stft.fit_scaler(features) assert scaled.shape == (10, 21, 513) assert scaled.mean() == pytest.approx(0.) assert scaled.std() == pytest.approx(1.)
def test_sine_extraction(self): frame_size = 1024 hop_size = 512 bin_freq = 44100. / float(frame_size) sine = utils.make_test_cosine(1024 + 1, bin_freq * 10, 44100) audio = AudioBuffer(sine, 44100) spectral = SpectralSummarized(frame_size=1024, hop_size=512) features = spectral(audio) assert features.shape == (22, ) assert features[0] == pytest.approx(bin_freq * 10) assert features[1] == pytest.approx(0.) assert features[2] == pytest.approx(30.452547928239625) assert features[3] == pytest.approx(0.) assert features[4] == pytest.approx(0.) assert features[5] == pytest.approx(0.) assert features[6] == pytest.approx(bin_freq * 11) assert features[7] == pytest.approx(0.) # Spectral flatness subbands assert features[8] == pytest.approx(44.0823996531185) assert features[9] == pytest.approx(0.) assert features[10] == pytest.approx(44.0823996531185) assert features[11] == pytest.approx(0.) assert features[12] == pytest.approx(124.0823996531185) assert features[13] == pytest.approx(0.) assert features[14] == pytest.approx(44.0823996531185) assert features[15] == pytest.approx(0.) assert features[16] == pytest.approx(44.0823996531185) assert features[17] == pytest.approx(0.) assert features[18] == pytest.approx(44.0823996531185) assert features[19] == pytest.approx(0.) assert features[20] == pytest.approx(44.0823996531185) assert features[21] == pytest.approx(0.)
def test_peak_normalize(self): samples = self.make_test_sine(44100, 100) samplesHalfAmp = samples * 0.5 samplesNorm = AudioBuffer.peak_normalize(samples) np.testing.assert_array_equal(samples, samplesNorm)
def test_empty_construction(self): audio = AudioBuffer() assert audio.get_audio() == None assert audio.get_sample_rate() == None assert audio.channels == 0 assert audio.file_name == ''
def test_save_mono_normalize(self, tmp_path): samples = self.make_test_sine(44100, 400, 44100) samplesHalfAmp = samples * 0.5 audio = AudioBuffer(samples, 44100) audioNormed = AudioBuffer(samples, 44100) file_name = (tmp_path / 'test_save.wav').resolve() audio.save(file_name, normalize=True) audioReload = AudioBuffer(file_name) # Make sure it looks correct np.testing.assert_array_almost_equal(audioNormed.get_audio(), audioReload.get_audio(), decimal=5) assert audioReload.get_audio().shape == (44100,) assert audioReload.get_sample_rate() == 44100 assert audioReload.channels == 1 assert audioReload.file_name == file_name
def test_array_construction_sample_rate_exception(self): samples = np.array([1,2,3,4,5,6,7,8,9,10]) with pytest.raises(Exception) as exc_info: audio = AudioBuffer(samples) assert exc_info.type is Exception assert exc_info.value.args[0] == 'Sample rate is required when initializing with audio data'
def test_peak_normalize_no_change(self): samples = self.make_test_sine(44100, 100) samplesNorm = AudioBuffer.peak_normalize(samples) np.testing.assert_array_almost_equal(samples, samplesNorm, decimal=5)
def test_load_folder_exception(self, shared_datadir): file_name = (shared_datadir / 'audio/non_existent').resolve() with pytest.raises(Exception) as exc_info: audio = AudioBuffer.load_folder(file_name) assert exc_info.type is ValueError assert exc_info.value.args[0] == '%s is not a directory' % file_name