2929def generate_pulse (
3030 pitch : torch .Tensor ,
3131 phase : torch .Tensor ,
32- shift : float | torch .Tensor ,
3332 bipolar : bool ,
3433) -> torch .Tensor :
3534 def get_pulse_pos (p ):
3635 return torch .ge (torch .diff (torch .ceil (p )), 1 )
3736
3837 e = torch .zeros_like (pitch )
39-
40- padded_phase = F .pad (phase , (1 , 0 ))
41- padded_phase += shift
42-
43- pulse_pos = get_pulse_pos (padded_phase )
38+ pulse_pos = get_pulse_pos (phase )
4439 e [pulse_pos ] = torch .sqrt (pitch [pulse_pos ])
4540
4641 if bipolar :
47- pulse_pos_double = get_pulse_pos (0.5 * padded_phase )
42+ pulse_pos_double = get_pulse_pos (0.5 * phase )
4843 e [pulse_pos & ~ pulse_pos_double ] *= - 1
4944
5045 return e
@@ -53,30 +48,33 @@ def get_pulse_pos(p):
5348def generate_harmonic_pulse (
5449 pitch : torch .Tensor ,
5550 phase : torch .Tensor ,
56- shift : float | torch .Tensor ,
5751 bipolar : bool ,
58- power_factor : float = 0.1 ,
5952) -> torch .Tensor :
60- if not bipolar :
61- raise ValueError ("Harmonic pulse is only defined for bipolar polarity." )
62-
63- # number of harmonics = floor(0.5 * fs / f0) = floor(0.5 * 1 / T)
53+ # The number of harmonics is floor(0.5 * fs / f0) = floor(0.5 * 1 / T)
6454 n_harmonics = torch .floor (0.5 * pitch )
6555
6656 # The summation of sinusoids can be computed efficiently using the closed-form
6757 # expression of the Dirichlet kernel.
68- theta = TAU * (phase + shift )
69- numer = torch .cos (0.5 * theta ) - torch .cos ((n_harmonics + 0.5 ) * theta )
70- denom = 2 * torch .sin (0.5 * theta )
58+ theta = TAU * phase [..., :- 1 ]
59+ half_theta = 0.5 * theta
60+ if bipolar :
61+ numer = torch .cos (half_theta ) - torch .cos ((n_harmonics + 0.5 ) * theta )
62+ else :
63+ numer = - torch .sin (half_theta ) + torch .sin ((n_harmonics + 0.5 ) * theta )
64+ denom = 2 * torch .sin (half_theta )
7165
72- # Handle singularities at theta = 0, where the limit is the number of harmonics.
66+ # Handle singularities at phase is zero (i.e., harmonics) .
7367 eps = 1e-6
74- is_off_peak = denom .abs () > eps
75- safe_denom = torch .where (is_off_peak , denom , torch .ones_like (denom ))
68+ is_on_peak = denom .abs () < eps
69+ safe_denom = torch .where (is_on_peak , torch .ones_like (denom ), denom )
7670 e = numer / safe_denom
77- e = torch .where (is_off_peak , e , n_harmonics )
71+ if bipolar :
72+ e [is_on_peak ] = 0
73+ else :
74+ e [is_on_peak ] = n_harmonics [is_on_peak ]
7875
79- norm_factor = power_factor * torch .sqrt (2 / n_harmonics .clip (min = 1 ))
76+ # Normalize as the same energy as the pulse excitation.
77+ norm_factor = torch .sqrt (2 / n_harmonics .clip (min = 1 ))
8078 return norm_factor * e
8179
8280
@@ -244,13 +242,7 @@ def _forward(
244242 p = p .transpose (- 2 , - 1 )
245243 p *= mask
246244
247- # Compute phase.
248- voiced_pos = torch .gt (p , 0 )
249- q = torch .zeros_like (p )
250- q [voiced_pos ] = torch .reciprocal (p [voiced_pos ])
251- s = torch .cumsum (q .double (), dim = - 1 )
252- bias , _ = torch .cummax (s * ~ mask , dim = - 1 )
253- phase = (s - bias ).to (p .dtype )
245+ # Compute initial phase.
254246 if not isinstance (init_phase , str ):
255247 shift = init_phase / TAU
256248 elif init_phase == "zeros" :
@@ -260,6 +252,14 @@ def _forward(
260252 else :
261253 raise ValueError (f"init_phase { init_phase } is not supported." )
262254
255+ # Compute phase.
256+ voiced_pos = torch .gt (p , 0 )
257+ q = torch .zeros_like (p )
258+ q [voiced_pos ] = torch .reciprocal (p [voiced_pos ])
259+ s = torch .cumsum (q .double (), dim = - 1 )
260+ bias , _ = torch .cummax (s * ~ mask , dim = - 1 )
261+ phase = (s - bias ).to (p .dtype )
262+
263263 if polarity == "auto" :
264264 bipolar = voiced_region != "pulse"
265265 elif polarity in ("unipolar" , "bipolar" ):
@@ -274,7 +274,9 @@ def _forward(
274274 }
275275 if voiced_region not in generators :
276276 raise ValueError (f"voiced_region { voiced_region } is not supported." )
277- e = generators [voiced_region ](p , phase , shift , bipolar )
277+ phase = F .pad (phase , (1 , 0 ))
278+ phase += shift
279+ e = generators [voiced_region ](p , phase , bipolar )
278280 else :
279281 generators = {
280282 "sinusoidal" : generate_sinusoidal ,
0 commit comments