Pulse train generator pulse_train, uv = forward(f0) input F0: tensor(batchsize=1, length, dim=1) f0 for unvoiced steps should be 0 output pulse_train: tensor(batchsize=1, length, dim) output uv: tensor(batchsize=1, length, 1) Note: self.l_s
(self, f0)
| 156 | flag_for_pulse=True) |
| 157 | |
| 158 | def forward(self, f0): |
| 159 | """ Pulse train generator |
| 160 | pulse_train, uv = forward(f0) |
| 161 | input F0: tensor(batchsize=1, length, dim=1) |
| 162 | f0 for unvoiced steps should be 0 |
| 163 | output pulse_train: tensor(batchsize=1, length, dim) |
| 164 | output uv: tensor(batchsize=1, length, 1) |
| 165 | |
| 166 | Note: self.l_sine doesn't make sure that the initial phase of |
| 167 | a voiced segment is np.pi, the first pulse in a voiced segment |
| 168 | may not be at the first time step within a voiced segment |
| 169 | """ |
| 170 | with torch.no_grad(): |
| 171 | sine_wav, uv, noise = self.l_sinegen(f0) |
| 172 | |
| 173 | # sine without additive noise |
| 174 | pure_sine = sine_wav - noise |
| 175 | |
| 176 | # step t corresponds to a pulse if |
| 177 | # sine[t] > sine[t+1] & sine[t] > sine[t-1] |
| 178 | # & sine[t-1], sine[t+1], and sine[t] are voiced |
| 179 | # or |
| 180 | # sine[t] is voiced, sine[t-1] is unvoiced |
| 181 | # we use torch.roll to simulate sine[t+1] and sine[t-1] |
| 182 | sine_1 = torch.roll(pure_sine, shifts=1, dims=1) |
| 183 | uv_1 = torch.roll(uv, shifts=1, dims=1) |
| 184 | uv_1[:, 0, :] = 0 |
| 185 | sine_2 = torch.roll(pure_sine, shifts=-1, dims=1) |
| 186 | uv_2 = torch.roll(uv, shifts=-1, dims=1) |
| 187 | uv_2[:, -1, :] = 0 |
| 188 | |
| 189 | loc = (pure_sine > sine_1) * (pure_sine > sine_2) \ |
| 190 | * (uv_1 > 0) * (uv_2 > 0) * (uv > 0) \ |
| 191 | + (uv_1 < 1) * (uv > 0) |
| 192 | |
| 193 | # pulse train without noise |
| 194 | pulse_train = pure_sine * loc |
| 195 | |
| 196 | # additive noise to pulse train |
| 197 | # note that noise from sinegen is zero in voiced regions |
| 198 | pulse_noise = torch.randn_like(pure_sine) * self.noise_std |
| 199 | |
| 200 | # with additive noise on pulse, and unvoiced regions |
| 201 | pulse_train += pulse_noise * loc + pulse_noise * (1 - uv) |
| 202 | return pulse_train, sine_wav, uv, pulse_noise |
| 203 | |
| 204 | |
| 205 | class SignalsConv1d(torch.nn.Module): |
nothing calls this directly
no outgoing calls
no test coverage detected