Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
prophesier
GitHub Repository: prophesier/diff-svc
Path: blob/main/modules/parallel_wavegan/stft_loss.py
694 views
1
# -*- coding: utf-8 -*-
2
3
# Copyright 2019 Tomoki Hayashi
4
# MIT License (https://opensource.org/licenses/MIT)
5
6
"""STFT-based Loss modules."""
7
import librosa
8
import torch
9
10
from modules.parallel_wavegan.losses import LogSTFTMagnitudeLoss, SpectralConvergengeLoss, stft
11
12
13
class STFTLoss(torch.nn.Module):
14
"""STFT loss module."""
15
16
def __init__(self, fft_size=1024, shift_size=120, win_length=600, window="hann_window",
17
use_mel_loss=False):
18
"""Initialize STFT loss module."""
19
super(STFTLoss, self).__init__()
20
self.fft_size = fft_size
21
self.shift_size = shift_size
22
self.win_length = win_length
23
self.window = getattr(torch, window)(win_length)
24
self.spectral_convergenge_loss = SpectralConvergengeLoss()
25
self.log_stft_magnitude_loss = LogSTFTMagnitudeLoss()
26
self.use_mel_loss = use_mel_loss
27
self.mel_basis = None
28
29
def forward(self, x, y):
30
"""Calculate forward propagation.
31
32
Args:
33
x (Tensor): Predicted signal (B, T).
34
y (Tensor): Groundtruth signal (B, T).
35
36
Returns:
37
Tensor: Spectral convergence loss value.
38
Tensor: Log STFT magnitude loss value.
39
40
"""
41
x_mag = stft(x, self.fft_size, self.shift_size, self.win_length, self.window)
42
y_mag = stft(y, self.fft_size, self.shift_size, self.win_length, self.window)
43
if self.use_mel_loss:
44
if self.mel_basis is None:
45
self.mel_basis = torch.from_numpy(librosa.filters.mel(22050, self.fft_size, 80)).cuda().T
46
x_mag = x_mag @ self.mel_basis
47
y_mag = y_mag @ self.mel_basis
48
49
sc_loss = self.spectral_convergenge_loss(x_mag, y_mag)
50
mag_loss = self.log_stft_magnitude_loss(x_mag, y_mag)
51
52
return sc_loss, mag_loss
53
54
55
class MultiResolutionSTFTLoss(torch.nn.Module):
56
"""Multi resolution STFT loss module."""
57
58
def __init__(self,
59
fft_sizes=[1024, 2048, 512],
60
hop_sizes=[120, 240, 50],
61
win_lengths=[600, 1200, 240],
62
window="hann_window",
63
use_mel_loss=False):
64
"""Initialize Multi resolution STFT loss module.
65
66
Args:
67
fft_sizes (list): List of FFT sizes.
68
hop_sizes (list): List of hop sizes.
69
win_lengths (list): List of window lengths.
70
window (str): Window function type.
71
72
"""
73
super(MultiResolutionSTFTLoss, self).__init__()
74
assert len(fft_sizes) == len(hop_sizes) == len(win_lengths)
75
self.stft_losses = torch.nn.ModuleList()
76
for fs, ss, wl in zip(fft_sizes, hop_sizes, win_lengths):
77
self.stft_losses += [STFTLoss(fs, ss, wl, window, use_mel_loss)]
78
79
def forward(self, x, y):
80
"""Calculate forward propagation.
81
82
Args:
83
x (Tensor): Predicted signal (B, T).
84
y (Tensor): Groundtruth signal (B, T).
85
86
Returns:
87
Tensor: Multi resolution spectral convergence loss value.
88
Tensor: Multi resolution log STFT magnitude loss value.
89
90
"""
91
sc_loss = 0.0
92
mag_loss = 0.0
93
for f in self.stft_losses:
94
sc_l, mag_l = f(x, y)
95
sc_loss += sc_l
96
mag_loss += mag_l
97
sc_loss /= len(self.stft_losses)
98
mag_loss /= len(self.stft_losses)
99
100
return sc_loss, mag_loss
101
102