@@ -349,7 +349,25 @@ def _f02uv(self, f0):
349
349
if uv .device .type == "privateuseone" : # for DirectML
350
350
uv = uv .float ()
351
351
return uv
352
-
352
+
353
+ def _f02sine (self , f0 , upp ):
354
+ """ f0: (batchsize, length, dim)
355
+ where dim indicates fundamental tone and overtones
356
+ """
357
+ a = torch .arange (1 , upp + 1 , dtype = f0 .dtype , device = f0 .device )
358
+ rad = f0 / self .sampling_rate * a
359
+ rad2 = torch .fmod (rad [:, :- 1 , - 1 :].float () + 0.5 , 1.0 ) - 0.5
360
+ rad_acc = rad2 .cumsum (dim = 1 ).fmod (1.0 ).to (f0 )
361
+ rad += F .pad (rad_acc , (0 , 0 , 1 , 0 ), mode = 'constant' )
362
+ rad = rad .reshape (f0 .shape [0 ], - 1 , 1 )
363
+ b = torch .arange (1 , self .dim + 1 , dtype = f0 .dtype , device = f0 .device ).reshape (1 , 1 , - 1 )
364
+ rad *= b
365
+ rand_ini = torch .rand (1 , 1 , self .dim , device = f0 .device )
366
+ rand_ini [..., 0 ] = 0
367
+ rad += rand_ini
368
+ sines = torch .sin (2 * np .pi * rad )
369
+ return sines
370
+
353
371
def forward (self , f0 : torch .Tensor , upp : int ):
354
372
"""sine_tensor, uv = forward(f0)
355
373
input F0: tensor(batchsize=1, length, dim=1)
@@ -358,45 +376,8 @@ def forward(self, f0: torch.Tensor, upp: int):
358
376
output uv: tensor(batchsize=1, length, 1)
359
377
"""
360
378
with torch .no_grad ():
361
- f0 = f0 [:, None ].transpose (1 , 2 )
362
- f0_buf = torch .zeros (f0 .shape [0 ], f0 .shape [1 ], self .dim , device = f0 .device )
363
- # fundamental component
364
- f0_buf [:, :, 0 ] = f0 [:, :, 0 ]
365
- for idx in range (self .harmonic_num ):
366
- f0_buf [:, :, idx + 1 ] = f0_buf [:, :, 0 ] * (
367
- idx + 2
368
- ) # idx + 2: the (idx+1)-th overtone, (idx+2)-th harmonic
369
- rad_values = (
370
- f0_buf / self .sampling_rate
371
- ) % 1 ###%1意味着n_har的乘积无法后处理优化
372
- rand_ini = torch .rand (
373
- f0_buf .shape [0 ], f0_buf .shape [2 ], device = f0_buf .device
374
- )
375
- rand_ini [:, 0 ] = 0
376
- rad_values [:, 0 , :] = rad_values [:, 0 , :] + rand_ini
377
- tmp_over_one = torch .cumsum (
378
- rad_values , 1
379
- ) # % 1 #####%1意味着后面的cumsum无法再优化
380
- tmp_over_one *= upp
381
- tmp_over_one = F .interpolate (
382
- tmp_over_one .transpose (2 , 1 ),
383
- scale_factor = float (upp ),
384
- mode = "linear" ,
385
- align_corners = True ,
386
- ).transpose (2 , 1 )
387
- rad_values = F .interpolate (
388
- rad_values .transpose (2 , 1 ), scale_factor = float (upp ), mode = "nearest"
389
- ).transpose (
390
- 2 , 1
391
- ) #######
392
- tmp_over_one %= 1
393
- tmp_over_one_idx = (tmp_over_one [:, 1 :, :] - tmp_over_one [:, :- 1 , :]) < 0
394
- cumsum_shift = torch .zeros_like (rad_values )
395
- cumsum_shift [:, 1 :, :] = tmp_over_one_idx * - 1.0
396
- sine_waves = torch .sin (
397
- torch .cumsum (rad_values + cumsum_shift , dim = 1 ) * 2 * torch .pi
398
- )
399
- sine_waves = sine_waves * self .sine_amp
379
+ f0 = f0 .unsqueeze (- 1 )
380
+ sine_waves = self ._f02sine (f0 , upp ) * self .sine_amp
400
381
uv = self ._f02uv (f0 )
401
382
uv = F .interpolate (
402
383
uv .transpose (2 , 1 ), scale_factor = float (upp ), mode = "nearest"
0 commit comments