Definition of sine generator SineGen(samp_rate, harmonic_num = 0, sine_amp = 0.1, noise_std = 0.003, voiced_threshold = 0, flag_for_pulse=False) samp_rate: sampling rate in Hz harmonic_num: number of harmonic overtones (default 0) sine_amp: ampli
| 5 | |
| 6 | |
| 7 | class SineGen(torch.nn.Module): |
| 8 | """ Definition of sine generator |
| 9 | SineGen(samp_rate, harmonic_num = 0, |
| 10 | sine_amp = 0.1, noise_std = 0.003, |
| 11 | voiced_threshold = 0, |
| 12 | flag_for_pulse=False) |
| 13 | |
| 14 | samp_rate: sampling rate in Hz |
| 15 | harmonic_num: number of harmonic overtones (default 0) |
| 16 | sine_amp: amplitude of sine-wavefrom (default 0.1) |
| 17 | noise_std: std of Gaussian noise (default 0.003) |
| 18 | voiced_thoreshold: F0 threshold for U/V classification (default 0) |
| 19 | flag_for_pulse: this SinGen is used inside PulseGen (default False) |
| 20 | |
| 21 | Note: when flag_for_pulse is True, the first time step of a voiced |
| 22 | segment is always sin(np.pi) or cos(0) |
| 23 | """ |
| 24 | |
| 25 | def __init__(self, samp_rate, harmonic_num=0, |
| 26 | sine_amp=0.1, noise_std=0.003, |
| 27 | voiced_threshold=0, |
| 28 | flag_for_pulse=False): |
| 29 | super(SineGen, self).__init__() |
| 30 | self.sine_amp = sine_amp |
| 31 | self.noise_std = noise_std |
| 32 | self.harmonic_num = harmonic_num |
| 33 | self.dim = self.harmonic_num + 1 |
| 34 | self.sampling_rate = samp_rate |
| 35 | self.voiced_threshold = voiced_threshold |
| 36 | self.flag_for_pulse = flag_for_pulse |
| 37 | |
| 38 | def _f02uv(self, f0): |
| 39 | # generate uv signal |
| 40 | uv = torch.ones_like(f0) |
| 41 | uv = uv * (f0 > self.voiced_threshold) |
| 42 | return uv |
| 43 | |
| 44 | def _f02sine(self, f0_values): |
| 45 | """ f0_values: (batchsize, length, dim) |
| 46 | where dim indicates fundamental tone and overtones |
| 47 | """ |
| 48 | # convert to F0 in rad. The interger part n can be ignored |
| 49 | # because 2 * np.pi * n doesn't affect phase |
| 50 | rad_values = (f0_values / self.sampling_rate) % 1 |
| 51 | |
| 52 | # initial phase noise (no noise for fundamental component) |
| 53 | rand_ini = torch.rand(f0_values.shape[0], f0_values.shape[2], \ |
| 54 | device=f0_values.device) |
| 55 | rand_ini[:, 0] = 0 |
| 56 | rad_values[:, 0, :] = rad_values[:, 0, :] + rand_ini |
| 57 | |
| 58 | # instantanouse phase sine[t] = sin(2*pi \sum_i=1 ^{t} rad) |
| 59 | if not self.flag_for_pulse: |
| 60 | # for normal case |
| 61 | |
| 62 | # To prevent torch.cumsum numerical overflow, |
| 63 | # it is necessary to add -1 whenever \sum_k=1^n rad_value_k > 1. |
| 64 | # Buffer tmp_over_one_idx indicates the time step to add -1. |