def test_load_and_save_is_identity(self): input_path = os.path.join(self.test_dirpath, 'assets', 'sinewave.wav') tensor, sample_rate = load(input_path) output_path = os.path.join(self.test_dirpath, 'test.wav') save(output_path, tensor, sample_rate, 32) tensor2, sample_rate2 = load(output_path) self.assertTrue(tensor.allclose(tensor2)) self.assertEqual(sample_rate, sample_rate2) os.unlink(output_path)
def test_load_partial(self): num_frames = 100 offset = 200 # load entire mono sinewave wav file, load a partial copy and then compare input_sine_path = os.path.join(self.test_dirpath, 'assets', 'sinewave.wav') x_sine_full, sr_sine = load(input_sine_path) x_sine_part, _ = load(input_sine_path, num_frames=num_frames, offset=offset) l1_error = x_sine_full[offset:( num_frames + offset)].sub(x_sine_part).abs().sum().item() # test for the correct number of samples and that the correct portion was loaded self.assertEqual(x_sine_part.size(0), num_frames) self.assertEqual(l1_error, 0.) # create a two channel version of this wavefile x_2ch_sine = x_sine_full.repeat(1, 2) out_2ch_sine_path = os.path.join(self.test_dirpath, 'assets', '2ch_sinewave.wav') save(out_2ch_sine_path, x_2ch_sine, sr_sine) x_2ch_sine_load, _ = load(out_2ch_sine_path, num_frames=num_frames, offset=offset) os.unlink(out_2ch_sine_path) l1_error = x_2ch_sine_load.sub( x_2ch_sine[offset:(offset + num_frames)]).abs().sum().item() self.assertEqual(l1_error, 0.) # test with two channel mp3 x_2ch_full, sr_2ch = load(self.test_filepath, normalization=True) x_2ch_part, _ = load(self.test_filepath, normalization=True, num_frames=num_frames, offset=offset) l1_error = x_2ch_full[offset:( offset + num_frames)].sub(x_2ch_part).abs().sum().item() self.assertEqual(x_2ch_part.size(0), num_frames) self.assertEqual(l1_error, 0.) # check behavior if number of samples would exceed file length offset_ns = 300 x_ns, _ = load(input_sine_path, num_frames=100000, offset=offset_ns) self.assertEqual(x_ns.size(0), x_sine_full.size(0) - offset_ns) # check when offset is beyond the end of the file with self.assertRaises(RuntimeError): load(input_sine_path, offset=100000)
def test_save(self): # load signal x, sr = load(self.test_filepath) # check save new_filepath = os.path.join(self.test_dirpath, "test.wav") save(new_filepath, x, sr) self.assertTrue(os.path.isfile(new_filepath)) os.unlink(new_filepath) # check automatic normalization x /= 1 << 31 save(new_filepath, x, sr) self.assertTrue(os.path.isfile(new_filepath)) os.unlink(new_filepath) # test save 1d tensor x = x[:, 0] # get mono signal x.squeeze_() # remove channel dim save(new_filepath, x, sr) self.assertTrue(os.path.isfile(new_filepath)) os.unlink(new_filepath) # don't allow invalid sizes as inputs with self.assertRaises(ValueError): x.unsqueeze_(0) # N x L not L x N save(new_filepath, x, sr) with self.assertRaises(ValueError): x.squeeze_() x.unsqueeze_(1) x.unsqueeze_(0) # 1 x L x 1 save(new_filepath, x, sr) # automatically convert sr from floating point to int x.squeeze_(0) save(new_filepath, x, float(sr)) self.assertTrue(os.path.isfile(new_filepath)) os.unlink(new_filepath) # don't save to folders that don't exist with self.assertRaises(OSError): new_filepath = os.path.join(self.test_dirpath, "no-path", "test.wav") save(new_filepath, x, sr) # save created file sinewave_filepath = os.path.join(self.test_dirpath, "assets", "sinewave.wav") sr = 16000 freq = 440 volume = 0.3 y = (torch.cos(2 * math.pi * torch.arange(0, 4 * sr).float() * freq / sr)) y.unsqueeze_(1) # y is between -1 and 1, so must scale y = (y * volume * 2**31).long() save(sinewave_filepath, y, sr) self.assertTrue(os.path.isfile(sinewave_filepath)) # test precision new_filepath = os.path.join(self.test_dirpath, "test.wav") si, ei = torchaudio.info(sinewave_filepath) save(new_filepath, y, sr, precision=16) si16, ei16 = torchaudio.info(new_filepath) self.assertEqual(si.precision, 32) self.assertEqual(si16.precision, 16) os.unlink(new_filepath)