f0_values: (batchsize, length, dim) where dim indicates fundamental tone and overtones
(self, f0_values)
| 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. |
| 65 | # This will not change F0 of sine because (x-1) * 2*pi = x * 2*pi |
| 66 | tmp_over_one = torch.cumsum(rad_values, 1) % 1 |
| 67 | tmp_over_one_idx = (tmp_over_one[:, 1:, :] - |
| 68 | tmp_over_one[:, :-1, :]) < 0 |
| 69 | cumsum_shift = torch.zeros_like(rad_values) |
| 70 | cumsum_shift[:, 1:, :] = tmp_over_one_idx * -1.0 |
| 71 | |
| 72 | sines = torch.sin(torch.cumsum(rad_values + cumsum_shift, dim=1) |
| 73 | * 2 * np.pi) |
| 74 | else: |
| 75 | # If necessary, make sure that the first time step of every |
| 76 | # voiced segments is sin(pi) or cos(0) |
| 77 | # This is used for pulse-train generation |
| 78 | |
| 79 | # identify the last time step in unvoiced segments |
| 80 | uv = self._f02uv(f0_values) |
| 81 | uv_1 = torch.roll(uv, shifts=-1, dims=1) |
| 82 | uv_1[:, -1, :] = 1 |
| 83 | u_loc = (uv < 1) * (uv_1 > 0) |
| 84 | |
| 85 | # get the instantanouse phase |
| 86 | tmp_cumsum = torch.cumsum(rad_values, dim=1) |
| 87 | # different batch needs to be processed differently |
| 88 | for idx in range(f0_values.shape[0]): |
| 89 | temp_sum = tmp_cumsum[idx, u_loc[idx, :, 0], :] |
| 90 | temp_sum[1:, :] = temp_sum[1:, :] - temp_sum[0:-1, :] |
| 91 | # stores the accumulation of i.phase within |
| 92 | # each voiced segments |
| 93 | tmp_cumsum[idx, :, :] = 0 |
| 94 | tmp_cumsum[idx, u_loc[idx, :, 0], :] = temp_sum |
| 95 | |
| 96 | # rad_values - tmp_cumsum: remove the accumulation of i.phase |
| 97 | # within the previous voiced segment. |
| 98 | i_phase = torch.cumsum(rad_values - tmp_cumsum, dim=1) |
| 99 | |
| 100 | # get the sines |
| 101 | sines = torch.cos(i_phase * 2 * np.pi) |