def test_wavetable_synth_is_accurate(self, batch_size, frequency, amplitude, n_wavetable, wavetable_frames): """Tests accuracy of wavetable synthesizer. Generate a sine wave wavetable synthesizer and compare to the analytic form. Error will vary with the size of the lookup table, but should stay below a threshold for moderate sized tables. Args: batch_size: Number of batch examples in the test phase signal. frequency: Frequency of the carrier signal in Hertz. amplitude: Amplitude of the carrier signal. n_wavetable: Number of samples in the wavetable. wavetable_frames: Number of wavetables over time. """ sample_rate = 16000 seconds = 0.1 n_samples = int(sample_rate * seconds) n_cycles = seconds * frequency n_frames = 100 two_pi = 2.0 * np.pi wavetable = np.sin(np.linspace(0, two_pi, n_wavetable).astype(np.float32)) wavetable = np.tile(wavetable[np.newaxis, :], [batch_size, 1]) if wavetable_frames > 0: wavetable = np.tile(wavetable[:, np.newaxis, :], [1, wavetable_frames, 1]) wav_np = amplitude * np.sin(two_pi * np.linspace(0, n_cycles, n_samples)) wav_np = np.tile(wav_np[np.newaxis, :], [batch_size, 1]).astype(np.float32) amplitudes = np.ones([batch_size, n_frames, 1]) * amplitude frequencies = np.ones([batch_size, n_frames, 1]) * frequency with self.cached_session() as sess: wav_tf = sess.run(core.wavetable_synthesis( frequencies, amplitudes, wavetable, n_samples, sample_rate )) pad = n_samples // n_frames # Ignore edge effects. difference = np.abs(wav_np[:, pad:-pad] - wav_tf[:, pad:-pad]).mean() threshold = 3e-2 self.assertLessEqual(difference, threshold)
def get_signal(self, amplitudes, wavetables, f0_hz): """Synthesize audio with additive synthesizer from controls. Args: amplitudes: Amplitude tensor of shape [batch, n_frames, 1]. Expects float32 that is strictly positive. wavetables: Tensor of shape [batch, n_frames, n_wavetable]. f0_hz: The fundamental frequency in Hertz. Tensor of shape [batch, n_frames, 1]. Returns: signal: A tensor of of shape [batch, n_samples]. """ wavetables = core.resample(wavetables, self.n_samples) signal = core.wavetable_synthesis(amplitudes=amplitudes, wavetables=wavetables, frequencies=f0_hz, n_samples=self.n_samples, sample_rate=self.sample_rate) return signal