├── fig
├── figure_mel.png
└── proposed_model.png
├── requirements.txt
├── monotonic_align
├── setup.py
├── __init__.py
└── core.pyx
├── dataset
├── homebrew
│ └── transcript_utf8.txt
├── preprocess.py
└── ita
│ └── transcript_utf8.txt
├── text
├── symbols.py
├── __init__.py
└── cleaners.py
├── configs
├── ita_44100.json
├── jsut_44100.json
├── ita_44100_+2_uprate.json
├── homebrew_44100.json
├── jsut_44100_+2_uprate.json
└── homebrew_44100_+2_uprate.json
├── losses.py
├── g2p.py
├── mel_processing.py
├── pqmf.py
├── stft_loss.py
├── inference.py
├── README.md
├── commons.py
├── transforms.py
├── stft.py
├── utils.py
├── LICENSE
├── attentions.py
├── modules.py
├── train_latest.py
└── data_utils.py
/fig/figure_mel.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/tonnetonne814/MB-iSTFT-VITS-44100-Ja/HEAD/fig/figure_mel.png
--------------------------------------------------------------------------------
/fig/proposed_model.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/tonnetonne814/MB-iSTFT-VITS-44100-Ja/HEAD/fig/proposed_model.png
--------------------------------------------------------------------------------
/requirements.txt:
--------------------------------------------------------------------------------
1 | Cython
2 | librosa==0.8.0
3 | matplotlib
4 | numpy
5 | phonemizer
6 | scipy
7 | tensorboard
8 | Unidecode
9 | pyopenjtalk==0.2.0
10 | soundcard
--------------------------------------------------------------------------------
/monotonic_align/setup.py:
--------------------------------------------------------------------------------
1 | from distutils.core import setup
2 | from Cython.Build import cythonize
3 | import numpy
4 |
5 | setup(
6 | name = 'monotonic_align',
7 | ext_modules = cythonize("core.pyx"),
8 | include_dirs=[numpy.get_include()]
9 | )
10 |
--------------------------------------------------------------------------------
/dataset/homebrew/transcript_utf8.txt:
--------------------------------------------------------------------------------
1 | wavファイル名(拡張子無):発話テキスト
2 | wavファイル名(拡張子無):発話テキスト
3 | wavファイル名(拡張子無):発話テキスト
4 | wavファイル名(拡張子無):発話テキスト
5 | wavファイル名(拡張子無):発話テキスト
6 | wavファイル名(拡張子無):発話テキスト
7 | wavファイル名(拡張子無):発話テキスト
8 | wavファイル名(拡張子無):発話テキスト
9 | wavファイル名(拡張子無):発話テキスト
10 | wavファイル名(拡張子無):発話テキスト
11 | wavファイル名(拡張子無):発話テキスト
12 | wavファイル名(拡張子無):発話テキスト
13 | wavファイル名(拡張子無):発話テキスト
14 | wavファイル名(拡張子無):発話テキスト
15 |
--------------------------------------------------------------------------------
/monotonic_align/__init__.py:
--------------------------------------------------------------------------------
1 | import numpy as np
2 | import torch
3 | from .monotonic_align.core import maximum_path_c
4 |
5 |
6 | def maximum_path(neg_cent, mask):
7 | """ Cython optimized version.
8 | neg_cent: [b, t_t, t_s]
9 | mask: [b, t_t, t_s]
10 | """
11 | device = neg_cent.device
12 | dtype = neg_cent.dtype
13 | neg_cent = neg_cent.data.cpu().numpy().astype(np.float32)
14 | path = np.zeros(neg_cent.shape, dtype=np.int32)
15 |
16 | t_t_max = mask.sum(1)[:, 0].data.cpu().numpy().astype(np.int32)
17 | t_s_max = mask.sum(2)[:, 0].data.cpu().numpy().astype(np.int32)
18 | maximum_path_c(path, neg_cent, t_t_max, t_s_max)
19 | return torch.from_numpy(path).to(device=device, dtype=dtype)
20 |
--------------------------------------------------------------------------------
/text/symbols.py:
--------------------------------------------------------------------------------
1 | """ from https://github.com/keithito/tacotron """
2 |
3 | '''
4 | Defines the set of symbols used in text input to the model.
5 | '''
6 |
7 |
8 | """
9 | _pad = '_'
10 | _punctuation = ';:,.!?¡¿—…"«»“” '
11 | _letters = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz'
12 | _letters_ipa = "ɑɐɒæɓʙβɔɕçɗɖðʤəɘɚɛɜɝɞɟʄɡɠɢʛɦɧħɥʜɨɪʝɭɬɫɮʟɱɯɰŋɳɲɴøɵɸθœɶʘɹɺɾɻʀʁɽʂʃʈʧʉʊʋⱱʌɣɤʍχʎʏʑʐʒʔʡʕʢǀǁǂǃˈˌːˑʼʴʰʱʲʷˠˤ˞↓↑→↗↘'̩'ᵻ"
13 |
14 |
15 | # Export all symbols:
16 | symbols = [_pad] + list(_punctuation) + list(_letters) + list(_letters_ipa)
17 |
18 | # Special symbol ids
19 | SPACE_ID = symbols.index(" ")
20 |
21 | print(SPACE_ID)
22 | """
23 |
24 | ### add Japanese phonomes by pyopenjtalk_g2p_prosody ###
25 | symbols = [
26 | '_' , '#' , '$' , '[' , '?' , ']' , '^' ,
27 | 'a' , 'b' , 'by', 'ch', 'cl', 'd' , 'dy',
28 | 'e' , 'f' , 'g' , 'gy', 'h' , 'hy', 'i' ,
29 | 'j' , 'k' , 'ky', 'm' , 'my', 'n' , 'N' ,
30 | 'ny', 'o' , 'p' , 'py', 'r' , 'ry', 's' ,
31 | 'sh', 't' , 'ts', 'ty', 'u' , 'v' , 'w',
32 | 'y' , 'z' ]
33 | ########################################################
--------------------------------------------------------------------------------
/monotonic_align/core.pyx:
--------------------------------------------------------------------------------
1 | cimport cython
2 | from cython.parallel import prange
3 |
4 |
5 | @cython.boundscheck(False)
6 | @cython.wraparound(False)
7 | cdef void maximum_path_each(int[:,::1] path, float[:,::1] value, int t_y, int t_x, float max_neg_val=-1e9) nogil:
8 | cdef int x
9 | cdef int y
10 | cdef float v_prev
11 | cdef float v_cur
12 | cdef float tmp
13 | cdef int index = t_x - 1
14 |
15 | for y in range(t_y):
16 | for x in range(max(0, t_x + y - t_y), min(t_x, y + 1)):
17 | if x == y:
18 | v_cur = max_neg_val
19 | else:
20 | v_cur = value[y-1, x]
21 | if x == 0:
22 | if y == 0:
23 | v_prev = 0.
24 | else:
25 | v_prev = max_neg_val
26 | else:
27 | v_prev = value[y-1, x-1]
28 | value[y, x] += max(v_prev, v_cur)
29 |
30 | for y in range(t_y - 1, -1, -1):
31 | path[y, index] = 1
32 | if index != 0 and (index == y or value[y-1, index] < value[y-1, index-1]):
33 | index = index - 1
34 |
35 |
36 | @cython.boundscheck(False)
37 | @cython.wraparound(False)
38 | cpdef void maximum_path_c(int[:,:,::1] paths, float[:,:,::1] values, int[::1] t_ys, int[::1] t_xs) nogil:
39 | cdef int b = paths.shape[0]
40 | cdef int i
41 | for i in prange(b, nogil=True):
42 | maximum_path_each(paths[i], values[i], t_ys[i], t_xs[i])
43 |
--------------------------------------------------------------------------------
/configs/ita_44100.json:
--------------------------------------------------------------------------------
1 | {
2 | "train": {
3 | "log_interval": 200,
4 | "eval_interval": 10000,
5 | "seed": 1234,
6 | "epochs": 1000,
7 | "learning_rate": 2e-4,
8 | "betas": [0.8, 0.99],
9 | "eps": 1e-9,
10 | "batch_size": 64,
11 | "fp16_run": false,
12 | "lr_decay": 0.999875,
13 | "segment_size": 16384,
14 | "init_lr_ratio": 1,
15 | "warmup_epochs": 0,
16 | "c_mel": 45,
17 | "c_kl": 1.0,
18 | "fft_sizes": [768, 1366, 342],
19 | "hop_sizes": [60, 120, 20],
20 | "win_lengths": [300, 600, 120],
21 | "window": "hann_window" ,
22 | "finetune_model_dir" : "checkpoints/"
23 | },
24 | "data": {
25 | "training_files":"filelists/ita_train_44100.txt",
26 | "validation_files":"filelists/ita_val_44100.txt",
27 | "text_cleaners":[],
28 | "max_wav_value": 32768.0,
29 | "sampling_rate": 44100,
30 | "filter_length": 2048,
31 | "hop_length": 512,
32 | "win_length": 2048,
33 | "n_mel_channels": 80,
34 | "mel_fmin": 0.0,
35 | "mel_fmax": null,
36 | "add_blank": false,
37 | "n_speakers": 0,
38 | "cleaned_text": false
39 | },
40 | "model": {
41 | "ms_istft_vits": true,
42 | "mb_istft_vits": false,
43 | "istft_vits": false,
44 | "subbands": 8,
45 | "gen_istft_n_fft": 16,
46 | "gen_istft_hop_size": 4,
47 | "inter_channels": 192,
48 | "hidden_channels": 192,
49 | "filter_channels": 768,
50 | "n_heads": 2,
51 | "n_layers": 6,
52 | "kernel_size": 3,
53 | "p_dropout": 0.1,
54 | "resblock": "1",
55 | "resblock_kernel_sizes": [3,7,11],
56 | "resblock_dilation_sizes": [[1,3,5], [1,3,5], [1,3,5]],
57 | "upsample_rates": [4,4],
58 | "upsample_initial_channel": 512,
59 | "upsample_kernel_sizes": [16,16],
60 | "n_layers_q": 3,
61 | "use_spectral_norm": false,
62 | "use_sdp": true
63 | }
64 |
65 | }
66 |
67 |
--------------------------------------------------------------------------------
/configs/jsut_44100.json:
--------------------------------------------------------------------------------
1 | {
2 | "train": {
3 | "log_interval": 200,
4 | "eval_interval": 10000,
5 | "seed": 1234,
6 | "epochs": 1000,
7 | "learning_rate": 2e-4,
8 | "betas": [0.8, 0.99],
9 | "eps": 1e-9,
10 | "batch_size": 64,
11 | "fp16_run": false,
12 | "lr_decay": 0.999875,
13 | "segment_size": 16384,
14 | "init_lr_ratio": 1,
15 | "warmup_epochs": 0,
16 | "c_mel": 45,
17 | "c_kl": 1.0,
18 | "fft_sizes": [768, 1366, 342],
19 | "hop_sizes": [60, 120, 20],
20 | "win_lengths": [300, 600, 120],
21 | "window": "hann_window" ,
22 | "finetune_model_dir" : "checkpoints/"
23 | },
24 | "data": {
25 | "training_files":"filelists/jsut_train_44100.txt",
26 | "validation_files":"filelists/jsut_val_44100.txt",
27 | "text_cleaners":[],
28 | "max_wav_value": 32768.0,
29 | "sampling_rate": 44100,
30 | "filter_length": 2048,
31 | "hop_length": 512,
32 | "win_length": 2048,
33 | "n_mel_channels": 80,
34 | "mel_fmin": 0.0,
35 | "mel_fmax": null,
36 | "add_blank": false,
37 | "n_speakers": 0,
38 | "cleaned_text": false
39 | },
40 | "model": {
41 | "ms_istft_vits": true,
42 | "mb_istft_vits": false,
43 | "istft_vits": false,
44 | "subbands": 8,
45 | "gen_istft_n_fft": 16,
46 | "gen_istft_hop_size": 4,
47 | "inter_channels": 192,
48 | "hidden_channels": 192,
49 | "filter_channels": 768,
50 | "n_heads": 2,
51 | "n_layers": 6,
52 | "kernel_size": 3,
53 | "p_dropout": 0.1,
54 | "resblock": "1",
55 | "resblock_kernel_sizes": [3,7,11],
56 | "resblock_dilation_sizes": [[1,3,5], [1,3,5], [1,3,5]],
57 | "upsample_rates": [4,4],
58 | "upsample_initial_channel": 512,
59 | "upsample_kernel_sizes": [16,16],
60 | "n_layers_q": 3,
61 | "use_spectral_norm": false,
62 | "use_sdp": true
63 | }
64 |
65 | }
66 |
67 |
--------------------------------------------------------------------------------
/configs/ita_44100_+2_uprate.json:
--------------------------------------------------------------------------------
1 | {
2 | "train": {
3 | "log_interval": 200,
4 | "eval_interval": 10000,
5 | "seed": 1234,
6 | "epochs": 1000,
7 | "learning_rate": 2e-4,
8 | "betas": [0.8, 0.99],
9 | "eps": 1e-9,
10 | "batch_size": 32,
11 | "fp16_run": false,
12 | "lr_decay": 0.999875,
13 | "segment_size": 16384,
14 | "init_lr_ratio": 1,
15 | "warmup_epochs": 0,
16 | "c_mel": 45,
17 | "c_kl": 1.0,
18 | "fft_sizes": [768, 1366, 342],
19 | "hop_sizes": [60, 120, 20],
20 | "win_lengths": [300, 600, 120],
21 | "window": "hann_window" ,
22 | "finetune_model_dir" : "checkpoints/"
23 | },
24 | "data": {
25 | "training_files":"filelists/ita_train_44100.txt",
26 | "validation_files":"filelists/ita_val_44100.txt",
27 | "text_cleaners":[],
28 | "max_wav_value": 32768.0,
29 | "sampling_rate": 44100,
30 | "filter_length": 2048,
31 | "hop_length": 512,
32 | "win_length": 2048,
33 | "n_mel_channels": 80,
34 | "mel_fmin": 0.0,
35 | "mel_fmax": null,
36 | "add_blank": false,
37 | "n_speakers": 0,
38 | "cleaned_text": true
39 | },
40 | "model": {
41 | "ms_istft_vits": true,
42 | "mb_istft_vits": false,
43 | "istft_vits": false,
44 | "subbands": 4,
45 | "gen_istft_n_fft": 16,
46 | "gen_istft_hop_size": 4,
47 | "inter_channels": 192,
48 | "hidden_channels": 192,
49 | "filter_channels": 768,
50 | "n_heads": 2,
51 | "n_layers": 6,
52 | "kernel_size": 3,
53 | "p_dropout": 0.1,
54 | "resblock": "1",
55 | "resblock_kernel_sizes": [3,7,11],
56 | "resblock_dilation_sizes": [[1,3,5], [1,3,5], [1,3,5]],
57 | "upsample_rates": [4,4,2],
58 | "upsample_initial_channel": 512,
59 | "upsample_kernel_sizes": [16,16,8],
60 | "n_layers_q": 3,
61 | "use_spectral_norm": false,
62 | "use_sdp": false
63 | }
64 |
65 | }
66 |
67 |
--------------------------------------------------------------------------------
/configs/homebrew_44100.json:
--------------------------------------------------------------------------------
1 | {
2 | "train": {
3 | "log_interval": 200,
4 | "eval_interval": 10000,
5 | "seed": 1234,
6 | "epochs": 1000,
7 | "learning_rate": 2e-4,
8 | "betas": [0.8, 0.99],
9 | "eps": 1e-9,
10 | "batch_size": 64,
11 | "fp16_run": false,
12 | "lr_decay": 0.999875,
13 | "segment_size": 16384,
14 | "init_lr_ratio": 1,
15 | "warmup_epochs": 0,
16 | "c_mel": 45,
17 | "c_kl": 1.0,
18 | "fft_sizes": [768, 1366, 342],
19 | "hop_sizes": [60, 120, 20],
20 | "win_lengths": [300, 600, 120],
21 | "window": "hann_window" ,
22 | "finetune_model_dir" : "checkpoints/"
23 | },
24 | "data": {
25 | "training_files":"filelists/homebrew_train_44100.txt",
26 | "validation_files":"filelists/homebrew_train_44100.txt",
27 | "text_cleaners":[],
28 | "max_wav_value": 32768.0,
29 | "sampling_rate": 44100,
30 | "filter_length": 2048,
31 | "hop_length": 512,
32 | "win_length": 2048,
33 | "n_mel_channels": 80,
34 | "mel_fmin": 0.0,
35 | "mel_fmax": null,
36 | "add_blank": false,
37 | "n_speakers": 0,
38 | "cleaned_text": false
39 | },
40 | "model": {
41 | "ms_istft_vits": true,
42 | "mb_istft_vits": false,
43 | "istft_vits": false,
44 | "subbands": 8,
45 | "gen_istft_n_fft": 16,
46 | "gen_istft_hop_size": 4,
47 | "inter_channels": 192,
48 | "hidden_channels": 192,
49 | "filter_channels": 768,
50 | "n_heads": 2,
51 | "n_layers": 6,
52 | "kernel_size": 3,
53 | "p_dropout": 0.1,
54 | "resblock": "1",
55 | "resblock_kernel_sizes": [3,7,11],
56 | "resblock_dilation_sizes": [[1,3,5], [1,3,5], [1,3,5]],
57 | "upsample_rates": [4,4],
58 | "upsample_initial_channel": 512,
59 | "upsample_kernel_sizes": [16,16],
60 | "n_layers_q": 3,
61 | "use_spectral_norm": false,
62 | "use_sdp": true
63 | }
64 |
65 | }
66 |
67 |
--------------------------------------------------------------------------------
/configs/jsut_44100_+2_uprate.json:
--------------------------------------------------------------------------------
1 | {
2 | "train": {
3 | "log_interval": 200,
4 | "eval_interval": 10000,
5 | "seed": 1234,
6 | "epochs": 1000,
7 | "learning_rate": 2e-4,
8 | "betas": [0.8, 0.99],
9 | "eps": 1e-9,
10 | "batch_size": 32,
11 | "fp16_run": false,
12 | "lr_decay": 0.999875,
13 | "segment_size": 16384,
14 | "init_lr_ratio": 1,
15 | "warmup_epochs": 0,
16 | "c_mel": 45,
17 | "c_kl": 1.0,
18 | "fft_sizes": [768, 1366, 342],
19 | "hop_sizes": [60, 120, 20],
20 | "win_lengths": [300, 600, 120],
21 | "window": "hann_window" ,
22 | "finetune_model_dir" : "checkpoints/"
23 | },
24 | "data": {
25 | "training_files":"filelists/jsut_train_44100.txt",
26 | "validation_files":"filelists/jsut_val_44100.txt",
27 | "text_cleaners":[],
28 | "max_wav_value": 32768.0,
29 | "sampling_rate": 44100,
30 | "filter_length": 2048,
31 | "hop_length": 512,
32 | "win_length": 2048,
33 | "n_mel_channels": 80,
34 | "mel_fmin": 0.0,
35 | "mel_fmax": null,
36 | "add_blank": false,
37 | "n_speakers": 0,
38 | "cleaned_text": true
39 | },
40 | "model": {
41 | "ms_istft_vits": true,
42 | "mb_istft_vits": false,
43 | "istft_vits": false,
44 | "subbands": 4,
45 | "gen_istft_n_fft": 16,
46 | "gen_istft_hop_size": 4,
47 | "inter_channels": 192,
48 | "hidden_channels": 192,
49 | "filter_channels": 768,
50 | "n_heads": 2,
51 | "n_layers": 6,
52 | "kernel_size": 3,
53 | "p_dropout": 0.1,
54 | "resblock": "1",
55 | "resblock_kernel_sizes": [3,7,11],
56 | "resblock_dilation_sizes": [[1,3,5], [1,3,5], [1,3,5]],
57 | "upsample_rates": [4,4,2],
58 | "upsample_initial_channel": 512,
59 | "upsample_kernel_sizes": [16,16,8],
60 | "n_layers_q": 3,
61 | "use_spectral_norm": false,
62 | "use_sdp": false
63 | }
64 |
65 | }
66 |
67 |
--------------------------------------------------------------------------------
/configs/homebrew_44100_+2_uprate.json:
--------------------------------------------------------------------------------
1 | {
2 | "train": {
3 | "log_interval": 200,
4 | "eval_interval": 10000,
5 | "seed": 1234,
6 | "epochs": 1000,
7 | "learning_rate": 2e-4,
8 | "betas": [0.8, 0.99],
9 | "eps": 1e-9,
10 | "batch_size": 32,
11 | "fp16_run": false,
12 | "lr_decay": 0.999875,
13 | "segment_size": 16384,
14 | "init_lr_ratio": 1,
15 | "warmup_epochs": 0,
16 | "c_mel": 45,
17 | "c_kl": 1.0,
18 | "fft_sizes": [768, 1366, 342],
19 | "hop_sizes": [60, 120, 20],
20 | "win_lengths": [300, 600, 120],
21 | "window": "hann_window" ,
22 | "finetune_model_dir" : "checkpoints/"
23 | },
24 | "data": {
25 | "training_files":"filelists/homebrew_train_44100.txt",
26 | "validation_files":"filelists/homebrew_train_44100.txt",
27 | "text_cleaners":[],
28 | "max_wav_value": 32768.0,
29 | "sampling_rate": 44100,
30 | "filter_length": 2048,
31 | "hop_length": 512,
32 | "win_length": 2048,
33 | "n_mel_channels": 80,
34 | "mel_fmin": 0.0,
35 | "mel_fmax": null,
36 | "add_blank": false,
37 | "n_speakers": 0,
38 | "cleaned_text": false
39 | },
40 | "model": {
41 | "ms_istft_vits": true,
42 | "mb_istft_vits": false,
43 | "istft_vits": false,
44 | "subbands": 4,
45 | "gen_istft_n_fft": 16,
46 | "gen_istft_hop_size": 4,
47 | "inter_channels": 192,
48 | "hidden_channels": 192,
49 | "filter_channels": 768,
50 | "n_heads": 2,
51 | "n_layers": 6,
52 | "kernel_size": 3,
53 | "p_dropout": 0.1,
54 | "resblock": "1",
55 | "resblock_kernel_sizes": [3,7,11],
56 | "resblock_dilation_sizes": [[1,3,5], [1,3,5], [1,3,5]],
57 | "upsample_rates": [4,4,2],
58 | "upsample_initial_channel": 512,
59 | "upsample_kernel_sizes": [16,16,8],
60 | "n_layers_q": 3,
61 | "use_spectral_norm": false,
62 | "use_sdp": false
63 | }
64 |
65 | }
66 |
67 |
--------------------------------------------------------------------------------
/losses.py:
--------------------------------------------------------------------------------
1 | import torch
2 | from torch.nn import functional as F
3 | from stft_loss import MultiResolutionSTFTLoss
4 |
5 |
6 | import commons
7 |
8 |
9 | def feature_loss(fmap_r, fmap_g):
10 | loss = 0
11 | for dr, dg in zip(fmap_r, fmap_g):
12 | for rl, gl in zip(dr, dg):
13 | rl = rl.float().detach()
14 | gl = gl.float()
15 | loss += torch.mean(torch.abs(rl - gl))
16 |
17 | return loss * 2
18 |
19 |
20 | def discriminator_loss(disc_real_outputs, disc_generated_outputs):
21 | loss = 0
22 | r_losses = []
23 | g_losses = []
24 | for dr, dg in zip(disc_real_outputs, disc_generated_outputs):
25 | dr = dr.float()
26 | dg = dg.float()
27 | r_loss = torch.mean((1-dr)**2)
28 | g_loss = torch.mean(dg**2)
29 | loss += (r_loss + g_loss)
30 | r_losses.append(r_loss.item())
31 | g_losses.append(g_loss.item())
32 |
33 | return loss, r_losses, g_losses
34 |
35 |
36 | def generator_loss(disc_outputs):
37 | loss = 0
38 | gen_losses = []
39 | for dg in disc_outputs:
40 | dg = dg.float()
41 | l = torch.mean((1-dg)**2)
42 | gen_losses.append(l)
43 | loss += l
44 |
45 | return loss, gen_losses
46 |
47 |
48 | def kl_loss(z_p, logs_q, m_p, logs_p, z_mask):
49 | """
50 | z_p, logs_q: [b, h, t_t]
51 | m_p, logs_p: [b, h, t_t]
52 | """
53 | z_p = z_p.float()
54 | logs_q = logs_q.float()
55 | m_p = m_p.float()
56 | logs_p = logs_p.float()
57 | z_mask = z_mask.float()
58 |
59 | kl = logs_p - logs_q - 0.5
60 | kl += 0.5 * ((z_p - m_p)**2) * torch.exp(-2. * logs_p)
61 | kl = torch.sum(kl * z_mask)
62 | l = kl / torch.sum(z_mask)
63 | return l
64 |
65 | def subband_stft_loss(h, y_mb, y_hat_mb):
66 | sub_stft_loss = MultiResolutionSTFTLoss(h.train.fft_sizes, h.train.hop_sizes, h.train.win_lengths)
67 | y_mb = y_mb.view(-1, y_mb.size(2))
68 | y_hat_mb = y_hat_mb.view(-1, y_hat_mb.size(2))
69 | sub_sc_loss, sub_mag_loss = sub_stft_loss(y_hat_mb[:, :y_mb.size(-1)], y_mb)
70 | return sub_sc_loss+sub_mag_loss
71 |
72 |
--------------------------------------------------------------------------------
/text/__init__.py:
--------------------------------------------------------------------------------
1 | """ from https://github.com/keithito/tacotron """
2 | from text import cleaners
3 | from text.symbols import symbols
4 | from g2p import pyopenjtalk_g2p_prosody
5 |
6 |
7 | # Mappings from symbol to numeric ID and vice versa:
8 | _symbol_to_id = {s: i for i, s in enumerate(symbols)}
9 | _id_to_symbol = {i: s for i, s in enumerate(symbols)}
10 |
11 |
12 | def text_to_sequence(text, cleaner_names):
13 | '''Converts a string of text to a sequence of IDs corresponding to the symbols in the text.
14 | Args:
15 | text: string to convert to a sequence
16 | cleaner_names: names of the cleaner functions to run the text through
17 | Returns:
18 | List of integers corresponding to the symbols in the text
19 | '''
20 | sequence = []
21 |
22 | #clean_text = _clean_text(text, cleaner_names)
23 | #print(text)
24 | clean_text = pyopenjtalk_g2p_prosody(text[0])
25 | for symbol in clean_text:
26 | symbol_id = _symbol_to_id[symbol]
27 | sequence += [symbol_id]
28 | return sequence
29 |
30 |
31 | def infer_g2p(text, cleaner_names):
32 | sequence = []
33 |
34 | #clean_text = _clean_text(text, cleaner_names)
35 | #print(text)
36 | clean_text = pyopenjtalk_g2p_prosody(text)
37 | for symbol in clean_text:
38 | symbol_id = _symbol_to_id[symbol]
39 | sequence += [symbol_id]
40 | return sequence
41 |
42 |
43 | def cleaned_text_to_sequence(cleaned_text):
44 | '''Converts a string of text to a sequence of IDs corresponding to the symbols in the text.
45 | Args:
46 | text: string to convert to a sequence
47 | Returns:
48 | List of integers corresponding to the symbols in the text
49 | '''
50 | sequence = [_symbol_to_id[symbol] for symbol in cleaned_text]
51 | return sequence
52 |
53 |
54 | def sequence_to_text(sequence):
55 | '''Converts a sequence of IDs back to a string'''
56 | result = ''
57 | for symbol_id in sequence:
58 | s = _id_to_symbol[symbol_id]
59 | result += s
60 | return result
61 |
62 |
63 | def _clean_text(text, cleaner_names):
64 | for name in cleaner_names:
65 | cleaner = getattr(cleaners, name)
66 | if not cleaner:
67 | raise Exception('Unknown cleaner: %s' % name)
68 | text = cleaner(text)
69 | return text
70 |
--------------------------------------------------------------------------------
/text/cleaners.py:
--------------------------------------------------------------------------------
1 | """ from https://github.com/keithito/tacotron """
2 |
3 | '''
4 | Cleaners are transformations that run over the input text at both training and eval time.
5 |
6 | Cleaners can be selected by passing a comma-delimited list of cleaner names as the "cleaners"
7 | hyperparameter. Some cleaners are English-specific. You'll typically want to use:
8 | 1. "english_cleaners" for English text
9 | 2. "transliteration_cleaners" for non-English text that can be transliterated to ASCII using
10 | the Unidecode library (https://pypi.python.org/pypi/Unidecode)
11 | 3. "basic_cleaners" if you do not want to transliterate (in this case, you should also update
12 | the symbols in symbols.py to match your data).
13 | '''
14 |
15 | import re
16 | from unidecode import unidecode
17 | from phonemizer import phonemize
18 |
19 |
20 | # Regular expression matching whitespace:
21 | _whitespace_re = re.compile(r'\s+')
22 |
23 | # List of (regular expression, replacement) pairs for abbreviations:
24 | _abbreviations = [(re.compile('\\b%s\\.' % x[0], re.IGNORECASE), x[1]) for x in [
25 | ('mrs', 'misess'),
26 | ('mr', 'mister'),
27 | ('dr', 'doctor'),
28 | ('st', 'saint'),
29 | ('co', 'company'),
30 | ('jr', 'junior'),
31 | ('maj', 'major'),
32 | ('gen', 'general'),
33 | ('drs', 'doctors'),
34 | ('rev', 'reverend'),
35 | ('lt', 'lieutenant'),
36 | ('hon', 'honorable'),
37 | ('sgt', 'sergeant'),
38 | ('capt', 'captain'),
39 | ('esq', 'esquire'),
40 | ('ltd', 'limited'),
41 | ('col', 'colonel'),
42 | ('ft', 'fort'),
43 | ]]
44 |
45 |
46 | def expand_abbreviations(text):
47 | for regex, replacement in _abbreviations:
48 | text = re.sub(regex, replacement, text)
49 | return text
50 |
51 |
52 | def expand_numbers(text):
53 | return normalize_numbers(text)
54 |
55 |
56 | def lowercase(text):
57 | return text.lower()
58 |
59 |
60 | def collapse_whitespace(text):
61 | return re.sub(_whitespace_re, ' ', text)
62 |
63 |
64 | def convert_to_ascii(text):
65 | return unidecode(text)
66 |
67 |
68 | def basic_cleaners(text):
69 | '''Basic pipeline that lowercases and collapses whitespace without transliteration.'''
70 | text = lowercase(text)
71 | text = collapse_whitespace(text)
72 | return text
73 |
74 |
75 | def transliteration_cleaners(text):
76 | '''Pipeline for non-English text that transliterates to ASCII.'''
77 | text = convert_to_ascii(text)
78 | text = lowercase(text)
79 | text = collapse_whitespace(text)
80 | return text
81 |
82 |
83 | def english_cleaners(text):
84 | '''Pipeline for English text, including abbreviation expansion.'''
85 | text = convert_to_ascii(text)
86 | text = lowercase(text)
87 | text = expand_abbreviations(text)
88 | phonemes = phonemize(text, language='en-us', backend='espeak', strip=True)
89 | phonemes = collapse_whitespace(phonemes)
90 | return phonemes
91 |
92 |
93 | def english_cleaners2(text):
94 | '''Pipeline for English text, including abbreviation expansion. + punctuation + stress'''
95 | text = convert_to_ascii(text)
96 | text = lowercase(text)
97 | text = expand_abbreviations(text)
98 | phonemes = phonemize(text, language='en-us', backend='espeak', strip=True, preserve_punctuation=True, with_stress=True)
99 | phonemes = collapse_whitespace(phonemes)
100 | return phonemes
101 |
--------------------------------------------------------------------------------
/g2p.py:
--------------------------------------------------------------------------------
1 | import pyopenjtalk, re
2 | from packaging.version import parse as V
3 |
4 |
5 | ### Add from espnet ###
6 | # ESPNet:https://github.com/espnet/espnet
7 | #######################
8 | def pyopenjtalk_g2p_prosody(text: str, drop_unvoiced_vowels: bool = True) :
9 | """Extract phoneme + prosoody symbol sequence from input full-context labels.
10 |
11 | The algorithm is based on `Prosodic features control by symbols as input of
12 | sequence-to-sequence acoustic modeling for neural TTS`_ with some r9y9's tweaks.
13 |
14 | Args:
15 | text (str): Input text.
16 | drop_unvoiced_vowels (bool): whether to drop unvoiced vowels.
17 |
18 | Returns:
19 | List[str]: List of phoneme + prosody symbols.
20 |
21 | Examples:
22 | >>> from espnet2.text.phoneme_tokenizer import pyopenjtalk_g2p_prosody
23 | >>> pyopenjtalk_g2p_prosody("こんにちは。")
24 | ['^', 'k', 'o', '[', 'N', 'n', 'i', 'ch', 'i', 'w', 'a', '$']
25 |
26 | .. _`Prosodic features control by symbols as input of sequence-to-sequence acoustic
27 | modeling for neural TTS`: https://doi.org/10.1587/transinf.2020EDP7104
28 |
29 | """
30 | labels = _extract_fullcontext_label(text)
31 | N = len(labels)
32 |
33 | phones = []
34 | for n in range(N):
35 | lab_curr = labels[n]
36 |
37 | # current phoneme
38 | p3 = re.search(r"\-(.*?)\+", lab_curr).group(1)
39 |
40 | # deal unvoiced vowels as normal vowels
41 | if drop_unvoiced_vowels and p3 in "AEIOU":
42 | p3 = p3.lower()
43 |
44 | # deal with sil at the beginning and the end of text
45 | if p3 == "sil":
46 | assert n == 0 or n == N - 1
47 | if n == 0:
48 | phones.append("^")
49 | elif n == N - 1:
50 | # check question form or not
51 | e3 = _numeric_feature_by_regex(r"!(\d+)_", lab_curr)
52 | if e3 == 0:
53 | phones.append("$")
54 | elif e3 == 1:
55 | phones.append("?")
56 | continue
57 | elif p3 == "pau":
58 | phones.append("_")
59 | continue
60 | else:
61 | phones.append(p3)
62 |
63 | # accent type and position info (forward or backward)
64 | a1 = _numeric_feature_by_regex(r"/A:([0-9\-]+)\+", lab_curr)
65 | a2 = _numeric_feature_by_regex(r"\+(\d+)\+", lab_curr)
66 | a3 = _numeric_feature_by_regex(r"\+(\d+)/", lab_curr)
67 |
68 | # number of mora in accent phrase
69 | f1 = _numeric_feature_by_regex(r"/F:(\d+)_", lab_curr)
70 |
71 | a2_next = _numeric_feature_by_regex(r"\+(\d+)\+", labels[n + 1])
72 | # accent phrase border
73 | if a3 == 1 and a2_next == 1 and p3 in "aeiouAEIOUNcl":
74 | phones.append("#")
75 | # pitch falling
76 | elif a1 == 0 and a2_next == a2 + 1 and a2 != f1:
77 | phones.append("]")
78 | # pitch rising
79 | elif a2 == 1 and a2_next == 2:
80 | phones.append("[")
81 |
82 | return phones
83 |
84 | from packaging.version import parse as V
85 | def _extract_fullcontext_label(text):
86 | import pyopenjtalk
87 |
88 | if V(pyopenjtalk.__version__) >= V("0.3.0"):
89 | return pyopenjtalk.make_label(pyopenjtalk.run_frontend(text))
90 | else:
91 | return pyopenjtalk.run_frontend(text)[1]
92 |
93 |
94 | def _numeric_feature_by_regex(regex, s):
95 | match = re.search(regex, s)
96 | if match is None:
97 | return -50
98 | return int(match.group(1))
99 |
100 | #######################
101 |
102 | def main():
103 | phonome = pyopenjtalk_g2p_prosody("とてもつらい。なぜつらいか?それも分からない。")
104 | print(phonome)
105 | return 0
106 |
107 |
108 |
109 | if __name__ =="__main__":
110 | main()
--------------------------------------------------------------------------------
/mel_processing.py:
--------------------------------------------------------------------------------
1 | import math
2 | import os
3 | import random
4 | import torch
5 | from torch import nn
6 | import torch.nn.functional as F
7 | import torch.utils.data
8 | import numpy as np
9 | import librosa
10 | import librosa.util as librosa_util
11 | from librosa.util import normalize, pad_center, tiny
12 | from scipy.signal import get_window
13 | from scipy.io.wavfile import read
14 | from librosa.filters import mel as librosa_mel_fn
15 |
16 | MAX_WAV_VALUE = 32768.0
17 |
18 |
19 | def dynamic_range_compression_torch(x, C=1, clip_val=1e-5):
20 | """
21 | PARAMS
22 | ------
23 | C: compression factor
24 | """
25 | return torch.log(torch.clamp(x, min=clip_val) * C)
26 |
27 |
28 | def dynamic_range_decompression_torch(x, C=1):
29 | """
30 | PARAMS
31 | ------
32 | C: compression factor used to compress
33 | """
34 | return torch.exp(x) / C
35 |
36 |
37 | def spectral_normalize_torch(magnitudes):
38 | output = dynamic_range_compression_torch(magnitudes)
39 | return output
40 |
41 |
42 | def spectral_de_normalize_torch(magnitudes):
43 | output = dynamic_range_decompression_torch(magnitudes)
44 | return output
45 |
46 |
47 | mel_basis = {}
48 | hann_window = {}
49 |
50 |
51 | def spectrogram_torch(y, n_fft, sampling_rate, hop_size, win_size, center=False):
52 | if torch.min(y) < -1.:
53 | print('min value is ', torch.min(y))
54 | if torch.max(y) > 1.:
55 | print('max value is ', torch.max(y))
56 |
57 | global hann_window
58 | dtype_device = str(y.dtype) + '_' + str(y.device)
59 | wnsize_dtype_device = str(win_size) + '_' + dtype_device
60 | if wnsize_dtype_device not in hann_window:
61 | hann_window[wnsize_dtype_device] = torch.hann_window(win_size).to(dtype=y.dtype, device=y.device)
62 |
63 | y = torch.nn.functional.pad(y.unsqueeze(1), (int((n_fft-hop_size)/2), int((n_fft-hop_size)/2)), mode='reflect')
64 | y = y.squeeze(1)
65 |
66 | spec = torch.stft(y, n_fft, hop_length=hop_size, win_length=win_size, window=hann_window[wnsize_dtype_device],
67 | center=center, pad_mode='reflect', normalized=False, onesided=True, return_complex=False)
68 |
69 | spec = torch.sqrt(spec.pow(2).sum(-1) + 1e-6)
70 | return spec
71 |
72 |
73 | def spec_to_mel_torch(spec, n_fft, num_mels, sampling_rate, fmin, fmax):
74 | global mel_basis
75 | dtype_device = str(spec.dtype) + '_' + str(spec.device)
76 | fmax_dtype_device = str(fmax) + '_' + dtype_device
77 | if fmax_dtype_device not in mel_basis:
78 | mel = librosa_mel_fn(sampling_rate, n_fft, num_mels, fmin, fmax)
79 | mel_basis[fmax_dtype_device] = torch.from_numpy(mel).to(dtype=spec.dtype, device=spec.device)
80 | spec = torch.matmul(mel_basis[fmax_dtype_device], spec)
81 | spec = spectral_normalize_torch(spec)
82 | return spec
83 |
84 |
85 | def mel_spectrogram_torch(y, n_fft, num_mels, sampling_rate, hop_size, win_size, fmin, fmax, center=False):
86 | if torch.min(y) < -1.:
87 | print('min value is ', torch.min(y))
88 | if torch.max(y) > 1.:
89 | print('max value is ', torch.max(y))
90 |
91 | global mel_basis, hann_window
92 | dtype_device = str(y.dtype) + '_' + str(y.device)
93 | fmax_dtype_device = str(fmax) + '_' + dtype_device
94 | wnsize_dtype_device = str(win_size) + '_' + dtype_device
95 | if fmax_dtype_device not in mel_basis:
96 | mel = librosa_mel_fn(sampling_rate, n_fft, num_mels, fmin, fmax)
97 | mel_basis[fmax_dtype_device] = torch.from_numpy(mel).to(dtype=y.dtype, device=y.device)
98 | if wnsize_dtype_device not in hann_window:
99 | hann_window[wnsize_dtype_device] = torch.hann_window(win_size).to(dtype=y.dtype, device=y.device)
100 |
101 | y = torch.nn.functional.pad(y.unsqueeze(1), (int((n_fft-hop_size)/2), int((n_fft-hop_size)/2)), mode='reflect')
102 | y = y.squeeze(1)
103 |
104 | spec = torch.stft(y, n_fft, hop_length=hop_size, win_length=win_size, window=hann_window[wnsize_dtype_device],
105 | center=center, pad_mode='reflect', normalized=False, onesided=True, return_complex=False)
106 |
107 | spec = torch.sqrt(spec.pow(2).sum(-1) + 1e-6)
108 |
109 | spec = torch.matmul(mel_basis[fmax_dtype_device], spec)
110 | spec = spectral_normalize_torch(spec)
111 |
112 | return spec
113 |
--------------------------------------------------------------------------------
/pqmf.py:
--------------------------------------------------------------------------------
1 | # -*- coding: utf-8 -*-
2 |
3 | # Copyright 2020 Tomoki Hayashi
4 | # MIT License (https://opensource.org/licenses/MIT)
5 |
6 | """Pseudo QMF modules."""
7 |
8 | import numpy as np
9 | import torch
10 | import torch.nn.functional as F
11 |
12 | from scipy.signal import kaiser
13 |
14 |
15 | def design_prototype_filter(taps=62, cutoff_ratio=0.15, beta=9.0):
16 | """Design prototype filter for PQMF.
17 | This method is based on `A Kaiser window approach for the design of prototype
18 | filters of cosine modulated filterbanks`_.
19 | Args:
20 | taps (int): The number of filter taps.
21 | cutoff_ratio (float): Cut-off frequency ratio.
22 | beta (float): Beta coefficient for kaiser window.
23 | Returns:
24 | ndarray: Impluse response of prototype filter (taps + 1,).
25 | .. _`A Kaiser window approach for the design of prototype filters of cosine modulated filterbanks`:
26 | https://ieeexplore.ieee.org/abstract/document/681427
27 | """
28 | # check the arguments are valid
29 | assert taps % 2 == 0, "The number of taps mush be even number."
30 | assert 0.0 < cutoff_ratio < 1.0, "Cutoff ratio must be > 0.0 and < 1.0."
31 |
32 | # make initial filter
33 | omega_c = np.pi * cutoff_ratio
34 | with np.errstate(invalid='ignore'):
35 | h_i = np.sin(omega_c * (np.arange(taps + 1) - 0.5 * taps)) \
36 | / (np.pi * (np.arange(taps + 1) - 0.5 * taps))
37 | h_i[taps // 2] = np.cos(0) * cutoff_ratio # fix nan due to indeterminate form
38 |
39 | # apply kaiser window
40 | w = kaiser(taps + 1, beta)
41 | h = h_i * w
42 |
43 | return h
44 |
45 |
46 | class PQMF(torch.nn.Module):
47 | """PQMF module.
48 | This module is based on `Near-perfect-reconstruction pseudo-QMF banks`_.
49 | .. _`Near-perfect-reconstruction pseudo-QMF banks`:
50 | https://ieeexplore.ieee.org/document/258122
51 | """
52 |
53 | def __init__(self, device, subbands=4, taps=62, cutoff_ratio=0.15, beta=9.0):
54 | """Initilize PQMF module.
55 | Args:
56 | subbands (int): The number of subbands.
57 | taps (int): The number of filter taps.
58 | cutoff_ratio (float): Cut-off frequency ratio.
59 | beta (float): Beta coefficient for kaiser window.
60 | """
61 | super(PQMF, self).__init__()
62 |
63 | # define filter coefficient
64 | h_proto = design_prototype_filter(taps, cutoff_ratio, beta)
65 | h_analysis = np.zeros((subbands, len(h_proto)))
66 | h_synthesis = np.zeros((subbands, len(h_proto)))
67 | for k in range(subbands):
68 | h_analysis[k] = 2 * h_proto * np.cos(
69 | (2 * k + 1) * (np.pi / (2 * subbands)) *
70 | (np.arange(taps + 1) - ((taps - 1) / 2)) +
71 | (-1) ** k * np.pi / 4)
72 | h_synthesis[k] = 2 * h_proto * np.cos(
73 | (2 * k + 1) * (np.pi / (2 * subbands)) *
74 | (np.arange(taps + 1) - ((taps - 1) / 2)) -
75 | (-1) ** k * np.pi / 4)
76 |
77 | # convert to tensor
78 | analysis_filter = torch.from_numpy(h_analysis).float().unsqueeze(1).cuda(device)
79 | synthesis_filter = torch.from_numpy(h_synthesis).float().unsqueeze(0).cuda(device)
80 |
81 | # register coefficients as beffer
82 | self.register_buffer("analysis_filter", analysis_filter)
83 | self.register_buffer("synthesis_filter", synthesis_filter)
84 |
85 | # filter for downsampling & upsampling
86 | updown_filter = torch.zeros((subbands, subbands, subbands)).float().cuda(device)
87 | for k in range(subbands):
88 | updown_filter[k, k, 0] = 1.0
89 | self.register_buffer("updown_filter", updown_filter)
90 | self.subbands = subbands
91 |
92 | # keep padding info
93 | self.pad_fn = torch.nn.ConstantPad1d(taps // 2, 0.0)
94 |
95 | def analysis(self, x):
96 | """Analysis with PQMF.
97 | Args:
98 | x (Tensor): Input tensor (B, 1, T).
99 | Returns:
100 | Tensor: Output tensor (B, subbands, T // subbands).
101 | """
102 | x = F.conv1d(self.pad_fn(x), self.analysis_filter)
103 | return F.conv1d(x, self.updown_filter, stride=self.subbands)
104 |
105 | def synthesis(self, x):
106 | """Synthesis with PQMF.
107 | Args:
108 | x (Tensor): Input tensor (B, subbands, T // subbands).
109 | Returns:
110 | Tensor: Output tensor (B, 1, T).
111 | """
112 | # NOTE(kan-bayashi): Power will be dreased so here multipy by # subbands.
113 | # Not sure this is the correct way, it is better to check again.
114 | # TODO(kan-bayashi): Understand the reconstruction procedure
115 | x = F.conv_transpose1d(x, self.updown_filter * self.subbands, stride=self.subbands)
116 | return F.conv1d(self.pad_fn(x), self.synthesis_filter)
--------------------------------------------------------------------------------
/stft_loss.py:
--------------------------------------------------------------------------------
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 |
8 | import torch
9 | import torch.nn.functional as F
10 |
11 |
12 | def stft(x, fft_size, hop_size, win_length, window):
13 | """Perform STFT and convert to magnitude spectrogram.
14 | Args:
15 | x (Tensor): Input signal tensor (B, T).
16 | fft_size (int): FFT size.
17 | hop_size (int): Hop size.
18 | win_length (int): Window length.
19 | window (str): Window function type.
20 | Returns:
21 | Tensor: Magnitude spectrogram (B, #frames, fft_size // 2 + 1).
22 | """
23 | x_stft = torch.stft(x, fft_size, hop_size, win_length, window.to(x.device))
24 | real = x_stft[..., 0]
25 | imag = x_stft[..., 1]
26 |
27 | # NOTE(kan-bayashi): clamp is needed to avoid nan or inf
28 | return torch.sqrt(torch.clamp(real ** 2 + imag ** 2, min=1e-7)).transpose(2, 1)
29 |
30 |
31 | class SpectralConvergengeLoss(torch.nn.Module):
32 | """Spectral convergence loss module."""
33 |
34 | def __init__(self):
35 | """Initilize spectral convergence loss module."""
36 | super(SpectralConvergengeLoss, self).__init__()
37 |
38 | def forward(self, x_mag, y_mag):
39 | """Calculate forward propagation.
40 | Args:
41 | x_mag (Tensor): Magnitude spectrogram of predicted signal (B, #frames, #freq_bins).
42 | y_mag (Tensor): Magnitude spectrogram of groundtruth signal (B, #frames, #freq_bins).
43 | Returns:
44 | Tensor: Spectral convergence loss value.
45 | """
46 | return torch.norm(y_mag - x_mag, p="fro") / torch.norm(y_mag, p="fro")
47 |
48 |
49 | class LogSTFTMagnitudeLoss(torch.nn.Module):
50 | """Log STFT magnitude loss module."""
51 |
52 | def __init__(self):
53 | """Initilize los STFT magnitude loss module."""
54 | super(LogSTFTMagnitudeLoss, self).__init__()
55 |
56 | def forward(self, x_mag, y_mag):
57 | """Calculate forward propagation.
58 | Args:
59 | x_mag (Tensor): Magnitude spectrogram of predicted signal (B, #frames, #freq_bins).
60 | y_mag (Tensor): Magnitude spectrogram of groundtruth signal (B, #frames, #freq_bins).
61 | Returns:
62 | Tensor: Log STFT magnitude loss value.
63 | """
64 | return F.l1_loss(torch.log(y_mag), torch.log(x_mag))
65 |
66 |
67 | class STFTLoss(torch.nn.Module):
68 | """STFT loss module."""
69 |
70 | def __init__(self, fft_size=1024, shift_size=120, win_length=600, window="hann_window"):
71 | """Initialize STFT loss module."""
72 | super(STFTLoss, self).__init__()
73 | self.fft_size = fft_size
74 | self.shift_size = shift_size
75 | self.win_length = win_length
76 | self.window = getattr(torch, window)(win_length)
77 | self.spectral_convergenge_loss = SpectralConvergengeLoss()
78 | self.log_stft_magnitude_loss = LogSTFTMagnitudeLoss()
79 |
80 | def forward(self, x, y):
81 | """Calculate forward propagation.
82 | Args:
83 | x (Tensor): Predicted signal (B, T).
84 | y (Tensor): Groundtruth signal (B, T).
85 | Returns:
86 | Tensor: Spectral convergence loss value.
87 | Tensor: Log STFT magnitude loss value.
88 | """
89 | x_mag = stft(x, self.fft_size, self.shift_size, self.win_length, self.window)
90 | y_mag = stft(y, self.fft_size, self.shift_size, self.win_length, self.window)
91 | sc_loss = self.spectral_convergenge_loss(x_mag, y_mag)
92 | mag_loss = self.log_stft_magnitude_loss(x_mag, y_mag)
93 |
94 | return sc_loss, mag_loss
95 |
96 |
97 | class MultiResolutionSTFTLoss(torch.nn.Module):
98 | """Multi resolution STFT loss module."""
99 |
100 | def __init__(self,
101 | fft_sizes=[1024, 2048, 512],
102 | hop_sizes=[120, 240, 50],
103 | win_lengths=[600, 1200, 240],
104 | window="hann_window"):
105 | """Initialize Multi resolution STFT loss module.
106 | Args:
107 | fft_sizes (list): List of FFT sizes.
108 | hop_sizes (list): List of hop sizes.
109 | win_lengths (list): List of window lengths.
110 | window (str): Window function type.
111 | """
112 | super(MultiResolutionSTFTLoss, self).__init__()
113 | assert len(fft_sizes) == len(hop_sizes) == len(win_lengths)
114 | self.stft_losses = torch.nn.ModuleList()
115 | for fs, ss, wl in zip(fft_sizes, hop_sizes, win_lengths):
116 | self.stft_losses += [STFTLoss(fs, ss, wl, window)]
117 |
118 | def forward(self, x, y):
119 | """Calculate forward propagation.
120 | Args:
121 | x (Tensor): Predicted signal (B, T).
122 | y (Tensor): Groundtruth signal (B, T).
123 | Returns:
124 | Tensor: Multi resolution spectral convergence loss value.
125 | Tensor: Multi resolution log STFT magnitude loss value.
126 | """
127 | sc_loss = 0.0
128 | mag_loss = 0.0
129 | for f in self.stft_losses:
130 | sc_l, mag_l = f(x, y)
131 | sc_loss += sc_l
132 | mag_loss += mag_l
133 | sc_loss /= len(self.stft_losses)
134 | mag_loss /= len(self.stft_losses)
135 |
136 | return sc_loss, mag_loss
--------------------------------------------------------------------------------
/inference.py:
--------------------------------------------------------------------------------
1 | import warnings
2 | warnings.filterwarnings(action='ignore')
3 |
4 | import os
5 | import time
6 | import torch
7 | import utils
8 | import argparse
9 | import commons
10 | import utils
11 | from models import SynthesizerTrn
12 | from text.symbols import symbols
13 | from text import cleaned_text_to_sequence
14 | from g2p import pyopenjtalk_g2p_prosody
15 | import soundcard as sc
16 | import soundfile as sf
17 |
18 |
19 | def get_text(text, hps):
20 | text_norm = cleaned_text_to_sequence(text)
21 | if hps.data.add_blank:
22 | text_norm = commons.intersperse(text_norm, 0)
23 | text_norm = torch.LongTensor(text_norm)
24 | return text_norm
25 |
26 | def inference(args):
27 |
28 | config_path = args.config
29 | G_model_path = args.model_path
30 |
31 | # check device
32 | if torch.cuda.is_available() is True:
33 | print("Enter the device number to use.")
34 | key = input("GPU:0, CPU:1 ===> ")
35 | if key == "0":
36 | device="cuda:0"
37 | elif key=="1":
38 | device="cpu"
39 | print(f"Device : {device}")
40 | else:
41 | print(f"CUDA is not available. Device : cpu")
42 | device = "cpu"
43 |
44 | # load config.json
45 | hps = utils.get_hparams_from_file(config_path)
46 |
47 | # load checkpoint
48 | net_g = SynthesizerTrn(
49 | len(symbols),
50 | hps.data.filter_length // 2 + 1,
51 | hps.train.segment_size // hps.data.hop_length,
52 | **hps.model).cuda()
53 | _ = net_g.eval()
54 | _ = utils.load_checkpoint(G_model_path, net_g, None)
55 |
56 | # play audio by system default
57 | speaker = sc.get_speaker(sc.default_speaker().name)
58 |
59 | # parameter settings
60 | noise_scale = torch.tensor(0.66) # adjust z_p noise
61 | noise_scale_w = torch.tensor(0.8) # adjust SDP noise
62 | length_scale = torch.tensor(1.0) # adjust sound length scale (talk speed)
63 |
64 | if args.is_save is True:
65 | n_save = 0
66 | save_dir = os.path.join("./infer_logs/")
67 | os.makedirs(save_dir, exist_ok=True)
68 |
69 | ### Dummy Input ###
70 | with torch.inference_mode():
71 | stn_phn = pyopenjtalk_g2p_prosody("速度計測のためのダミーインプットです。")
72 | stn_tst = get_text(stn_phn, hps)
73 | # generate audio
74 | x_tst = stn_tst.cuda().unsqueeze(0)
75 | x_tst_lengths = torch.LongTensor([stn_tst.size(0)]).cuda()
76 | audio = net_g.infer(x_tst,
77 | x_tst_lengths,
78 | noise_scale=noise_scale,
79 | noise_scale_w=noise_scale_w,
80 | length_scale=length_scale)[0][0,0].data.cpu().float().numpy()
81 |
82 | while True:
83 |
84 | # get text
85 | text = input("Enter text. ==> ")
86 | if text=="":
87 | print("Empty input is detected... Exit...")
88 | break
89 |
90 | # measure the execution time
91 | torch.cuda.synchronize()
92 | start = time.time()
93 |
94 | # required_grad is False
95 | with torch.inference_mode():
96 | stn_phn = pyopenjtalk_g2p_prosody(text)
97 | stn_tst = get_text(stn_phn, hps)
98 |
99 | # generate audio
100 | x_tst = stn_tst.cuda().unsqueeze(0)
101 | x_tst_lengths = torch.LongTensor([stn_tst.size(0)]).cuda()
102 | audio = net_g.infer(x_tst,
103 | x_tst_lengths,
104 | noise_scale=noise_scale,
105 | noise_scale_w=noise_scale_w,
106 | length_scale=length_scale)[0][0,0].data.cpu().float().numpy()
107 |
108 | # measure the execution time
109 | torch.cuda.synchronize()
110 | elapsed_time = time.time() - start
111 | print(f"Gen Time : {elapsed_time}")
112 |
113 | # play audio
114 | speaker.play(audio, hps.data.sampling_rate)
115 |
116 | # save audio
117 | if args.is_save is True:
118 | n_save += 1
119 | data = audio
120 | try:
121 | save_path = os.path.join(save_dir, str(n_save).zfill(3)+f"_{text}.wav")
122 | sf.write(
123 | file=save_path,
124 | data=data,
125 | samplerate=hps.data.sampling_rate,
126 | format="WAV")
127 | except:
128 | save_path = os.path.join(save_dir, str(n_save).zfill(3)+f"_{text[:10]}〜.wav")
129 | sf.write(
130 | file=save_path,
131 | data=data,
132 | samplerate=hps.data.sampling_rate,
133 | format="WAV")
134 |
135 | print(f"Audio is saved at : {save_path}")
136 |
137 |
138 | return 0
139 |
140 | if __name__ == "__main__":
141 |
142 | parser = argparse.ArgumentParser()
143 | parser.add_argument('--config',
144 | type=str,
145 | required=True,
146 | #default="./logs/ITA_CORPUS/config.json" ,
147 | help='Path to configuration file')
148 | parser.add_argument('--model_path',
149 | type=str,
150 | required=True,
151 | #default="./logs/ITA_CORPUS/G_1200.pth",
152 | help='Path to checkpoint')
153 | parser.add_argument('--is_save',
154 | type=str,
155 | default=True,
156 | help='Whether to save output or not')
157 | args = parser.parse_args()
158 |
159 | inference(args)
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # MB-iSTFT-VITS(44100Hz 日本語対応版)
2 | **MB-iSTFT-VITS: Lightweight and High-Fidelity End-to-End Text-to-Speech with Multi-Band Generation and Inverse Short-Time Fourier Transform**
3 |
4 | このリポジトリは、 44100Hzの日本語音声を学習および出力できるように編集した[MB-iSTFT-VITS](https://github.com/MasayaKawamura/MB-iSTFT-VITS)です。44100Hzに対応させた際、pseudo-QMFを用いた合成では定周波ノイズが発生したため、合成フィルタを学習パラメータにすることで柔軟に対応できるようにしたMS-iSTFT-VITS実装のみを対象にしています。
5 |
6 |
7 |
8 | ## サンプル視聴 : [JSUT 2000 Epoch sample](https://drive.google.com/file/d/1YQaMxSSrdqpcg2_l_I-Ejtg2kMbeYP1Y/view?usp=share_link) / **生成時間 : 約0.04[秒]**(A6000) ##
9 |
10 |
11 |
12 |
13 | ## 1. 環境構築
14 |
15 | Anacondaによる実行環境構築を想定する。
16 |
17 | 0. Anacondaで"MB-iSTFT-VITS"という名前の仮想環境を作成する。[y]or nを聞かれたら[y]を入力する。
18 | ```sh
19 | conda create -n MB-iSTFT-VITS python=3.8
20 | ```
21 | 0. 仮想環境を有効化する。
22 | ```sh
23 | conda activate MB-iSTFT-VITS
24 | ```
25 | 0. このレポジトリをクローンする(もしくはDownload Zipでダウンロードする)
26 |
27 | ```sh
28 | git clone https://github.com/tonnetonne814/MB-iSTFT-VITS-44100-Ja.git
29 | cd MB-iSTFT-VITS-44100-Ja # フォルダへ移動
30 | ```
31 |
32 | 0. [https://pytorch.org/](https://pytorch.org/)のURLよりPyTorch1.13.1をインストールする(_VF.stftの部分でエラーで止まったら違うバージョンに変える)
33 |
34 | ```sh
35 | # OS=Linux, CUDA=11.7 の例
36 | pip install torch==1.13.1+cu117 torchvision==0.14.1+cu117 torchaudio==0.13.1 --extra-index-url https://download.pytorch.org/whl/cu117
37 | ```
38 |
39 | 0. その他、必要なパッケージをインストールする。
40 | ```sh
41 | pip install -r requirements.txt
42 | ```
43 | 0. Monotonoic Alignment Searchをビルドする。
44 | ```sh
45 | cd monotonic_align
46 | mkdir monotonic_align
47 | python setup.py build_ext --inplace
48 | cd ..
49 | ```
50 |
51 | ## 2. データセットの準備
52 |
53 | [JSUT Speech dataset](https://sites.google.com/site/shinnosuketakamichi/publication/jsut)によるBasic5000音源、[ITAコーパス](https://github.com/mmorise/ita-corpus)によるEmotion音源とRecitation音源、及び自作データセット音源による、44100Hzでの学習を想定する。
54 |
55 | - JSUT Basic5000
56 | 1. [JSUT Speech dataset](https://sites.google.com/site/shinnosuketakamichi/publication/jsut)をダウンロード及び展開する。
57 | 1. 展開したフォルダの中にあるbasic5000フォルダを指定して、以下を実行する。
58 | ```sh
59 | python3 ./dataset/preprocess.py --dataset_name jsut --folder_path ./path/to/jsut_ver1.1/basic5000/ --sampling_rate 44100
60 | ```
61 | - [ITAコーパス](https://github.com/mmorise/ita-corpus) (例:[あみたろの声素材工房](https://amitaro.net/) 様)
62 | 1. [ITAコーパス読み上げ音声](https://amitaro.net/voice/corpus-list/ita/)をダウンロードし、展開する。
63 | 1. RECITATION音源が格納されているrecitationフォルダと、EMOTION音源が格納されているemotionフォルダを準備し、2つのフォルダが格納されているフォルダを指定して、以下を実行する。
64 | ```sh
65 | python3 ./dataset/preprocess.py --dataset_name ita --folder_path ./path/to/ita_corpus/ --sampling_rate 44100
66 | ```
67 | > ⚠音源は、ファイル名の001や002等の3桁の数字で区別するので、3桁の数字を含むこと。
68 |
69 | > ⚠音源を格納している2つのフォルダ名は、それぞれ”recitation”と"emotion"にすること。
70 |
71 | - 自作データセット(単一話者)
72 | 1. 以下の要素に注意して、読み上げ音声を準備する。([What makes a good TTS dataset](https://github.com/coqui-ai/TTS/wiki/What-makes-a-good-TTS-dataset)より)
73 | - テキストや発話の長さが正規分布感になってること。
74 | - テキストデータと発話音声に間違いがないこと。
75 | - 背景ノイズが無いこと。
76 | - 発話音声データ間で、話し方が似通っていること。
77 | - 使用する言語の音素を網羅していること。
78 | - 声色や音程の違い等をできるだけ自然に録音していること。
79 | 1. `./dataset/homebrew/transcript_utf8.txt`に、以下の形式で音源と発話テキストを記述してください。
80 | ```sh
81 | wavファイル名(拡張子無):発話テキスト
82 | ```
83 | 1. 用意した音源が格納されているフォルダを指定して、以下を実行する。
84 | ```sh
85 | python3 dataset/preprocess.py --dataset_name homebrew --folder_path ./path/to/wav_folder/ --sampling_rate 44100
86 | ```
87 |
88 | ## 3. [configs](configs)フォルダ内のjsonを編集
89 | 主要なパラメータを説明します。必要であれば編集する。
90 | | 分類 | パラメータ名 | 説明 |
91 | |:-----:|:-----------------:|:---------------------------------------------------------:|
92 | | train | log_interval | 指定ステップ毎にロスを算出し記録する |
93 | | train | eval_interval | 指定ステップ毎にモデル評価を行う |
94 | | train | epochs | 学習データ全体を学習する回数 |
95 | | train | batch_size | 一度のパラメータ更新に使用する学習データ数 |
96 | | train | finetune_model_dir| ファインチューニング用のcheckpointsが入っているフォルダ |
97 | | data | training_files | 学習用filelistのテキストパス |
98 | | data | validation_files | 検証用filelistのテキストパス |
99 |
100 |
101 | ## 4. 学習
102 | 次のコマンドを入力することで、学習を開始する。
103 | > ⚠CUDA Out of Memoryのエラーが出た場合には、config.jsonにてbatch_sizeを小さくする。
104 |
105 | - JSUT Basic5000
106 | ```sh
107 | python train_latest.py -c configs/jsut_44100.json -m JSUT_BASIC5000
108 | ```
109 |
110 | - ITAコーパス
111 | ```sh
112 | python train_latest.py -c configs/ita_44100.json -m ITA_CORPUS
113 | ```
114 |
115 | - 自作データセット
116 | ```sh
117 | python train_latest.py -c configs/homebrew_44100.json -m homebrew_dataset
118 | ```
119 |
120 | 学習経過はターミナルにも表示されるが、tensorboardを用いて確認することで、生成音声の視聴や、スペクトログラム、各ロス遷移を目視で確認することができます。
121 | ```sh
122 | tensorboard --logdir logs
123 | ```
124 |
125 | ## 5. 推論
126 | 次のコマンドを入力することで、推論を開始する。config.jsonへのパスと、生成器モデルパスを指定する。
127 | ```sh
128 | python3 inference.py --config ./path/to/config.json --model_path ./path/to/G_xxx.pth
129 | ```
130 | Terminal上にて使用するデバイスを選択後、テキストを入力することで、音声が生成さされます。音声は自動的に再生され、infer_logsフォルダ(存在しない場合は自動作成)に保存されます。
131 |
132 | ## 6.ファインチューニング
133 | ファインチューニングを行う場合は、生成器モデルのcheckpointをG_finetune.pth、識別器モデルのcheckpointsをD_finetune.pthに名前を変更し、config.jsonで記述しているfinetune_model_dirフォルダ内へと配置する。その後、「4. 学習」のコマンドで学習を開始することで、ファインチューニングを行うことが出来ます。ファインチューニングの際には**事前学習モデルを使用する**のがオススメです。
134 |
135 | ## 事前学習モデル
136 | **ダウンロード:**
137 | - [JSUT_2000Epoch_64Batch](https://drive.google.com/file/d/15PK5k9IcwDjUJpf1ERjPLC8db9cf1XPy/view?usp=share_link)
138 | - [JSUT_240ksteps_+2_uprate](https://drive.google.com/file/d/1ZXC8mc_obWXKeQ7Vn5RrYdyjINbAWyEN/view?usp=share_link)
139 |
140 | ## 付録
141 | - FullBand化におけるMB-iSTFT-VITSの定周波ノイズについて。
142 |
143 | MB-iSTFT-VITSでは、ピー(ファの音あたり)という定周波ノイズが発生し、スペクトログラムに横線が入ってしまったが、MS-iSTFT-VITSの方では発生しませんでした。モデル設定は共通にしてあるので、学習可能なフィルタが貢献しているかもしれません。
144 |
145 |
146 |
147 | ## 参考文献
148 | - https://github.com/jaywalnut310/vits.git
149 | - https://github.com/rishikksh20/iSTFTNet-pytorch.git
150 | - https://github.com/rishikksh20/melgan.git
151 |
--------------------------------------------------------------------------------
/commons.py:
--------------------------------------------------------------------------------
1 | import math
2 | import numpy as np
3 | import torch
4 | from torch import nn
5 | from torch.nn import functional as F
6 |
7 |
8 | def init_weights(m, mean=0.0, std=0.01):
9 | classname = m.__class__.__name__
10 | if classname.find("Conv") != -1:
11 | m.weight.data.normal_(mean, std)
12 |
13 |
14 | def get_padding(kernel_size, dilation=1):
15 | return int((kernel_size*dilation - dilation)/2)
16 |
17 |
18 | def convert_pad_shape(pad_shape):
19 | l = pad_shape[::-1]
20 | pad_shape = [item for sublist in l for item in sublist]
21 | return pad_shape
22 |
23 |
24 | def intersperse(lst, item):
25 | result = [item] * (len(lst) * 2 + 1)
26 | result[1::2] = lst
27 | return result
28 |
29 |
30 | def kl_divergence(m_p, logs_p, m_q, logs_q):
31 | """KL(P||Q)"""
32 | kl = (logs_q - logs_p) - 0.5
33 | kl += 0.5 * (torch.exp(2. * logs_p) + ((m_p - m_q)**2)) * torch.exp(-2. * logs_q)
34 | return kl
35 |
36 |
37 | def rand_gumbel(shape):
38 | """Sample from the Gumbel distribution, protect from overflows."""
39 | uniform_samples = torch.rand(shape) * 0.99998 + 0.00001
40 | return -torch.log(-torch.log(uniform_samples))
41 |
42 |
43 | def rand_gumbel_like(x):
44 | g = rand_gumbel(x.size()).to(dtype=x.dtype, device=x.device)
45 | return g
46 | """
47 |
48 | def slice_segments(x, ids_str, segment_size=4):
49 | ret = torch.zeros_like(x[:, :, :segment_size])
50 | for i in range(x.size(0)):
51 | try:
52 | idx_str = ids_str[i]
53 | idx_end = idx_str + segment_size
54 | ret[i] = x[i, :, idx_str:idx_end]
55 | except:
56 | idx_str = ids_str[i]
57 | idx_end = idx_str + segment_size
58 | ret[i] = torch.cat((x[i, :, idx_str:] , torch.zeros), dim=1)
59 |
60 | return ret
61 |
62 | """
63 | def slice_segments(x, ids_str, segment_size=4):
64 | ret = torch.zeros_like(x[:, :, :segment_size])
65 | for i in range(x.size(0)):
66 | idx_str = ids_str[i]
67 | idx_end = idx_str + segment_size
68 | ret[i] = x[i, :, idx_str:idx_end]
69 | return ret
70 |
71 |
72 | def rand_slice_segments(x, x_lengths=None, segment_size=4):
73 | b, d, t = x.size()
74 | if x_lengths is None:
75 | x_lengths = t
76 | ids_str_max = torch.floor((x_lengths - segment_size + 1))
77 | #ids_str_max = torch.floor((x_lengths - segment_size + 1) * 0.7)
78 | ids_str = (torch.rand([b]).to(device=x.device) * ids_str_max).to(dtype=torch.long)
79 | ret = slice_segments(x, ids_str, segment_size)
80 | return ret, ids_str
81 |
82 |
83 | def last_slice_segments(x, x_lengths=None, segment_size=4):
84 | b, d, t = x.size()
85 | if x_lengths is None:
86 | x_lengths = t
87 | ids_str_max = torch.floor((x_lengths - segment_size + 1))
88 | #ids_str_max = torch.floor((x_lengths - segment_size + 1) * 0.7)
89 | ids_str = ids_str_max - 1
90 | ret = slice_segments(x, ids_str, segment_size)
91 | return ret, ids_str
92 |
93 |
94 |
95 | def get_timing_signal_1d(
96 | length, channels, min_timescale=1.0, max_timescale=1.0e4):
97 | position = torch.arange(length, dtype=torch.float)
98 | num_timescales = channels // 2
99 | log_timescale_increment = (
100 | math.log(float(max_timescale) / float(min_timescale)) /
101 | (num_timescales - 1))
102 | inv_timescales = min_timescale * torch.exp(
103 | torch.arange(num_timescales, dtype=torch.float) * -log_timescale_increment)
104 | scaled_time = position.unsqueeze(0) * inv_timescales.unsqueeze(1)
105 | signal = torch.cat([torch.sin(scaled_time), torch.cos(scaled_time)], 0)
106 | signal = F.pad(signal, [0, 0, 0, channels % 2])
107 | signal = signal.view(1, channels, length)
108 | return signal
109 |
110 |
111 | def add_timing_signal_1d(x, min_timescale=1.0, max_timescale=1.0e4):
112 | b, channels, length = x.size()
113 | signal = get_timing_signal_1d(length, channels, min_timescale, max_timescale)
114 | return x + signal.to(dtype=x.dtype, device=x.device)
115 |
116 |
117 | def cat_timing_signal_1d(x, min_timescale=1.0, max_timescale=1.0e4, axis=1):
118 | b, channels, length = x.size()
119 | signal = get_timing_signal_1d(length, channels, min_timescale, max_timescale)
120 | return torch.cat([x, signal.to(dtype=x.dtype, device=x.device)], axis)
121 |
122 |
123 | def subsequent_mask(length):
124 | mask = torch.tril(torch.ones(length, length)).unsqueeze(0).unsqueeze(0)
125 | return mask
126 |
127 |
128 | @torch.jit.script
129 | def fused_add_tanh_sigmoid_multiply(input_a, input_b, n_channels):
130 | n_channels_int = n_channels[0]
131 | in_act = input_a + input_b
132 | t_act = torch.tanh(in_act[:, :n_channels_int, :])
133 | s_act = torch.sigmoid(in_act[:, n_channels_int:, :])
134 | acts = t_act * s_act
135 | return acts
136 |
137 |
138 | def convert_pad_shape(pad_shape):
139 | l = pad_shape[::-1]
140 | pad_shape = [item for sublist in l for item in sublist]
141 | return pad_shape
142 |
143 |
144 | def shift_1d(x):
145 | x = F.pad(x, convert_pad_shape([[0, 0], [0, 0], [1, 0]]))[:, :, :-1]
146 | return x
147 |
148 |
149 | def sequence_mask(length, max_length=None):
150 | if max_length is None:
151 | max_length = length.max()
152 | x = torch.arange(max_length, dtype=length.dtype, device=length.device)
153 | return x.unsqueeze(0) < length.unsqueeze(1)
154 |
155 |
156 | def generate_path(duration, mask):
157 | """
158 | duration: [b, 1, t_x]
159 | mask: [b, 1, t_y, t_x]
160 | """
161 | device = duration.device
162 |
163 | b, _, t_y, t_x = mask.shape
164 | cum_duration = torch.cumsum(duration, -1)
165 |
166 | cum_duration_flat = cum_duration.view(b * t_x)
167 | path = sequence_mask(cum_duration_flat, t_y).to(mask.dtype)
168 | path = path.view(b, t_x, t_y)
169 | path = path - F.pad(path, convert_pad_shape([[0, 0], [1, 0], [0, 0]]))[:, :-1]
170 | path = path.unsqueeze(1).transpose(2,3) * mask
171 | return path
172 |
173 |
174 | def clip_grad_value_(parameters, clip_value, norm_type=2):
175 | if isinstance(parameters, torch.Tensor):
176 | parameters = [parameters]
177 | parameters = list(filter(lambda p: p.grad is not None, parameters))
178 | norm_type = float(norm_type)
179 | if clip_value is not None:
180 | clip_value = float(clip_value)
181 |
182 | total_norm = 0
183 | for p in parameters:
184 | param_norm = p.grad.data.norm(norm_type)
185 | total_norm += param_norm.item() ** norm_type
186 | if clip_value is not None:
187 | p.grad.data.clamp_(min=-clip_value, max=clip_value)
188 | total_norm = total_norm ** (1. / norm_type)
189 | return total_norm
190 |
--------------------------------------------------------------------------------
/dataset/preprocess.py:
--------------------------------------------------------------------------------
1 | import librosa
2 | import os
3 | import soundfile
4 | from tqdm import tqdm
5 | import random
6 | import argparse
7 | import numpy as np
8 |
9 |
10 | os.makedirs("./filelists/",exist_ok=True)
11 | os.makedirs("./checkpoints/",exist_ok=True)
12 |
13 |
14 | def jsut_preprocess(dataset_dir:str = "./jsut_ver1.1/basic5000/", results_folder="./dataset/jsut/", target_sr:int = 44100):
15 | os.makedirs(results_folder, exist_ok=True)
16 |
17 | wav_dir = os.path.join(dataset_dir, "wav")
18 | #"""
19 | for filename in tqdm(os.listdir(wav_dir)):
20 | wav_path = os.path.join(wav_dir, filename)
21 | y, sr = librosa.load(wav_path)
22 | y_converted = librosa.resample(y, orig_sr=sr, target_sr=target_sr)
23 | save_path = os.path.join(results_folder, filename)
24 | soundfile.write(save_path, y_converted, target_sr)
25 | #"""
26 | txt_path = os.path.join(dataset_dir, "transcript_utf8.txt")
27 | text_list = list()
28 | for txt in read_txt(txt_path):
29 | if txt == "\n":
30 | continue
31 | name, sentence = txt.split(":")
32 | sentence = sentence.replace("\n", "")
33 | wav_filepath = os.path.join(results_folder, name +".wav")
34 | out_txt = wav_filepath + "|" + sentence + "\n"
35 | text_list.append(out_txt)
36 |
37 | max_n = len(text_list)
38 | test_list = list()
39 | for _ in range(int(max_n * 0.005)):
40 | n = len(text_list)
41 | idx = random.randint(9, int(n-1))
42 | txt = text_list.pop(idx)
43 | test_list.append(txt)
44 |
45 | max_n = len(text_list)
46 | val_list = list()
47 | for _ in range(int(max_n * 0.005)):
48 | n = len(text_list)
49 | idx = random.randint(9, int(n-1))
50 | txt = text_list.pop(idx)
51 | val_list.append(txt)
52 |
53 | write_txt(f"./filelists/jsut_train_{target_sr}.txt", text_list)
54 | write_txt(f"./filelists/jsut_val_{target_sr}.txt", val_list)
55 | write_txt(f"./filelists/jsut_test_{target_sr}.txt", test_list)
56 |
57 | return 0
58 |
59 | def ita_preprocess(dataset_dir:str = "./path/to/ita_corpus", results_folder="./dataset/ita/", target_sr:int = 44100):
60 |
61 | os.makedirs(results_folder, exist_ok=True)
62 | folder_list = ["recitation", "emotion"]
63 | #"""
64 | for folder in folder_list:
65 | wav_dir = os.path.join(dataset_dir, folder)
66 | filelist = os.listdir(wav_dir)
67 | results_folder_dir = os.path.join(results_folder,folder)
68 | os.makedirs(results_folder_dir, exist_ok=True)
69 |
70 | for filename in tqdm(filelist):
71 | wav_path = os.path.join(wav_dir, filename)
72 | y, sr = librosa.load(wav_path)
73 | y_converted = librosa.resample(y, orig_sr=sr, target_sr=target_sr)
74 | for idx in range(999):
75 | if str(idx).zfill(3) in filename:
76 | break
77 |
78 | if folder == "recitation":
79 | filename_out = "RECITATION324_" + str(idx).zfill(3) + ".wav"
80 | elif folder == "emotion":
81 | filename_out = "EMOTION100_"+ str(idx).zfill(3) + ".wav"
82 | else:
83 | print("ERROR. Check ITA corpus.")
84 | continue
85 |
86 | save_path = os.path.join(results_folder_dir, filename_out)
87 | soundfile.write(save_path, y_converted, target_sr)
88 | #"""
89 | txt_path = os.path.join(results_folder, "transcript_utf8.txt")
90 | text_list = list()
91 | for txt in read_txt(txt_path):
92 | if txt == "\n":
93 | continue
94 | name, sentence = txt.split(":")
95 | sentence, kana = sentence.split(",")
96 | sentence = sentence.replace("\n", "")
97 | if "RECITATION" in name:
98 | wav_filepath = os.path.join(results_folder,"recitation", name +".wav")
99 | elif "EMOTION" in name:
100 | wav_filepath = os.path.join(results_folder,"emotion", name +".wav")
101 |
102 | out_txt = wav_filepath + "|" + sentence + "\n"
103 | text_list.append(out_txt)
104 |
105 | max_n = len(text_list)
106 | test_list = list()
107 | for _ in range(int(max_n * 0.005)):
108 | n = len(text_list)
109 | idx = random.randint(9, int(n-1))
110 | txt = text_list.pop(idx)
111 | test_list.append(txt)
112 |
113 | max_n = len(text_list)
114 | val_list = list()
115 | for _ in range(int(max_n * 0.005)):
116 | n = len(text_list)
117 | idx = random.randint(9, int(n-1))
118 | txt = text_list.pop(idx)
119 | val_list.append(txt)
120 |
121 | write_txt(f"./filelists/ita_train_{target_sr}.txt", text_list)
122 | write_txt(f"./filelists/ita_val_{target_sr}.txt", val_list)
123 | write_txt(f"./filelists/ita_test_{target_sr}.txt", test_list)
124 |
125 | return 0
126 |
127 |
128 | def homebrew_preprocess(dataset_dir:str = "./homebrew/", results_folder="./dataset/homebrew/", target_sr:int = 44100):
129 |
130 | os.makedirs(results_folder, exist_ok=True)
131 |
132 | wav_dir = dataset_dir
133 | for filename in tqdm(os.listdir(wav_dir)):
134 | wav_path = os.path.join(wav_dir, filename)
135 | y, sr = librosa.load(wav_path)
136 | y_converted = librosa.resample(y, orig_sr=sr, target_sr=target_sr)
137 | save_path = os.path.join(results_folder, filename)
138 | soundfile.write(save_path, y_converted, target_sr)
139 |
140 | txt_path = os.path.join(results_folder, "transcript_utf8.txt")
141 | text_list = list()
142 | for txt in read_txt(txt_path):
143 | if txt == "\n":
144 | continue
145 | name, sentence = txt.split(":")
146 | sentence = sentence.replace("\n", "")
147 | wav_filepath = os.path.join(results_folder, name +".wav")
148 | out_txt = wav_filepath + "|" + sentence + "\n"
149 | text_list.append(out_txt)
150 |
151 | max_n = len(text_list)
152 | test_list = list()
153 | for _ in range(int(max_n * 0.005)):
154 | n = len(text_list)
155 | idx = random.randint(9, int(n-1))
156 | txt = text_list.pop(idx)
157 | test_list.append(txt)
158 |
159 | max_n = len(text_list)
160 | val_list = list()
161 | for _ in range(int(max_n * 0.005)):
162 | n = len(text_list)
163 | idx = random.randint(9, int(n-1))
164 | txt = text_list.pop(idx)
165 | val_list.append(txt)
166 |
167 | write_txt(f"./filelists/homebrew_train_{target_sr}.txt", text_list)
168 | write_txt(f"./filelists/homebrew_val_{target_sr}.txt", val_list)
169 | write_txt(f"./filelists/homebrew_test_{target_sr}.txt", test_list)
170 |
171 | return 0
172 |
173 | def read_txt(path):
174 | with open(path, mode="r", encoding="utf-8")as f:
175 | lines = f.readlines()
176 | return lines
177 |
178 | def write_txt(path, lines):
179 | with open(path, mode="w", encoding="utf-8")as f:
180 | f.writelines(lines)
181 |
182 |
183 | if __name__ == "__main__":
184 |
185 | parser = argparse.ArgumentParser()
186 |
187 | parser.add_argument('--dataset_name',
188 | type=str,
189 | #required=True,
190 | default="jsut",
191 | help='jsut or ita or homebrew')
192 | parser.add_argument('--folder_path',
193 | type=str,
194 | #required=True,
195 | default="./basic5000/",
196 | help='Path to jvs corpus folder')
197 | parser.add_argument('--sampling_rate',
198 | type=str,
199 | #required=True,
200 | default=44100,
201 | help='Target sampling rate')
202 |
203 | args = parser.parse_args()
204 |
205 | if args.dataset_name == "jsut":
206 | jsut_preprocess(dataset_dir=args.folder_path, target_sr=int(args.sampling_rate))
207 | elif args.dataset_name == "ita":
208 | ita_preprocess(dataset_dir=args.folder_path, target_sr=int(args.sampling_rate))
209 | elif args.dataset_name == "homebrew":
210 | homebrew_preprocess(dataset_dir=args.folder_path, target_sr=int(args.sampling_rate))
211 | else:
212 | print("ERROR. Check dataset_name.")
--------------------------------------------------------------------------------
/transforms.py:
--------------------------------------------------------------------------------
1 | import torch
2 | from torch.nn import functional as F
3 |
4 | import numpy as np
5 |
6 |
7 | DEFAULT_MIN_BIN_WIDTH = 1e-3
8 | DEFAULT_MIN_BIN_HEIGHT = 1e-3
9 | DEFAULT_MIN_DERIVATIVE = 1e-3
10 |
11 |
12 | def piecewise_rational_quadratic_transform(inputs,
13 | unnormalized_widths,
14 | unnormalized_heights,
15 | unnormalized_derivatives,
16 | inverse=False,
17 | tails=None,
18 | tail_bound=1.,
19 | min_bin_width=DEFAULT_MIN_BIN_WIDTH,
20 | min_bin_height=DEFAULT_MIN_BIN_HEIGHT,
21 | min_derivative=DEFAULT_MIN_DERIVATIVE):
22 |
23 | if tails is None:
24 | spline_fn = rational_quadratic_spline
25 | spline_kwargs = {}
26 | else:
27 | spline_fn = unconstrained_rational_quadratic_spline
28 | spline_kwargs = {
29 | 'tails': tails,
30 | 'tail_bound': tail_bound
31 | }
32 |
33 | outputs, logabsdet = spline_fn(
34 | inputs=inputs,
35 | unnormalized_widths=unnormalized_widths,
36 | unnormalized_heights=unnormalized_heights,
37 | unnormalized_derivatives=unnormalized_derivatives,
38 | inverse=inverse,
39 | min_bin_width=min_bin_width,
40 | min_bin_height=min_bin_height,
41 | min_derivative=min_derivative,
42 | **spline_kwargs
43 | )
44 | return outputs, logabsdet
45 |
46 |
47 | def searchsorted(bin_locations, inputs, eps=1e-6):
48 | bin_locations[..., -1] += eps
49 | return torch.sum(
50 | inputs[..., None] >= bin_locations,
51 | dim=-1
52 | ) - 1
53 |
54 |
55 | def unconstrained_rational_quadratic_spline(inputs,
56 | unnormalized_widths,
57 | unnormalized_heights,
58 | unnormalized_derivatives,
59 | inverse=False,
60 | tails='linear',
61 | tail_bound=1.,
62 | min_bin_width=DEFAULT_MIN_BIN_WIDTH,
63 | min_bin_height=DEFAULT_MIN_BIN_HEIGHT,
64 | min_derivative=DEFAULT_MIN_DERIVATIVE):
65 | inside_interval_mask = (inputs >= -tail_bound) & (inputs <= tail_bound)
66 | outside_interval_mask = ~inside_interval_mask
67 |
68 | outputs = torch.zeros_like(inputs)
69 | logabsdet = torch.zeros_like(inputs)
70 |
71 | if tails == 'linear':
72 | unnormalized_derivatives = F.pad(unnormalized_derivatives, pad=(1, 1))
73 | constant = np.log(np.exp(1 - min_derivative) - 1)
74 | unnormalized_derivatives[..., 0] = constant
75 | unnormalized_derivatives[..., -1] = constant
76 |
77 | outputs[outside_interval_mask] = inputs[outside_interval_mask]
78 | logabsdet[outside_interval_mask] = 0
79 | else:
80 | raise RuntimeError('{} tails are not implemented.'.format(tails))
81 |
82 | outputs[inside_interval_mask], logabsdet[inside_interval_mask] = rational_quadratic_spline(
83 | inputs=inputs[inside_interval_mask],
84 | unnormalized_widths=unnormalized_widths[inside_interval_mask, :],
85 | unnormalized_heights=unnormalized_heights[inside_interval_mask, :],
86 | unnormalized_derivatives=unnormalized_derivatives[inside_interval_mask, :],
87 | inverse=inverse,
88 | left=-tail_bound, right=tail_bound, bottom=-tail_bound, top=tail_bound,
89 | min_bin_width=min_bin_width,
90 | min_bin_height=min_bin_height,
91 | min_derivative=min_derivative
92 | )
93 |
94 | return outputs, logabsdet
95 |
96 | def rational_quadratic_spline(inputs,
97 | unnormalized_widths,
98 | unnormalized_heights,
99 | unnormalized_derivatives,
100 | inverse=False,
101 | left=0., right=1., bottom=0., top=1.,
102 | min_bin_width=DEFAULT_MIN_BIN_WIDTH,
103 | min_bin_height=DEFAULT_MIN_BIN_HEIGHT,
104 | min_derivative=DEFAULT_MIN_DERIVATIVE):
105 | if torch.min(inputs) < left or torch.max(inputs) > right:
106 | raise ValueError('Input to a transform is not within its domain')
107 |
108 | num_bins = unnormalized_widths.shape[-1]
109 |
110 | if min_bin_width * num_bins > 1.0:
111 | raise ValueError('Minimal bin width too large for the number of bins')
112 | if min_bin_height * num_bins > 1.0:
113 | raise ValueError('Minimal bin height too large for the number of bins')
114 |
115 | widths = F.softmax(unnormalized_widths, dim=-1)
116 | widths = min_bin_width + (1 - min_bin_width * num_bins) * widths
117 | cumwidths = torch.cumsum(widths, dim=-1)
118 | cumwidths = F.pad(cumwidths, pad=(1, 0), mode='constant', value=0.0)
119 | cumwidths = (right - left) * cumwidths + left
120 | cumwidths[..., 0] = left
121 | cumwidths[..., -1] = right
122 | widths = cumwidths[..., 1:] - cumwidths[..., :-1]
123 |
124 | derivatives = min_derivative + F.softplus(unnormalized_derivatives)
125 |
126 | heights = F.softmax(unnormalized_heights, dim=-1)
127 | heights = min_bin_height + (1 - min_bin_height * num_bins) * heights
128 | cumheights = torch.cumsum(heights, dim=-1)
129 | cumheights = F.pad(cumheights, pad=(1, 0), mode='constant', value=0.0)
130 | cumheights = (top - bottom) * cumheights + bottom
131 | cumheights[..., 0] = bottom
132 | cumheights[..., -1] = top
133 | heights = cumheights[..., 1:] - cumheights[..., :-1]
134 |
135 | if inverse:
136 | bin_idx = searchsorted(cumheights, inputs)[..., None]
137 | else:
138 | bin_idx = searchsorted(cumwidths, inputs)[..., None]
139 |
140 | input_cumwidths = cumwidths.gather(-1, bin_idx)[..., 0]
141 | input_bin_widths = widths.gather(-1, bin_idx)[..., 0]
142 |
143 | input_cumheights = cumheights.gather(-1, bin_idx)[..., 0]
144 | delta = heights / widths
145 | input_delta = delta.gather(-1, bin_idx)[..., 0]
146 |
147 | input_derivatives = derivatives.gather(-1, bin_idx)[..., 0]
148 | input_derivatives_plus_one = derivatives[..., 1:].gather(-1, bin_idx)[..., 0]
149 |
150 | input_heights = heights.gather(-1, bin_idx)[..., 0]
151 |
152 | if inverse:
153 | a = (((inputs - input_cumheights) * (input_derivatives
154 | + input_derivatives_plus_one
155 | - 2 * input_delta)
156 | + input_heights * (input_delta - input_derivatives)))
157 | b = (input_heights * input_derivatives
158 | - (inputs - input_cumheights) * (input_derivatives
159 | + input_derivatives_plus_one
160 | - 2 * input_delta))
161 | c = - input_delta * (inputs - input_cumheights)
162 |
163 | discriminant = b.pow(2) - 4 * a * c
164 | assert (discriminant >= 0).all()
165 |
166 | root = (2 * c) / (-b - torch.sqrt(discriminant))
167 | outputs = root * input_bin_widths + input_cumwidths
168 |
169 | theta_one_minus_theta = root * (1 - root)
170 | denominator = input_delta + ((input_derivatives + input_derivatives_plus_one - 2 * input_delta)
171 | * theta_one_minus_theta)
172 | derivative_numerator = input_delta.pow(2) * (input_derivatives_plus_one * root.pow(2)
173 | + 2 * input_delta * theta_one_minus_theta
174 | + input_derivatives * (1 - root).pow(2))
175 | logabsdet = torch.log(derivative_numerator) - 2 * torch.log(denominator)
176 |
177 | return outputs, -logabsdet
178 | else:
179 | theta = (inputs - input_cumwidths) / input_bin_widths
180 | theta_one_minus_theta = theta * (1 - theta)
181 |
182 | numerator = input_heights * (input_delta * theta.pow(2)
183 | + input_derivatives * theta_one_minus_theta)
184 | denominator = input_delta + ((input_derivatives + input_derivatives_plus_one - 2 * input_delta)
185 | * theta_one_minus_theta)
186 | outputs = input_cumheights + numerator / denominator
187 |
188 | derivative_numerator = input_delta.pow(2) * (input_derivatives_plus_one * theta.pow(2)
189 | + 2 * input_delta * theta_one_minus_theta
190 | + input_derivatives * (1 - theta).pow(2))
191 | logabsdet = torch.log(derivative_numerator) - 2 * torch.log(denominator)
192 |
193 | return outputs, logabsdet
194 |
--------------------------------------------------------------------------------
/stft.py:
--------------------------------------------------------------------------------
1 | """
2 | BSD 3-Clause License
3 | Copyright (c) 2017, Prem Seetharaman
4 | All rights reserved.
5 | * Redistribution and use in source and binary forms, with or without
6 | modification, are permitted provided that the following conditions are met:
7 | * Redistributions of source code must retain the above copyright notice,
8 | this list of conditions and the following disclaimer.
9 | * Redistributions in binary form must reproduce the above copyright notice, this
10 | list of conditions and the following disclaimer in the
11 | documentation and/or other materials provided with the distribution.
12 | * Neither the name of the copyright holder nor the names of its
13 | contributors may be used to endorse or promote products derived from this
14 | software without specific prior written permission.
15 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
16 | ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
17 | WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
18 | DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
19 | ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
20 | (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
21 | LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
22 | ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
23 | (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
24 | SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
25 | """
26 |
27 | import torch
28 | import numpy as np
29 | import torch.nn.functional as F
30 | from torch.autograd import Variable
31 | from scipy.signal import get_window
32 | from librosa.util import pad_center, tiny
33 | import librosa.util as librosa_util
34 |
35 | def window_sumsquare(window, n_frames, hop_length=200, win_length=800,
36 | n_fft=800, dtype=np.float32, norm=None):
37 | """
38 | # from librosa 0.6
39 | Compute the sum-square envelope of a window function at a given hop length.
40 | This is used to estimate modulation effects induced by windowing
41 | observations in short-time fourier transforms.
42 | Parameters
43 | ----------
44 | window : string, tuple, number, callable, or list-like
45 | Window specification, as in `get_window`
46 | n_frames : int > 0
47 | The number of analysis frames
48 | hop_length : int > 0
49 | The number of samples to advance between frames
50 | win_length : [optional]
51 | The length of the window function. By default, this matches `n_fft`.
52 | n_fft : int > 0
53 | The length of each analysis frame.
54 | dtype : np.dtype
55 | The data type of the output
56 | Returns
57 | -------
58 | wss : np.ndarray, shape=`(n_fft + hop_length * (n_frames - 1))`
59 | The sum-squared envelope of the window function
60 | """
61 | if win_length is None:
62 | win_length = n_fft
63 |
64 | n = n_fft + hop_length * (n_frames - 1)
65 | x = np.zeros(n, dtype=dtype)
66 |
67 | # Compute the squared window at the desired length
68 | win_sq = get_window(window, win_length, fftbins=True)
69 | win_sq = librosa_util.normalize(win_sq, norm=norm)**2
70 | win_sq = librosa_util.pad_center(win_sq, n_fft)
71 |
72 | # Fill the envelope
73 | for i in range(n_frames):
74 | sample = i * hop_length
75 | x[sample:min(n, sample + n_fft)] += win_sq[:max(0, min(n_fft, n - sample))]
76 | return x
77 |
78 |
79 | class STFT(torch.nn.Module):
80 | """adapted from Prem Seetharaman's https://github.com/pseeth/pytorch-stft"""
81 | def __init__(self, filter_length=800, hop_length=200, win_length=800,
82 | window='hann'):
83 | super(STFT, self).__init__()
84 | self.filter_length = filter_length
85 | self.hop_length = hop_length
86 | self.win_length = win_length
87 | self.window = window
88 | self.forward_transform = None
89 | scale = self.filter_length / self.hop_length
90 | fourier_basis = np.fft.fft(np.eye(self.filter_length))
91 |
92 | cutoff = int((self.filter_length / 2 + 1))
93 | fourier_basis = np.vstack([np.real(fourier_basis[:cutoff, :]),
94 | np.imag(fourier_basis[:cutoff, :])])
95 |
96 | forward_basis = torch.FloatTensor(fourier_basis[:, None, :])
97 | inverse_basis = torch.FloatTensor(
98 | np.linalg.pinv(scale * fourier_basis).T[:, None, :])
99 |
100 | if window is not None:
101 | assert(filter_length >= win_length)
102 | # get window and zero center pad it to filter_length
103 | fft_window = get_window(window, win_length, fftbins=True)
104 | fft_window = pad_center(fft_window, filter_length)
105 | fft_window = torch.from_numpy(fft_window).float()
106 |
107 | # window the bases
108 | forward_basis *= fft_window
109 | inverse_basis *= fft_window
110 |
111 | self.register_buffer('forward_basis', forward_basis.float())
112 | self.register_buffer('inverse_basis', inverse_basis.float())
113 |
114 | def transform(self, input_data):
115 | num_batches = input_data.size(0)
116 | num_samples = input_data.size(1)
117 |
118 | self.num_samples = num_samples
119 |
120 | # similar to librosa, reflect-pad the input
121 | input_data = input_data.view(num_batches, 1, num_samples)
122 | input_data = F.pad(
123 | input_data.unsqueeze(1),
124 | (int(self.filter_length / 2), int(self.filter_length / 2), 0, 0),
125 | mode='reflect')
126 | input_data = input_data.squeeze(1)
127 |
128 | forward_transform = F.conv1d(
129 | input_data,
130 | Variable(self.forward_basis, requires_grad=False),
131 | stride=self.hop_length,
132 | padding=0)
133 |
134 | cutoff = int((self.filter_length / 2) + 1)
135 | real_part = forward_transform[:, :cutoff, :]
136 | imag_part = forward_transform[:, cutoff:, :]
137 |
138 | magnitude = torch.sqrt(real_part**2 + imag_part**2)
139 | phase = torch.autograd.Variable(
140 | torch.atan2(imag_part.data, real_part.data))
141 |
142 | return magnitude, phase
143 |
144 | def inverse(self, magnitude, phase):
145 | recombine_magnitude_phase = torch.cat(
146 | [magnitude*torch.cos(phase), magnitude*torch.sin(phase)], dim=1)
147 |
148 | inverse_transform = F.conv_transpose1d(
149 | recombine_magnitude_phase,
150 | Variable(self.inverse_basis, requires_grad=False),
151 | stride=self.hop_length,
152 | padding=0)
153 |
154 | if self.window is not None:
155 | window_sum = window_sumsquare(
156 | self.window, magnitude.size(-1), hop_length=self.hop_length,
157 | win_length=self.win_length, n_fft=self.filter_length,
158 | dtype=np.float32)
159 | # remove modulation effects
160 | approx_nonzero_indices = torch.from_numpy(
161 | np.where(window_sum > tiny(window_sum))[0])
162 | window_sum = torch.autograd.Variable(
163 | torch.from_numpy(window_sum), requires_grad=False)
164 | window_sum = window_sum.to(inverse_transform.device()) if magnitude.is_cuda else window_sum
165 | inverse_transform[:, :, approx_nonzero_indices] /= window_sum[approx_nonzero_indices]
166 |
167 | # scale by hop ratio
168 | inverse_transform *= float(self.filter_length) / self.hop_length
169 |
170 | inverse_transform = inverse_transform[:, :, int(self.filter_length/2):]
171 | inverse_transform = inverse_transform[:, :, :-int(self.filter_length/2):]
172 |
173 | return inverse_transform
174 |
175 | def forward(self, input_data):
176 | self.magnitude, self.phase = self.transform(input_data)
177 | reconstruction = self.inverse(self.magnitude, self.phase)
178 | return reconstruction
179 |
180 |
181 | class TorchSTFT(torch.nn.Module):
182 | def __init__(self, filter_length=800, hop_length=200, win_length=800, window='hann'):
183 | super().__init__()
184 | self.filter_length = filter_length
185 | self.hop_length = hop_length
186 | self.win_length = win_length
187 | self.window = torch.from_numpy(get_window(window, win_length, fftbins=True).astype(np.float32))
188 |
189 | def transform(self, input_data):
190 | forward_transform = torch.stft(
191 | input_data,
192 | self.filter_length, self.hop_length, self.win_length, window=self.window,
193 | return_complex=True)
194 |
195 | return torch.abs(forward_transform), torch.angle(forward_transform)
196 |
197 | def inverse(self, magnitude, phase):
198 | inverse_transform = torch.istft(
199 | magnitude * torch.exp(phase * 1j),
200 | self.filter_length, self.hop_length, self.win_length, window=self.window.to(magnitude.device))
201 |
202 | return inverse_transform.unsqueeze(-2) # unsqueeze to stay consistent with conv_transpose1d implementation
203 |
204 | def forward(self, input_data):
205 | self.magnitude, self.phase = self.transform(input_data)
206 | reconstruction = self.inverse(self.magnitude, self.phase)
207 | return reconstruction
208 |
209 |
210 |
--------------------------------------------------------------------------------
/utils.py:
--------------------------------------------------------------------------------
1 | import os
2 | import glob
3 | import sys
4 | import argparse
5 | import logging
6 | import json
7 | import subprocess
8 | import numpy as np
9 | from scipy.io.wavfile import read
10 | import torch
11 |
12 | MATPLOTLIB_FLAG = False
13 |
14 | logging.basicConfig(stream=sys.stdout, level=logging.WARNING)
15 | logger = logging
16 |
17 |
18 | def load_checkpoint(checkpoint_path, model, optimizer=None):
19 | assert os.path.isfile(checkpoint_path)
20 | checkpoint_dict = torch.load(checkpoint_path, map_location='cpu')
21 | iteration = checkpoint_dict['iteration']
22 | learning_rate = checkpoint_dict['learning_rate']
23 | if optimizer is not None:
24 | optimizer.load_state_dict(checkpoint_dict['optimizer'])
25 | saved_state_dict = checkpoint_dict['model']
26 | if hasattr(model, 'module'):
27 | state_dict = model.module.state_dict()
28 | else:
29 | state_dict = model.state_dict()
30 | new_state_dict= {}
31 | for k, v in state_dict.items():
32 | try:
33 | new_state_dict[k] = saved_state_dict[k]
34 | except:
35 | logger.info("%s is not in the checkpoint" % k)
36 | new_state_dict[k] = v
37 | if hasattr(model, 'module'):
38 | model.module.load_state_dict(new_state_dict)
39 | else:
40 | model.load_state_dict(new_state_dict)
41 | logger.info("Loaded checkpoint '{}' (iteration {})" .format(
42 | checkpoint_path, iteration))
43 | return model, optimizer, learning_rate, iteration
44 |
45 |
46 | def load_checkpoint_for_finetuning(checkpoint_path, model,hps, optimizer=None):
47 | assert os.path.isfile(checkpoint_path)
48 | checkpoint_dict = torch.load(checkpoint_path, map_location='cpu')
49 | iteration = 1
50 | learning_rate = hps.train.learning_rate
51 | if optimizer is not None:
52 | optimizer.load_state_dict(checkpoint_dict['optimizer'])
53 | saved_state_dict = checkpoint_dict['model']
54 | if hasattr(model, 'module'):
55 | state_dict = model.module.state_dict()
56 | else:
57 | state_dict = model.state_dict()
58 | new_state_dict= {}
59 | for k, v in state_dict.items():
60 | try:
61 | new_state_dict[k] = saved_state_dict[k]
62 | except:
63 | logger.info("%s is not in the checkpoint" % k)
64 | new_state_dict[k] = v
65 | if hasattr(model, 'module'):
66 | model.module.load_state_dict(new_state_dict)
67 | else:
68 | model.load_state_dict(new_state_dict)
69 | logger.info("Loaded checkpoint for finetuning'{}' (iteration {})" .format(
70 | checkpoint_path, iteration))
71 | return model, optimizer, learning_rate, iteration
72 |
73 | def save_checkpoint(model, optimizer, learning_rate, iteration, checkpoint_path):
74 | logger.info("Saving model and optimizer state at iteration {} to {}".format(
75 | iteration, checkpoint_path))
76 | if hasattr(model, 'module'):
77 | state_dict = model.module.state_dict()
78 | else:
79 | state_dict = model.state_dict()
80 | torch.save({'model': state_dict,
81 | 'iteration': iteration,
82 | 'optimizer': optimizer.state_dict(),
83 | 'learning_rate': learning_rate}, checkpoint_path)
84 |
85 |
86 | def load_model_diffsize(checkpoint_path, model,hps, optimizer=None):
87 | assert os.path.isfile(checkpoint_path)
88 | checkpoint_dict = torch.load(checkpoint_path, map_location='cpu')["model"]
89 |
90 | if hasattr(model, 'module'):
91 | state_dict = model.module.state_dict()
92 | else:
93 | state_dict = model.state_dict()
94 |
95 | for k, v in checkpoint_dict.items():
96 | if k in state_dict and state_dict[k].size() == v.size():
97 | state_dict[k] = v
98 | else:
99 | print("Diffsize ",k)
100 |
101 | if hasattr(model, 'module'):
102 | model.module.load_state_dict(state_dict, strict=False)
103 | else:
104 | model.load_state_dict(state_dict, strict=False)
105 |
106 | return model
107 |
108 |
109 | def summarize(writer, global_step, scalars={}, histograms={}, images={}, audios={}, audio_sampling_rate=44100):
110 | for k, v in scalars.items():
111 | writer.add_scalar(k, v, global_step)
112 | for k, v in histograms.items():
113 | writer.add_histogram(k, v, global_step)
114 | for k, v in images.items():
115 | writer.add_image(k, v, global_step, dataformats='HWC')
116 | for k, v in audios.items():
117 | writer.add_audio(k, v, global_step, audio_sampling_rate)
118 |
119 |
120 | def latest_checkpoint_path(dir_path, regex="G_*.pth"):
121 | f_list = glob.glob(os.path.join(dir_path, regex))
122 | f_list.sort(key=lambda f: int("".join(filter(str.isdigit, f))))
123 | x = f_list[-1]
124 | print(x)
125 | return x
126 |
127 |
128 | def plot_spectrogram_to_numpy(spectrogram):
129 | global MATPLOTLIB_FLAG
130 | if not MATPLOTLIB_FLAG:
131 | import matplotlib
132 | matplotlib.use("Agg")
133 | MATPLOTLIB_FLAG = True
134 | mpl_logger = logging.getLogger('matplotlib')
135 | mpl_logger.setLevel(logging.WARNING)
136 | import matplotlib.pylab as plt
137 | import numpy as np
138 |
139 | fig, ax = plt.subplots(figsize=(10,2))
140 | im = ax.imshow(spectrogram, aspect="auto", origin="lower",
141 | interpolation='none')
142 | plt.colorbar(im, ax=ax)
143 | plt.xlabel("Frames")
144 | plt.ylabel("Channels")
145 | plt.tight_layout()
146 |
147 | fig.canvas.draw()
148 | data = np.fromstring(fig.canvas.tostring_rgb(), dtype=np.uint8, sep='')
149 | data = data.reshape(fig.canvas.get_width_height()[::-1] + (3,))
150 | plt.close()
151 | return data
152 |
153 |
154 | def plot_alignment_to_numpy(alignment, info=None):
155 | global MATPLOTLIB_FLAG
156 | if not MATPLOTLIB_FLAG:
157 | import matplotlib
158 | matplotlib.use("Agg")
159 | MATPLOTLIB_FLAG = True
160 | mpl_logger = logging.getLogger('matplotlib')
161 | mpl_logger.setLevel(logging.WARNING)
162 | import matplotlib.pylab as plt
163 | import numpy as np
164 |
165 | fig, ax = plt.subplots(figsize=(6, 4))
166 | im = ax.imshow(alignment.transpose(), aspect='auto', origin='lower',
167 | interpolation='none')
168 | fig.colorbar(im, ax=ax)
169 | xlabel = 'Decoder timestep'
170 | if info is not None:
171 | xlabel += '\n\n' + info
172 | plt.xlabel(xlabel)
173 | plt.ylabel('Encoder timestep')
174 | plt.tight_layout()
175 |
176 | fig.canvas.draw()
177 | data = np.fromstring(fig.canvas.tostring_rgb(), dtype=np.uint8, sep='')
178 | data = data.reshape(fig.canvas.get_width_height()[::-1] + (3,))
179 | plt.close()
180 | return data
181 |
182 | import soundfile as sf
183 | def load_wav_to_torch(full_path):
184 | sampling_rate, wav = read(full_path.replace("\\", "/")) ### modify .replace("\\", "/") ###
185 |
186 | if len(wav.shape) == 2:
187 | wav = wav[:, 0]
188 | if wav.dtype == np.int16:
189 | wav = wav / 32768.0
190 | elif wav.dtype == np.int32:
191 | wav = wav / 2147483648.0
192 | elif wav.dtype == np.uint8:
193 | wav = (wav - 128) / 128.0
194 | wav = wav.astype(np.float32)
195 |
196 | if sampling_rate != 44100:
197 | print("ERROR SAMPLINGRATE")
198 |
199 | return torch.FloatTensor(wav), sampling_rate
200 | """
201 | sampling_rate, data = read(full_path)
202 | #data, sampling_rate = sf.read(full_path)
203 |
204 | if sampling_rate != 44100:
205 | print("ERROR SAMPLINGRATE")
206 | return torch.FloatTensor(data.astype(np.float32)), sampling_rate
207 | """
208 |
209 | def load_filepaths_and_text(filename, split="|"):
210 | with open(filename, encoding='utf-8') as f:
211 | filepaths_and_text = [line.strip().split(split) for line in f]
212 | return filepaths_and_text
213 |
214 |
215 | def get_hparams(init=True):
216 | parser = argparse.ArgumentParser()
217 | parser.add_argument('-c', '--config', type=str, default="./configs/jsut_fullband.json",
218 | help='JSON file for configuration')
219 | parser.add_argument('-m', '--model',default='JSUT_BASIC5000', type=str,
220 | help='Model Name')
221 |
222 | args = parser.parse_args()
223 | model_dir = os.path.join("./logs", args.model)
224 |
225 | if not os.path.exists(model_dir):
226 | os.makedirs(model_dir)
227 |
228 | config_path = args.config
229 | config_save_path = os.path.join(model_dir, "config.json")
230 | if init:
231 | with open(config_path, "r") as f:
232 | data = f.read()
233 | with open(config_save_path, "w") as f:
234 | f.write(data)
235 | else:
236 | with open(config_save_path, "r") as f:
237 | data = f.read()
238 | config = json.loads(data)
239 |
240 | hparams = HParams(**config)
241 | hparams.model_dir = model_dir
242 | return hparams
243 |
244 |
245 | def get_hparams_from_dir(model_dir):
246 | config_save_path = os.path.join(model_dir, "config.json")
247 | with open(config_save_path, "r") as f:
248 | data = f.read()
249 | config = json.loads(data)
250 |
251 | hparams =HParams(**config)
252 | hparams.model_dir = model_dir
253 | return hparams
254 |
255 |
256 | def get_hparams_from_file(config_path):
257 | with open(config_path, "r") as f:
258 | data = f.read()
259 | config = json.loads(data)
260 |
261 | hparams =HParams(**config)
262 | return hparams
263 |
264 |
265 | def check_git_hash(model_dir):
266 | source_dir = os.path.dirname(os.path.realpath(__file__))
267 | if not os.path.exists(os.path.join(source_dir, ".git")):
268 | logger.warn("{} is not a git repository, therefore hash value comparison will be ignored.".format(
269 | source_dir
270 | ))
271 | return
272 |
273 | cur_hash = subprocess.getoutput("git rev-parse HEAD")
274 |
275 | path = os.path.join(model_dir, "githash")
276 | if os.path.exists(path):
277 | saved_hash = open(path).read()
278 | if saved_hash != cur_hash:
279 | logger.warn("git hash values are different. {}(saved) != {}(current)".format(
280 | saved_hash[:8], cur_hash[:8]))
281 | else:
282 | open(path, "w").write(cur_hash)
283 |
284 |
285 | def get_logger(model_dir, filename="train.log"):
286 | global logger
287 | logger = logging.getLogger(os.path.basename(model_dir))
288 | logger.setLevel(logging.DEBUG)
289 |
290 | formatter = logging.Formatter("%(asctime)s\t%(name)s\t%(levelname)s\t%(message)s")
291 | if not os.path.exists(model_dir):
292 | os.makedirs(model_dir)
293 | h = logging.FileHandler(os.path.join(model_dir, filename))
294 | h.setLevel(logging.DEBUG)
295 | h.setFormatter(formatter)
296 | logger.addHandler(h)
297 | return logger
298 |
299 |
300 | class HParams():
301 | def __init__(self, **kwargs):
302 | for k, v in kwargs.items():
303 | if type(v) == dict:
304 | v = HParams(**v)
305 | self[k] = v
306 |
307 | def keys(self):
308 | return self.__dict__.keys()
309 |
310 | def items(self):
311 | return self.__dict__.items()
312 |
313 | def values(self):
314 | return self.__dict__.values()
315 |
316 | def __len__(self):
317 | return len(self.__dict__)
318 |
319 | def __getitem__(self, key):
320 | return getattr(self, key)
321 |
322 | def __setitem__(self, key, value):
323 | return setattr(self, key, value)
324 |
325 | def __contains__(self, key):
326 | return key in self.__dict__
327 |
328 | def __repr__(self):
329 | return self.__dict__.__repr__()
330 |
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | Apache License
2 | Version 2.0, January 2004
3 | http://www.apache.org/licenses/
4 |
5 | TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
6 |
7 | 1. Definitions.
8 |
9 | "License" shall mean the terms and conditions for use, reproduction,
10 | and distribution as defined by Sections 1 through 9 of this document.
11 |
12 | "Licensor" shall mean the copyright owner or entity authorized by
13 | the copyright owner that is granting the License.
14 |
15 | "Legal Entity" shall mean the union of the acting entity and all
16 | other entities that control, are controlled by, or are under common
17 | control with that entity. For the purposes of this definition,
18 | "control" means (i) the power, direct or indirect, to cause the
19 | direction or management of such entity, whether by contract or
20 | otherwise, or (ii) ownership of fifty percent (50%) or more of the
21 | outstanding shares, or (iii) beneficial ownership of such entity.
22 |
23 | "You" (or "Your") shall mean an individual or Legal Entity
24 | exercising permissions granted by this License.
25 |
26 | "Source" form shall mean the preferred form for making modifications,
27 | including but not limited to software source code, documentation
28 | source, and configuration files.
29 |
30 | "Object" form shall mean any form resulting from mechanical
31 | transformation or translation of a Source form, including but
32 | not limited to compiled object code, generated documentation,
33 | and conversions to other media types.
34 |
35 | "Work" shall mean the work of authorship, whether in Source or
36 | Object form, made available under the License, as indicated by a
37 | copyright notice that is included in or attached to the work
38 | (an example is provided in the Appendix below).
39 |
40 | "Derivative Works" shall mean any work, whether in Source or Object
41 | form, that is based on (or derived from) the Work and for which the
42 | editorial revisions, annotations, elaborations, or other modifications
43 | represent, as a whole, an original work of authorship. For the purposes
44 | of this License, Derivative Works shall not include works that remain
45 | separable from, or merely link (or bind by name) to the interfaces of,
46 | the Work and Derivative Works thereof.
47 |
48 | "Contribution" shall mean any work of authorship, including
49 | the original version of the Work and any modifications or additions
50 | to that Work or Derivative Works thereof, that is intentionally
51 | submitted to Licensor for inclusion in the Work by the copyright owner
52 | or by an individual or Legal Entity authorized to submit on behalf of
53 | the copyright owner. For the purposes of this definition, "submitted"
54 | means any form of electronic, verbal, or written communication sent
55 | to the Licensor or its representatives, including but not limited to
56 | communication on electronic mailing lists, source code control systems,
57 | and issue tracking systems that are managed by, or on behalf of, the
58 | Licensor for the purpose of discussing and improving the Work, but
59 | excluding communication that is conspicuously marked or otherwise
60 | designated in writing by the copyright owner as "Not a Contribution."
61 |
62 | "Contributor" shall mean Licensor and any individual or Legal Entity
63 | on behalf of whom a Contribution has been received by Licensor and
64 | subsequently incorporated within the Work.
65 |
66 | 2. Grant of Copyright License. Subject to the terms and conditions of
67 | this License, each Contributor hereby grants to You a perpetual,
68 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable
69 | copyright license to reproduce, prepare Derivative Works of,
70 | publicly display, publicly perform, sublicense, and distribute the
71 | Work and such Derivative Works in Source or Object form.
72 |
73 | 3. Grant of Patent License. Subject to the terms and conditions of
74 | this License, each Contributor hereby grants to You a perpetual,
75 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable
76 | (except as stated in this section) patent license to make, have made,
77 | use, offer to sell, sell, import, and otherwise transfer the Work,
78 | where such license applies only to those patent claims licensable
79 | by such Contributor that are necessarily infringed by their
80 | Contribution(s) alone or by combination of their Contribution(s)
81 | with the Work to which such Contribution(s) was submitted. If You
82 | institute patent litigation against any entity (including a
83 | cross-claim or counterclaim in a lawsuit) alleging that the Work
84 | or a Contribution incorporated within the Work constitutes direct
85 | or contributory patent infringement, then any patent licenses
86 | granted to You under this License for that Work shall terminate
87 | as of the date such litigation is filed.
88 |
89 | 4. Redistribution. You may reproduce and distribute copies of the
90 | Work or Derivative Works thereof in any medium, with or without
91 | modifications, and in Source or Object form, provided that You
92 | meet the following conditions:
93 |
94 | (a) You must give any other recipients of the Work or
95 | Derivative Works a copy of this License; and
96 |
97 | (b) You must cause any modified files to carry prominent notices
98 | stating that You changed the files; and
99 |
100 | (c) You must retain, in the Source form of any Derivative Works
101 | that You distribute, all copyright, patent, trademark, and
102 | attribution notices from the Source form of the Work,
103 | excluding those notices that do not pertain to any part of
104 | the Derivative Works; and
105 |
106 | (d) If the Work includes a "NOTICE" text file as part of its
107 | distribution, then any Derivative Works that You distribute must
108 | include a readable copy of the attribution notices contained
109 | within such NOTICE file, excluding those notices that do not
110 | pertain to any part of the Derivative Works, in at least one
111 | of the following places: within a NOTICE text file distributed
112 | as part of the Derivative Works; within the Source form or
113 | documentation, if provided along with the Derivative Works; or,
114 | within a display generated by the Derivative Works, if and
115 | wherever such third-party notices normally appear. The contents
116 | of the NOTICE file are for informational purposes only and
117 | do not modify the License. You may add Your own attribution
118 | notices within Derivative Works that You distribute, alongside
119 | or as an addendum to the NOTICE text from the Work, provided
120 | that such additional attribution notices cannot be construed
121 | as modifying the License.
122 |
123 | You may add Your own copyright statement to Your modifications and
124 | may provide additional or different license terms and conditions
125 | for use, reproduction, or distribution of Your modifications, or
126 | for any such Derivative Works as a whole, provided Your use,
127 | reproduction, and distribution of the Work otherwise complies with
128 | the conditions stated in this License.
129 |
130 | 5. Submission of Contributions. Unless You explicitly state otherwise,
131 | any Contribution intentionally submitted for inclusion in the Work
132 | by You to the Licensor shall be under the terms and conditions of
133 | this License, without any additional terms or conditions.
134 | Notwithstanding the above, nothing herein shall supersede or modify
135 | the terms of any separate license agreement you may have executed
136 | with Licensor regarding such Contributions.
137 |
138 | 6. Trademarks. This License does not grant permission to use the trade
139 | names, trademarks, service marks, or product names of the Licensor,
140 | except as required for reasonable and customary use in describing the
141 | origin of the Work and reproducing the content of the NOTICE file.
142 |
143 | 7. Disclaimer of Warranty. Unless required by applicable law or
144 | agreed to in writing, Licensor provides the Work (and each
145 | Contributor provides its Contributions) on an "AS IS" BASIS,
146 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
147 | implied, including, without limitation, any warranties or conditions
148 | of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
149 | PARTICULAR PURPOSE. You are solely responsible for determining the
150 | appropriateness of using or redistributing the Work and assume any
151 | risks associated with Your exercise of permissions under this License.
152 |
153 | 8. Limitation of Liability. In no event and under no legal theory,
154 | whether in tort (including negligence), contract, or otherwise,
155 | unless required by applicable law (such as deliberate and grossly
156 | negligent acts) or agreed to in writing, shall any Contributor be
157 | liable to You for damages, including any direct, indirect, special,
158 | incidental, or consequential damages of any character arising as a
159 | result of this License or out of the use or inability to use the
160 | Work (including but not limited to damages for loss of goodwill,
161 | work stoppage, computer failure or malfunction, or any and all
162 | other commercial damages or losses), even if such Contributor
163 | has been advised of the possibility of such damages.
164 |
165 | 9. Accepting Warranty or Additional Liability. While redistributing
166 | the Work or Derivative Works thereof, You may choose to offer,
167 | and charge a fee for, acceptance of support, warranty, indemnity,
168 | or other liability obligations and/or rights consistent with this
169 | License. However, in accepting such obligations, You may act only
170 | on Your own behalf and on Your sole responsibility, not on behalf
171 | of any other Contributor, and only if You agree to indemnify,
172 | defend, and hold each Contributor harmless for any liability
173 | incurred by, or claims asserted against, such Contributor by reason
174 | of your accepting any such warranty or additional liability.
175 |
176 | END OF TERMS AND CONDITIONS
177 |
178 | APPENDIX: How to apply the Apache License to your work.
179 |
180 | To apply the Apache License to your work, attach the following
181 | boilerplate notice, with the fields enclosed by brackets "[]"
182 | replaced with your own identifying information. (Don't include
183 | the brackets!) The text should be enclosed in the appropriate
184 | comment syntax for the file format. We also recommend that a
185 | file or class name and description of purpose be included on the
186 | same "printed page" as the copyright notice for easier
187 | identification within third-party archives.
188 |
189 | Copyright [yyyy] [name of copyright owner]
190 |
191 | Licensed under the Apache License, Version 2.0 (the "License");
192 | you may not use this file except in compliance with the License.
193 | You may obtain a copy of the License at
194 |
195 | http://www.apache.org/licenses/LICENSE-2.0
196 |
197 | Unless required by applicable law or agreed to in writing, software
198 | distributed under the License is distributed on an "AS IS" BASIS,
199 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
200 | See the License for the specific language governing permissions and
201 | limitations under the License.
202 |
--------------------------------------------------------------------------------
/attentions.py:
--------------------------------------------------------------------------------
1 | import copy
2 | import math
3 | import numpy as np
4 | import torch
5 | from torch import nn
6 | from torch.nn import functional as F
7 |
8 | import commons
9 | import modules
10 | from modules import LayerNorm
11 |
12 |
13 | class Encoder(nn.Module):
14 | def __init__(self, hidden_channels, filter_channels, n_heads, n_layers, kernel_size=1, p_dropout=0., window_size=4, **kwargs):
15 | super().__init__()
16 | self.hidden_channels = hidden_channels
17 | self.filter_channels = filter_channels
18 | self.n_heads = n_heads
19 | self.n_layers = n_layers
20 | self.kernel_size = kernel_size
21 | self.p_dropout = p_dropout
22 | self.window_size = window_size
23 |
24 | self.drop = nn.Dropout(p_dropout)
25 | self.attn_layers = nn.ModuleList()
26 | self.norm_layers_1 = nn.ModuleList()
27 | self.ffn_layers = nn.ModuleList()
28 | self.norm_layers_2 = nn.ModuleList()
29 | for i in range(self.n_layers):
30 | self.attn_layers.append(MultiHeadAttention(hidden_channels, hidden_channels, n_heads, p_dropout=p_dropout, window_size=window_size))
31 | self.norm_layers_1.append(LayerNorm(hidden_channels))
32 | self.ffn_layers.append(FFN(hidden_channels, hidden_channels, filter_channels, kernel_size, p_dropout=p_dropout))
33 | self.norm_layers_2.append(LayerNorm(hidden_channels))
34 |
35 | def forward(self, x, x_mask):
36 | attn_mask = x_mask.unsqueeze(2) * x_mask.unsqueeze(-1)
37 | x = x * x_mask
38 | for i in range(self.n_layers):
39 | y = self.attn_layers[i](x, x, attn_mask)
40 | y = self.drop(y)
41 | x = self.norm_layers_1[i](x + y)
42 |
43 | y = self.ffn_layers[i](x, x_mask)
44 | y = self.drop(y)
45 | x = self.norm_layers_2[i](x + y)
46 | x = x * x_mask
47 | return x
48 |
49 |
50 | class Decoder(nn.Module):
51 | def __init__(self, hidden_channels, filter_channels, n_heads, n_layers, kernel_size=1, p_dropout=0., proximal_bias=False, proximal_init=True, **kwargs):
52 | super().__init__()
53 | self.hidden_channels = hidden_channels
54 | self.filter_channels = filter_channels
55 | self.n_heads = n_heads
56 | self.n_layers = n_layers
57 | self.kernel_size = kernel_size
58 | self.p_dropout = p_dropout
59 | self.proximal_bias = proximal_bias
60 | self.proximal_init = proximal_init
61 |
62 | self.drop = nn.Dropout(p_dropout)
63 | self.self_attn_layers = nn.ModuleList()
64 | self.norm_layers_0 = nn.ModuleList()
65 | self.encdec_attn_layers = nn.ModuleList()
66 | self.norm_layers_1 = nn.ModuleList()
67 | self.ffn_layers = nn.ModuleList()
68 | self.norm_layers_2 = nn.ModuleList()
69 | for i in range(self.n_layers):
70 | self.self_attn_layers.append(MultiHeadAttention(hidden_channels, hidden_channels, n_heads, p_dropout=p_dropout, proximal_bias=proximal_bias, proximal_init=proximal_init))
71 | self.norm_layers_0.append(LayerNorm(hidden_channels))
72 | self.encdec_attn_layers.append(MultiHeadAttention(hidden_channels, hidden_channels, n_heads, p_dropout=p_dropout))
73 | self.norm_layers_1.append(LayerNorm(hidden_channels))
74 | self.ffn_layers.append(FFN(hidden_channels, hidden_channels, filter_channels, kernel_size, p_dropout=p_dropout, causal=True))
75 | self.norm_layers_2.append(LayerNorm(hidden_channels))
76 |
77 | def forward(self, x, x_mask, h, h_mask):
78 | """
79 | x: decoder input
80 | h: encoder output
81 | """
82 | self_attn_mask = commons.subsequent_mask(x_mask.size(2)).to(device=x.device, dtype=x.dtype)
83 | encdec_attn_mask = h_mask.unsqueeze(2) * x_mask.unsqueeze(-1)
84 | x = x * x_mask
85 | for i in range(self.n_layers):
86 | y = self.self_attn_layers[i](x, x, self_attn_mask)
87 | y = self.drop(y)
88 | x = self.norm_layers_0[i](x + y)
89 |
90 | y = self.encdec_attn_layers[i](x, h, encdec_attn_mask)
91 | y = self.drop(y)
92 | x = self.norm_layers_1[i](x + y)
93 |
94 | y = self.ffn_layers[i](x, x_mask)
95 | y = self.drop(y)
96 | x = self.norm_layers_2[i](x + y)
97 | x = x * x_mask
98 | return x
99 |
100 |
101 | class MultiHeadAttention(nn.Module):
102 | def __init__(self, channels, out_channels, n_heads, p_dropout=0., window_size=None, heads_share=True, block_length=None, proximal_bias=False, proximal_init=False):
103 | super().__init__()
104 | assert channels % n_heads == 0
105 |
106 | self.channels = channels
107 | self.out_channels = out_channels
108 | self.n_heads = n_heads
109 | self.p_dropout = p_dropout
110 | self.window_size = window_size
111 | self.heads_share = heads_share
112 | self.block_length = block_length
113 | self.proximal_bias = proximal_bias
114 | self.proximal_init = proximal_init
115 | self.attn = None
116 |
117 | self.k_channels = channels // n_heads
118 | self.conv_q = nn.Conv1d(channels, channels, 1)
119 | self.conv_k = nn.Conv1d(channels, channels, 1)
120 | self.conv_v = nn.Conv1d(channels, channels, 1)
121 | self.conv_o = nn.Conv1d(channels, out_channels, 1)
122 | self.drop = nn.Dropout(p_dropout)
123 |
124 | if window_size is not None:
125 | n_heads_rel = 1 if heads_share else n_heads
126 | rel_stddev = self.k_channels**-0.5
127 | self.emb_rel_k = nn.Parameter(torch.randn(n_heads_rel, window_size * 2 + 1, self.k_channels) * rel_stddev)
128 | self.emb_rel_v = nn.Parameter(torch.randn(n_heads_rel, window_size * 2 + 1, self.k_channels) * rel_stddev)
129 |
130 | nn.init.xavier_uniform_(self.conv_q.weight)
131 | nn.init.xavier_uniform_(self.conv_k.weight)
132 | nn.init.xavier_uniform_(self.conv_v.weight)
133 | if proximal_init:
134 | with torch.no_grad():
135 | self.conv_k.weight.copy_(self.conv_q.weight)
136 | self.conv_k.bias.copy_(self.conv_q.bias)
137 |
138 | def forward(self, x, c, attn_mask=None):
139 | q = self.conv_q(x)
140 | k = self.conv_k(c)
141 | v = self.conv_v(c)
142 |
143 | x, self.attn = self.attention(q, k, v, mask=attn_mask)
144 |
145 | x = self.conv_o(x)
146 | return x
147 |
148 | def attention(self, query, key, value, mask=None):
149 | # reshape [b, d, t] -> [b, n_h, t, d_k]
150 | b, d, t_s, t_t = (*key.size(), query.size(2))
151 | query = query.view(b, self.n_heads, self.k_channels, t_t).transpose(2, 3)
152 | key = key.view(b, self.n_heads, self.k_channels, t_s).transpose(2, 3)
153 | value = value.view(b, self.n_heads, self.k_channels, t_s).transpose(2, 3)
154 |
155 | scores = torch.matmul(query / math.sqrt(self.k_channels), key.transpose(-2, -1))
156 | if self.window_size is not None:
157 | assert t_s == t_t, "Relative attention is only available for self-attention."
158 | key_relative_embeddings = self._get_relative_embeddings(self.emb_rel_k, t_s)
159 | rel_logits = self._matmul_with_relative_keys(query /math.sqrt(self.k_channels), key_relative_embeddings)
160 | scores_local = self._relative_position_to_absolute_position(rel_logits)
161 | scores = scores + scores_local
162 | if self.proximal_bias:
163 | assert t_s == t_t, "Proximal bias is only available for self-attention."
164 | scores = scores + self._attention_bias_proximal(t_s).to(device=scores.device, dtype=scores.dtype)
165 | if mask is not None:
166 | scores = scores.masked_fill(mask == 0, -1e4)
167 | if self.block_length is not None:
168 | assert t_s == t_t, "Local attention is only available for self-attention."
169 | block_mask = torch.ones_like(scores).triu(-self.block_length).tril(self.block_length)
170 | scores = scores.masked_fill(block_mask == 0, -1e4)
171 | p_attn = F.softmax(scores, dim=-1) # [b, n_h, t_t, t_s]
172 | p_attn = self.drop(p_attn)
173 | output = torch.matmul(p_attn, value)
174 | if self.window_size is not None:
175 | relative_weights = self._absolute_position_to_relative_position(p_attn)
176 | value_relative_embeddings = self._get_relative_embeddings(self.emb_rel_v, t_s)
177 | output = output + self._matmul_with_relative_values(relative_weights, value_relative_embeddings)
178 | output = output.transpose(2, 3).contiguous().view(b, d, t_t) # [b, n_h, t_t, d_k] -> [b, d, t_t]
179 | return output, p_attn
180 |
181 | def _matmul_with_relative_values(self, x, y):
182 | """
183 | x: [b, h, l, m]
184 | y: [h or 1, m, d]
185 | ret: [b, h, l, d]
186 | """
187 | ret = torch.matmul(x, y.unsqueeze(0))
188 | return ret
189 |
190 | def _matmul_with_relative_keys(self, x, y):
191 | """
192 | x: [b, h, l, d]
193 | y: [h or 1, m, d]
194 | ret: [b, h, l, m]
195 | """
196 | ret = torch.matmul(x, y.unsqueeze(0).transpose(-2, -1))
197 | return ret
198 |
199 | def _get_relative_embeddings(self, relative_embeddings, length):
200 | max_relative_position = 2 * self.window_size + 1
201 | # Pad first before slice to avoid using cond ops.
202 | pad_length = max(length - (self.window_size + 1), 0)
203 | slice_start_position = max((self.window_size + 1) - length, 0)
204 | slice_end_position = slice_start_position + 2 * length - 1
205 | if pad_length > 0:
206 | padded_relative_embeddings = F.pad(
207 | relative_embeddings,
208 | commons.convert_pad_shape([[0, 0], [pad_length, pad_length], [0, 0]]))
209 | else:
210 | padded_relative_embeddings = relative_embeddings
211 | used_relative_embeddings = padded_relative_embeddings[:,slice_start_position:slice_end_position]
212 | return used_relative_embeddings
213 |
214 | def _relative_position_to_absolute_position(self, x):
215 | """
216 | x: [b, h, l, 2*l-1]
217 | ret: [b, h, l, l]
218 | """
219 | batch, heads, length, _ = x.size()
220 | # Concat columns of pad to shift from relative to absolute indexing.
221 | x = F.pad(x, commons.convert_pad_shape([[0,0],[0,0],[0,0],[0,1]]))
222 |
223 | # Concat extra elements so to add up to shape (len+1, 2*len-1).
224 | x_flat = x.view([batch, heads, length * 2 * length])
225 | x_flat = F.pad(x_flat, commons.convert_pad_shape([[0,0],[0,0],[0,length-1]]))
226 |
227 | # Reshape and slice out the padded elements.
228 | x_final = x_flat.view([batch, heads, length+1, 2*length-1])[:, :, :length, length-1:]
229 | return x_final
230 |
231 | def _absolute_position_to_relative_position(self, x):
232 | """
233 | x: [b, h, l, l]
234 | ret: [b, h, l, 2*l-1]
235 | """
236 | batch, heads, length, _ = x.size()
237 | # padd along column
238 | x = F.pad(x, commons.convert_pad_shape([[0, 0], [0, 0], [0, 0], [0, length-1]]))
239 | x_flat = x.view([batch, heads, length**2 + length*(length -1)])
240 | # add 0's in the beginning that will skew the elements after reshape
241 | x_flat = F.pad(x_flat, commons.convert_pad_shape([[0, 0], [0, 0], [length, 0]]))
242 | x_final = x_flat.view([batch, heads, length, 2*length])[:,:,:,1:]
243 | return x_final
244 |
245 | def _attention_bias_proximal(self, length):
246 | """Bias for self-attention to encourage attention to close positions.
247 | Args:
248 | length: an integer scalar.
249 | Returns:
250 | a Tensor with shape [1, 1, length, length]
251 | """
252 | r = torch.arange(length, dtype=torch.float32)
253 | diff = torch.unsqueeze(r, 0) - torch.unsqueeze(r, 1)
254 | return torch.unsqueeze(torch.unsqueeze(-torch.log1p(torch.abs(diff)), 0), 0)
255 |
256 |
257 | class FFN(nn.Module):
258 | def __init__(self, in_channels, out_channels, filter_channels, kernel_size, p_dropout=0., activation=None, causal=False):
259 | super().__init__()
260 | self.in_channels = in_channels
261 | self.out_channels = out_channels
262 | self.filter_channels = filter_channels
263 | self.kernel_size = kernel_size
264 | self.p_dropout = p_dropout
265 | self.activation = activation
266 | self.causal = causal
267 |
268 | if causal:
269 | self.padding = self._causal_padding
270 | else:
271 | self.padding = self._same_padding
272 |
273 | self.conv_1 = nn.Conv1d(in_channels, filter_channels, kernel_size)
274 | self.conv_2 = nn.Conv1d(filter_channels, out_channels, kernel_size)
275 | self.drop = nn.Dropout(p_dropout)
276 |
277 | def forward(self, x, x_mask):
278 | x = self.conv_1(self.padding(x * x_mask))
279 | if self.activation == "gelu":
280 | x = x * torch.sigmoid(1.702 * x)
281 | else:
282 | x = torch.relu(x)
283 | x = self.drop(x)
284 | x = self.conv_2(self.padding(x * x_mask))
285 | return x * x_mask
286 |
287 | def _causal_padding(self, x):
288 | if self.kernel_size == 1:
289 | return x
290 | pad_l = self.kernel_size - 1
291 | pad_r = 0
292 | padding = [[0, 0], [0, 0], [pad_l, pad_r]]
293 | x = F.pad(x, commons.convert_pad_shape(padding))
294 | return x
295 |
296 | def _same_padding(self, x):
297 | if self.kernel_size == 1:
298 | return x
299 | pad_l = (self.kernel_size - 1) // 2
300 | pad_r = self.kernel_size // 2
301 | padding = [[0, 0], [0, 0], [pad_l, pad_r]]
302 | x = F.pad(x, commons.convert_pad_shape(padding))
303 | return x
304 |
--------------------------------------------------------------------------------
/modules.py:
--------------------------------------------------------------------------------
1 | import copy
2 | import math
3 | import numpy as np
4 | import scipy
5 | import torch
6 | from torch import nn
7 | from torch.nn import functional as F
8 |
9 | from torch.nn import Conv1d, ConvTranspose1d, AvgPool1d, Conv2d
10 | from torch.nn.utils import weight_norm, remove_weight_norm
11 |
12 | import commons
13 | from commons import init_weights, get_padding
14 | from transforms import piecewise_rational_quadratic_transform
15 |
16 |
17 | LRELU_SLOPE = 0.1
18 |
19 |
20 | class LayerNorm(nn.Module):
21 | def __init__(self, channels, eps=1e-5):
22 | super().__init__()
23 | self.channels = channels
24 | self.eps = eps
25 |
26 | self.gamma = nn.Parameter(torch.ones(channels))
27 | self.beta = nn.Parameter(torch.zeros(channels))
28 |
29 | def forward(self, x):
30 | x = x.transpose(1, -1)
31 | x = F.layer_norm(x, (self.channels,), self.gamma, self.beta, self.eps)
32 | return x.transpose(1, -1)
33 |
34 |
35 | class ConvReluNorm(nn.Module):
36 | def __init__(self, in_channels, hidden_channels, out_channels, kernel_size, n_layers, p_dropout):
37 | super().__init__()
38 | self.in_channels = in_channels
39 | self.hidden_channels = hidden_channels
40 | self.out_channels = out_channels
41 | self.kernel_size = kernel_size
42 | self.n_layers = n_layers
43 | self.p_dropout = p_dropout
44 | assert n_layers > 1, "Number of layers should be larger than 0."
45 |
46 | self.conv_layers = nn.ModuleList()
47 | self.norm_layers = nn.ModuleList()
48 | self.conv_layers.append(nn.Conv1d(in_channels, hidden_channels, kernel_size, padding=kernel_size//2))
49 | self.norm_layers.append(LayerNorm(hidden_channels))
50 | self.relu_drop = nn.Sequential(
51 | nn.ReLU(),
52 | nn.Dropout(p_dropout))
53 | for _ in range(n_layers-1):
54 | self.conv_layers.append(nn.Conv1d(hidden_channels, hidden_channels, kernel_size, padding=kernel_size//2))
55 | self.norm_layers.append(LayerNorm(hidden_channels))
56 | self.proj = nn.Conv1d(hidden_channels, out_channels, 1)
57 | self.proj.weight.data.zero_()
58 | self.proj.bias.data.zero_()
59 |
60 | def forward(self, x, x_mask):
61 | x_org = x
62 | for i in range(self.n_layers):
63 | x = self.conv_layers[i](x * x_mask)
64 | x = self.norm_layers[i](x)
65 | x = self.relu_drop(x)
66 | x = x_org + self.proj(x)
67 | return x * x_mask
68 |
69 |
70 | class DDSConv(nn.Module):
71 | """
72 | Dialted and Depth-Separable Convolution
73 | """
74 | def __init__(self, channels, kernel_size, n_layers, p_dropout=0.):
75 | super().__init__()
76 | self.channels = channels
77 | self.kernel_size = kernel_size
78 | self.n_layers = n_layers
79 | self.p_dropout = p_dropout
80 |
81 | self.drop = nn.Dropout(p_dropout)
82 | self.convs_sep = nn.ModuleList()
83 | self.convs_1x1 = nn.ModuleList()
84 | self.norms_1 = nn.ModuleList()
85 | self.norms_2 = nn.ModuleList()
86 | for i in range(n_layers):
87 | dilation = kernel_size ** i
88 | padding = (kernel_size * dilation - dilation) // 2
89 | self.convs_sep.append(nn.Conv1d(channels, channels, kernel_size,
90 | groups=channels, dilation=dilation, padding=padding
91 | ))
92 | self.convs_1x1.append(nn.Conv1d(channels, channels, 1))
93 | self.norms_1.append(LayerNorm(channels))
94 | self.norms_2.append(LayerNorm(channels))
95 |
96 | def forward(self, x, x_mask, g=None):
97 | if g is not None:
98 | x = x + g
99 | for i in range(self.n_layers):
100 | y = self.convs_sep[i](x * x_mask)
101 | y = self.norms_1[i](y)
102 | y = F.gelu(y)
103 | y = self.convs_1x1[i](y)
104 | y = self.norms_2[i](y)
105 | y = F.gelu(y)
106 | y = self.drop(y)
107 | x = x + y
108 | return x * x_mask
109 |
110 |
111 | class WN(torch.nn.Module):
112 | def __init__(self, hidden_channels, kernel_size, dilation_rate, n_layers, gin_channels=0, p_dropout=0):
113 | super(WN, self).__init__()
114 | assert(kernel_size % 2 == 1)
115 | self.hidden_channels =hidden_channels
116 | self.kernel_size = kernel_size,
117 | self.dilation_rate = dilation_rate
118 | self.n_layers = n_layers
119 | self.gin_channels = gin_channels
120 | self.p_dropout = p_dropout
121 |
122 | self.in_layers = torch.nn.ModuleList()
123 | self.res_skip_layers = torch.nn.ModuleList()
124 | self.drop = nn.Dropout(p_dropout)
125 |
126 | if gin_channels != 0:
127 | cond_layer = torch.nn.Conv1d(gin_channels, 2*hidden_channels*n_layers, 1)
128 | self.cond_layer = torch.nn.utils.weight_norm(cond_layer, name='weight')
129 |
130 | for i in range(n_layers):
131 | dilation = dilation_rate ** i
132 | padding = int((kernel_size * dilation - dilation) / 2)
133 | in_layer = torch.nn.Conv1d(hidden_channels, 2*hidden_channels, kernel_size,
134 | dilation=dilation, padding=padding)
135 | in_layer = torch.nn.utils.weight_norm(in_layer, name='weight')
136 | self.in_layers.append(in_layer)
137 |
138 | # last one is not necessary
139 | if i < n_layers - 1:
140 | res_skip_channels = 2 * hidden_channels
141 | else:
142 | res_skip_channels = hidden_channels
143 |
144 | res_skip_layer = torch.nn.Conv1d(hidden_channels, res_skip_channels, 1)
145 | res_skip_layer = torch.nn.utils.weight_norm(res_skip_layer, name='weight')
146 | self.res_skip_layers.append(res_skip_layer)
147 |
148 | def forward(self, x, x_mask, g=None, **kwargs):
149 | output = torch.zeros_like(x)
150 | n_channels_tensor = torch.IntTensor([self.hidden_channels])
151 |
152 | if g is not None:
153 | g = self.cond_layer(g)
154 |
155 | for i in range(self.n_layers):
156 | x_in = self.in_layers[i](x)
157 | if g is not None:
158 | cond_offset = i * 2 * self.hidden_channels
159 | g_l = g[:,cond_offset:cond_offset+2*self.hidden_channels,:]
160 | else:
161 | g_l = torch.zeros_like(x_in)
162 |
163 | acts = commons.fused_add_tanh_sigmoid_multiply(
164 | x_in,
165 | g_l,
166 | n_channels_tensor)
167 | acts = self.drop(acts)
168 |
169 | res_skip_acts = self.res_skip_layers[i](acts)
170 | if i < self.n_layers - 1:
171 | res_acts = res_skip_acts[:,:self.hidden_channels,:]
172 | x = (x + res_acts) * x_mask
173 | output = output + res_skip_acts[:,self.hidden_channels:,:]
174 | else:
175 | output = output + res_skip_acts
176 | return output * x_mask
177 |
178 | def remove_weight_norm(self):
179 | if self.gin_channels != 0:
180 | torch.nn.utils.remove_weight_norm(self.cond_layer)
181 | for l in self.in_layers:
182 | torch.nn.utils.remove_weight_norm(l)
183 | for l in self.res_skip_layers:
184 | torch.nn.utils.remove_weight_norm(l)
185 |
186 |
187 | class ResBlock1(torch.nn.Module):
188 | def __init__(self, channels, kernel_size=3, dilation=(1, 3, 5)):
189 | super(ResBlock1, self).__init__()
190 | self.convs1 = nn.ModuleList([
191 | weight_norm(Conv1d(channels, channels, kernel_size, 1, dilation=dilation[0],
192 | padding=get_padding(kernel_size, dilation[0]))),
193 | weight_norm(Conv1d(channels, channels, kernel_size, 1, dilation=dilation[1],
194 | padding=get_padding(kernel_size, dilation[1]))),
195 | weight_norm(Conv1d(channels, channels, kernel_size, 1, dilation=dilation[2],
196 | padding=get_padding(kernel_size, dilation[2])))
197 | ])
198 | self.convs1.apply(init_weights)
199 |
200 | self.convs2 = nn.ModuleList([
201 | weight_norm(Conv1d(channels, channels, kernel_size, 1, dilation=1,
202 | padding=get_padding(kernel_size, 1))),
203 | weight_norm(Conv1d(channels, channels, kernel_size, 1, dilation=1,
204 | padding=get_padding(kernel_size, 1))),
205 | weight_norm(Conv1d(channels, channels, kernel_size, 1, dilation=1,
206 | padding=get_padding(kernel_size, 1)))
207 | ])
208 | self.convs2.apply(init_weights)
209 |
210 | def forward(self, x, x_mask=None):
211 | for c1, c2 in zip(self.convs1, self.convs2):
212 | xt = F.leaky_relu(x, LRELU_SLOPE)
213 | if x_mask is not None:
214 | xt = xt * x_mask
215 | xt = c1(xt)
216 | xt = F.leaky_relu(xt, LRELU_SLOPE)
217 | if x_mask is not None:
218 | xt = xt * x_mask
219 | xt = c2(xt)
220 | x = xt + x
221 | if x_mask is not None:
222 | x = x * x_mask
223 | return x
224 |
225 | def remove_weight_norm(self):
226 | for l in self.convs1:
227 | remove_weight_norm(l)
228 | for l in self.convs2:
229 | remove_weight_norm(l)
230 |
231 |
232 | class ResBlock2(torch.nn.Module):
233 | def __init__(self, channels, kernel_size=3, dilation=(1, 3)):
234 | super(ResBlock2, self).__init__()
235 | self.convs = nn.ModuleList([
236 | weight_norm(Conv1d(channels, channels, kernel_size, 1, dilation=dilation[0],
237 | padding=get_padding(kernel_size, dilation[0]))),
238 | weight_norm(Conv1d(channels, channels, kernel_size, 1, dilation=dilation[1],
239 | padding=get_padding(kernel_size, dilation[1])))
240 | ])
241 | self.convs.apply(init_weights)
242 |
243 | def forward(self, x, x_mask=None):
244 | for c in self.convs:
245 | xt = F.leaky_relu(x, LRELU_SLOPE)
246 | if x_mask is not None:
247 | xt = xt * x_mask
248 | xt = c(xt)
249 | x = xt + x
250 | if x_mask is not None:
251 | x = x * x_mask
252 | return x
253 |
254 | def remove_weight_norm(self):
255 | for l in self.convs:
256 | remove_weight_norm(l)
257 |
258 |
259 | class Log(nn.Module):
260 | def forward(self, x, x_mask, reverse=False, **kwargs):
261 | if not reverse:
262 | y = torch.log(torch.clamp_min(x, 1e-5)) * x_mask
263 | logdet = torch.sum(-y, [1, 2])
264 | return y, logdet
265 | else:
266 | x = torch.exp(x) * x_mask
267 | return x
268 |
269 |
270 | class Flip(nn.Module):
271 | def forward(self, x, *args, reverse=False, **kwargs):
272 | x = torch.flip(x, [1])
273 | if not reverse:
274 | logdet = torch.zeros(x.size(0)).to(dtype=x.dtype, device=x.device)
275 | return x, logdet
276 | else:
277 | return x
278 |
279 |
280 | class ElementwiseAffine(nn.Module):
281 | def __init__(self, channels):
282 | super().__init__()
283 | self.channels = channels
284 | self.m = nn.Parameter(torch.zeros(channels,1))
285 | self.logs = nn.Parameter(torch.zeros(channels,1))
286 |
287 | def forward(self, x, x_mask, reverse=False, **kwargs):
288 | if not reverse:
289 | y = self.m + torch.exp(self.logs) * x
290 | y = y * x_mask
291 | logdet = torch.sum(self.logs * x_mask, [1,2])
292 | return y, logdet
293 | else:
294 | x = (x - self.m) * torch.exp(-self.logs) * x_mask
295 | return x
296 |
297 |
298 | class ResidualCouplingLayer(nn.Module):
299 | def __init__(self,
300 | channels,
301 | hidden_channels,
302 | kernel_size,
303 | dilation_rate,
304 | n_layers,
305 | p_dropout=0,
306 | gin_channels=0,
307 | mean_only=False):
308 | assert channels % 2 == 0, "channels should be divisible by 2"
309 | super().__init__()
310 | self.channels = channels
311 | self.hidden_channels = hidden_channels
312 | self.kernel_size = kernel_size
313 | self.dilation_rate = dilation_rate
314 | self.n_layers = n_layers
315 | self.half_channels = channels // 2
316 | self.mean_only = mean_only
317 |
318 | self.pre = nn.Conv1d(self.half_channels, hidden_channels, 1)
319 | self.enc = WN(hidden_channels, kernel_size, dilation_rate, n_layers, p_dropout=p_dropout, gin_channels=gin_channels)
320 | self.post = nn.Conv1d(hidden_channels, self.half_channels * (2 - mean_only), 1)
321 | self.post.weight.data.zero_()
322 | self.post.bias.data.zero_()
323 |
324 | def forward(self, x, x_mask, g=None, reverse=False):
325 | x0, x1 = torch.split(x, [self.half_channels]*2, 1)
326 | h = self.pre(x0) * x_mask
327 | h = self.enc(h, x_mask, g=g)
328 | stats = self.post(h) * x_mask
329 | if not self.mean_only:
330 | m, logs = torch.split(stats, [self.half_channels]*2, 1)
331 | else:
332 | m = stats
333 | logs = torch.zeros_like(m)
334 |
335 | if not reverse:
336 | x1 = m + x1 * torch.exp(logs) * x_mask
337 | x = torch.cat([x0, x1], 1)
338 | logdet = torch.sum(logs, [1,2])
339 | return x, logdet
340 | else:
341 | x1 = (x1 - m) * torch.exp(-logs) * x_mask
342 | x = torch.cat([x0, x1], 1)
343 | return x
344 |
345 |
346 | class ConvFlow(nn.Module):
347 | def __init__(self, in_channels, filter_channels, kernel_size, n_layers, num_bins=10, tail_bound=5.0):
348 | super().__init__()
349 | self.in_channels = in_channels
350 | self.filter_channels = filter_channels
351 | self.kernel_size = kernel_size
352 | self.n_layers = n_layers
353 | self.num_bins = num_bins
354 | self.tail_bound = tail_bound
355 | self.half_channels = in_channels // 2
356 |
357 | self.pre = nn.Conv1d(self.half_channels, filter_channels, 1)
358 | self.convs = DDSConv(filter_channels, kernel_size, n_layers, p_dropout=0.)
359 | self.proj = nn.Conv1d(filter_channels, self.half_channels * (num_bins * 3 - 1), 1)
360 | self.proj.weight.data.zero_()
361 | self.proj.bias.data.zero_()
362 |
363 | def forward(self, x, x_mask, g=None, reverse=False):
364 | x0, x1 = torch.split(x, [self.half_channels]*2, 1)
365 | h = self.pre(x0)
366 | h = self.convs(h, x_mask, g=g)
367 | h = self.proj(h) * x_mask
368 |
369 | b, c, t = x0.shape
370 | h = h.reshape(b, c, -1, t).permute(0, 1, 3, 2) # [b, cx?, t] -> [b, c, t, ?]
371 |
372 | unnormalized_widths = h[..., :self.num_bins] / math.sqrt(self.filter_channels)
373 | unnormalized_heights = h[..., self.num_bins:2*self.num_bins] / math.sqrt(self.filter_channels)
374 | unnormalized_derivatives = h[..., 2 * self.num_bins:]
375 |
376 | x1, logabsdet = piecewise_rational_quadratic_transform(x1,
377 | unnormalized_widths,
378 | unnormalized_heights,
379 | unnormalized_derivatives,
380 | inverse=reverse,
381 | tails='linear',
382 | tail_bound=self.tail_bound
383 | )
384 |
385 | x = torch.cat([x0, x1], 1) * x_mask
386 | logdet = torch.sum(logabsdet * x_mask, [1,2])
387 | if not reverse:
388 | return x, logdet
389 | else:
390 | return x
391 |
--------------------------------------------------------------------------------
/train_latest.py:
--------------------------------------------------------------------------------
1 | import os
2 | import json
3 | import argparse
4 | import itertools
5 | import math
6 | import torch
7 | from torch import nn, optim
8 | from torch.nn import functional as F
9 | from torch.utils.data import DataLoader
10 | from torch.utils.tensorboard import SummaryWriter
11 | import torch.multiprocessing as mp
12 | import torch.distributed as dist
13 | from torch.nn.parallel import DistributedDataParallel as DDP
14 | from torch.cuda.amp import autocast, GradScaler
15 | from pqmf import PQMF
16 |
17 | import commons
18 | import utils
19 | from data_utils import (
20 | TextAudioLoader,
21 | TextAudioCollate,
22 | DistributedBucketSampler
23 | )
24 | from models import (
25 | SynthesizerTrn,
26 | MultiPeriodDiscriminator,
27 | )
28 | from losses import (
29 | generator_loss,
30 | discriminator_loss,
31 | feature_loss,
32 | kl_loss,
33 | subband_stft_loss
34 | )
35 | from mel_processing import mel_spectrogram_torch, spec_to_mel_torch
36 | from text.symbols import symbols
37 |
38 | torch.autograd.set_detect_anomaly(True)
39 | torch.backends.cudnn.benchmark = True
40 | global_step = 0
41 |
42 | import warnings
43 | warnings.filterwarnings(action='ignore')
44 |
45 | def main():
46 | """Assume Single Node Multi GPUs Training Only"""
47 | assert torch.cuda.is_available(), "CPU training is not allowed."
48 |
49 | n_gpus = torch.cuda.device_count()
50 | os.environ['MASTER_ADDR'] = 'localhost'
51 | os.environ['MASTER_PORT'] = '65520'
52 | # n_gpus = 1
53 |
54 | hps = utils.get_hparams()
55 | #run(rank=0, n_gpus=n_gpus, hps=hps)
56 | mp.spawn(run, nprocs=n_gpus, args=(n_gpus, hps,))
57 |
58 |
59 | def run(rank, n_gpus, hps):
60 | global global_step
61 | if rank == 0:
62 | logger = utils.get_logger(hps.model_dir)
63 | logger.info(hps)
64 | utils.check_git_hash(hps.model_dir)
65 | writer = SummaryWriter(log_dir=hps.model_dir)
66 | writer_eval = SummaryWriter(log_dir=os.path.join(hps.model_dir, "eval"))
67 |
68 | dist.init_process_group(backend='nccl', init_method='env://', world_size=n_gpus, rank=rank) # Linux Only
69 | torch.manual_seed(hps.train.seed)
70 | torch.cuda.set_device(rank)
71 |
72 | train_dataset = TextAudioLoader(hps.data.training_files, hps.data)
73 | train_sampler = DistributedBucketSampler(
74 | train_dataset,
75 | hps.train.batch_size,
76 | [32,300,400,500,600,700,800,900,1000],
77 | num_replicas=n_gpus,
78 | rank=rank,
79 | shuffle=True)
80 | collate_fn = TextAudioCollate()
81 | train_loader = DataLoader(train_dataset, num_workers=24, shuffle=False, pin_memory=True,
82 | collate_fn=collate_fn, batch_sampler=train_sampler)
83 | if rank == 0:
84 | eval_dataset = TextAudioLoader(hps.data.validation_files, hps.data)
85 | eval_loader = DataLoader(eval_dataset, num_workers=8, shuffle=False,
86 | batch_size=hps.train.batch_size, pin_memory=True,
87 | drop_last=False, collate_fn=collate_fn)
88 |
89 | net_g = SynthesizerTrn(
90 | len(symbols),
91 | hps.data.filter_length // 2 + 1,
92 | hps.train.segment_size // hps.data.hop_length,
93 | **hps.model).cuda(rank)
94 | net_d = MultiPeriodDiscriminator(hps.model.use_spectral_norm).cuda(rank)
95 | optim_g = torch.optim.AdamW(
96 | net_g.parameters(),
97 | hps.train.learning_rate,
98 | betas=hps.train.betas,
99 | eps=hps.train.eps)
100 | optim_d = torch.optim.AdamW(
101 | net_d.parameters(),
102 | hps.train.learning_rate,
103 | betas=hps.train.betas,
104 | eps=hps.train.eps)
105 | try:
106 | net_g = utils.load_model_diffsize(os.path.join(hps.train.finetune_model_dir, "G_finetune.pth"), net_g, hps, optim_g)
107 | net_d = utils.load_model_diffsize(os.path.join(hps.train.finetune_model_dir, "D_finetune.pth"), net_d, hps, optim_d)
108 | print("################## FineTuning Mode ##################")
109 | epoch_str = 1
110 | global_step = 0
111 | except:
112 | try:
113 | _, _, _, epoch_str = utils.load_checkpoint(utils.latest_checkpoint_path(hps.model_dir, "G_*.pth"), net_g, optim_g)
114 | _, _, _, epoch_str = utils.load_checkpoint(utils.latest_checkpoint_path(hps.model_dir, "D_*.pth"), net_d, optim_d)
115 | global_step = (epoch_str - 1) * len(train_loader)
116 | print("################## FineTuning Mode ##################")
117 | except:
118 | epoch_str = 1
119 | global_step = 0
120 | print("Train from scratch")
121 |
122 | global_step = (epoch_str - 1) * len(train_loader)
123 |
124 | scheduler_g = torch.optim.lr_scheduler.ExponentialLR(optim_g, gamma=hps.train.lr_decay, last_epoch=epoch_str-2)
125 | scheduler_d = torch.optim.lr_scheduler.ExponentialLR(optim_d, gamma=hps.train.lr_decay, last_epoch=epoch_str-2)
126 |
127 | scaler = GradScaler(enabled=hps.train.fp16_run)
128 |
129 | net_g = DDP(net_g, device_ids=[rank]) # Linux Only
130 | net_d = DDP(net_d, device_ids=[rank]) # Linux Only
131 |
132 | for epoch in range(epoch_str, hps.train.epochs + 1):
133 | if rank==0:
134 | train_and_evaluate(rank, epoch, hps, [net_g, net_d], [optim_g, optim_d], [scheduler_g, scheduler_d], scaler, [train_loader, eval_loader], logger, [writer, writer_eval])
135 | else:
136 | train_and_evaluate(rank, epoch, hps, [net_g, net_d], [optim_g, optim_d], [scheduler_g, scheduler_d], scaler, [train_loader, None], None, None)
137 | scheduler_g.step()
138 | scheduler_d.step()
139 |
140 | # last model is saved
141 | utils.save_checkpoint(net_g, optim_g, hps.train.learning_rate, epoch, os.path.join(hps.model_dir, "G_{}.pth".format(global_step)))
142 | utils.save_checkpoint(net_d, optim_d, hps.train.learning_rate, epoch, os.path.join(hps.model_dir, "D_{}.pth".format(global_step)))
143 |
144 |
145 |
146 | def train_and_evaluate(rank, epoch, hps, nets, optims, schedulers, scaler, loaders, logger, writers):
147 | net_g, net_d = nets
148 | optim_g, optim_d = optims
149 | scheduler_g, scheduler_d = schedulers
150 | train_loader, eval_loader = loaders
151 | if writers is not None:
152 | writer, writer_eval = writers
153 |
154 | train_loader.batch_sampler.set_epoch(epoch)
155 | global global_step
156 |
157 | net_g.train()
158 | net_d.train()
159 | for batch_idx, (x, x_lengths, spec, spec_lengths, y, y_lengths) in enumerate(train_loader):
160 | x, x_lengths = x.cuda(rank, non_blocking=True), x_lengths.cuda(rank, non_blocking=True)
161 | spec, spec_lengths = spec.cuda(rank, non_blocking=True), spec_lengths.cuda(rank, non_blocking=True)
162 | y, y_lengths = y.cuda(rank, non_blocking=True), y_lengths.cuda(rank, non_blocking=True)
163 |
164 | with autocast(enabled=hps.train.fp16_run):
165 | y_hat, y_hat_mb, l_length, attn, ids_slice, x_mask, z_mask,\
166 | (z, z_p, m_p, logs_p, m_q, logs_q), y_hat_last, ids_slice_last= net_g(x, x_lengths, spec, spec_lengths)
167 |
168 | mel = spec_to_mel_torch(
169 | spec,
170 | hps.data.filter_length,
171 | hps.data.n_mel_channels,
172 | hps.data.sampling_rate,
173 | hps.data.mel_fmin,
174 | hps.data.mel_fmax)
175 |
176 | y_mel = commons.slice_segments(mel, ids_slice, hps.train.segment_size // hps.data.hop_length )
177 | #y_mel_last = commons.slice_segments(mel, ids_slice_last, hps.train.segment_size // hps.data.hop_length )
178 |
179 | y_hat_mel = mel_spectrogram_torch(
180 | y_hat.squeeze(1),
181 | hps.data.filter_length,
182 | hps.data.n_mel_channels,
183 | hps.data.sampling_rate,
184 | hps.data.hop_length,
185 | hps.data.win_length,
186 | hps.data.mel_fmin,
187 | hps.data.mel_fmax
188 | )
189 |
190 | """
191 | y_hat_mel_last = mel_spectrogram_torch(
192 | y_hat_last.squeeze(1),
193 | hps.data.filter_length,
194 | hps.data.n_mel_channels,
195 | hps.data.sampling_rate,
196 | hps.data.hop_length,
197 | hps.data.win_length,
198 | hps.data.mel_fmin,
199 | hps.data.mel_fmax
200 | )
201 | """
202 | y = commons.slice_segments(y, ids_slice * hps.data.hop_length, hps.train.segment_size)
203 |
204 | # Discriminator
205 | y_d_hat_r, y_d_hat_g, _, _ = net_d(y, y_hat.detach())
206 | with autocast(enabled=False):
207 | loss_disc, losses_disc_r, losses_disc_g = discriminator_loss(y_d_hat_r, y_d_hat_g)
208 | loss_disc_all = loss_disc
209 | optim_d.zero_grad()
210 | scaler.scale(loss_disc_all).backward()
211 | scaler.unscale_(optim_d)
212 | grad_norm_d = commons.clip_grad_value_(net_d.parameters(), None)
213 | scaler.step(optim_d)
214 |
215 | with autocast(enabled=hps.train.fp16_run):
216 | # Generator
217 | y_d_hat_r, y_d_hat_g, fmap_r, fmap_g = net_d(y, y_hat)
218 | with autocast(enabled=False):
219 |
220 | # Silence用 ノイズ発生を抑える
221 | """
222 | B,M,T = y_hat_mel_last.shape
223 | silence_mel = torch.zeros(size=(B,M), dtype=torch.float32).cuda(rank, non_blocking=True)
224 | loss_silence = torch.nn.functional.l1_loss(y_hat_mel_last[:,:,-1], silence_mel)
225 | """
226 |
227 | loss_dur = torch.sum(l_length.float())
228 | loss_mel = torch.nn.functional.l1_loss(y_mel, y_hat_mel) * hps.train.c_mel
229 | loss_kl = kl_loss(z_p, logs_q, m_p, logs_p, z_mask) * hps.train.c_kl
230 |
231 | loss_fm = feature_loss(fmap_r, fmap_g)
232 | loss_gen, losses_gen = generator_loss(y_d_hat_g)
233 | loss_gen, losses_gen = generator_loss(y_d_hat_g)
234 |
235 | if hps.model.mb_istft_vits == True:
236 | pqmf = PQMF(y.device)
237 | y_mb = pqmf.analysis(y)
238 | loss_subband = subband_stft_loss(hps, y_mb, y_hat_mb)
239 | else:
240 | loss_subband = torch.tensor(0.0)
241 |
242 | loss_gen_all = loss_gen + loss_fm + loss_mel + loss_dur + loss_kl + loss_subband # + loss_silence
243 |
244 | optim_g.zero_grad()
245 | scaler.scale(loss_gen_all).backward()
246 | scaler.unscale_(optim_g)
247 | grad_norm_g = commons.clip_grad_value_(net_g.parameters(), None)
248 | scaler.step(optim_g)
249 | scaler.update()
250 |
251 | # evaluate(hps, net_g, eval_loader, writer_eval)
252 |
253 | if rank==0:
254 | if global_step % hps.train.log_interval == 0:
255 | lr = optim_g.param_groups[0]['lr']
256 | losses = [loss_disc, loss_gen, loss_fm, loss_mel, loss_dur, loss_kl, loss_subband]
257 | logger.info('Train Epoch: {} [{:.0f}%]'.format(
258 | epoch,
259 | 100. * batch_idx / len(train_loader)))
260 | logger.info([x.item() for x in losses] + [global_step, lr])
261 |
262 | scalar_dict = {"loss/g/total": loss_gen_all, "loss/d/total": loss_disc_all, "learning_rate": lr, "grad_norm_d": grad_norm_d, "grad_norm_g": grad_norm_g}
263 | scalar_dict.update({"loss/g/fm": loss_fm, "loss/g/mel": loss_mel, "loss/g/dur": loss_dur, "loss/g/kl": loss_kl, "loss/g/subband": loss_subband})
264 |
265 | scalar_dict.update({"loss/g/{}".format(i): v for i, v in enumerate(losses_gen)})
266 | scalar_dict.update({"loss/d_r/{}".format(i): v for i, v in enumerate(losses_disc_r)})
267 | scalar_dict.update({"loss/d_g/{}".format(i): v for i, v in enumerate(losses_disc_g)})
268 | image_dict = {
269 | "slice/mel_org": utils.plot_spectrogram_to_numpy(y_mel[0].data.cpu().numpy()),
270 | "slice/mel_gen": utils.plot_spectrogram_to_numpy(y_hat_mel[0].data.cpu().numpy()),
271 | "all/mel": utils.plot_spectrogram_to_numpy(mel[0].data.cpu().numpy()),
272 | "all/attn": utils.plot_alignment_to_numpy(attn[0,0].data.cpu().numpy())
273 | }
274 | utils.summarize(
275 | writer=writer,
276 | global_step=global_step,
277 | images=image_dict,
278 | scalars=scalar_dict)
279 |
280 | if global_step % hps.train.eval_interval == 0:
281 | evaluate(hps, net_g, eval_loader, writer_eval)
282 | utils.save_checkpoint(net_g, optim_g, hps.train.learning_rate, epoch, os.path.join(hps.model_dir, "G_{}.pth".format(global_step)))
283 | utils.save_checkpoint(net_d, optim_d, hps.train.learning_rate, epoch, os.path.join(hps.model_dir, "D_{}.pth".format(global_step)))
284 | global_step += 1
285 |
286 |
287 | if rank == 0:
288 | logger.info('====> Epoch: {}'.format(epoch))
289 |
290 |
291 |
292 |
293 | def evaluate(hps, generator, eval_loader, writer_eval):
294 | generator.eval()
295 | with torch.no_grad():
296 | for batch_idx, (x, x_lengths, spec, spec_lengths, y, y_lengths) in enumerate(eval_loader):
297 | x, x_lengths = x.cuda(0), x_lengths.cuda(0)
298 | spec, spec_lengths = spec.cuda(0), spec_lengths.cuda(0)
299 | y, y_lengths = y.cuda(0), y_lengths.cuda(0)
300 |
301 | # remove else
302 | x = x[:1]
303 | x_lengths = x_lengths[:1]
304 | spec = spec[:1]
305 | spec_lengths = spec_lengths[:1]
306 | y = y[:1]
307 | y_lengths = y_lengths[:1]
308 | break
309 | y_hat, y_hat_mb, attn, mask, *_ = generator.module.infer(x, x_lengths, max_len=1000) # Linux
310 | #y_hat, y_hat_mb, attn, mask, *_ = generator.infer(x, x_lengths, max_len=1000)
311 | y_hat_lengths = mask.sum([1,2]).long() * hps.data.hop_length
312 |
313 | mel = spec_to_mel_torch(
314 | spec,
315 | hps.data.filter_length,
316 | hps.data.n_mel_channels,
317 | hps.data.sampling_rate,
318 | hps.data.mel_fmin,
319 | hps.data.mel_fmax)
320 | y_hat_mel = mel_spectrogram_torch(
321 | y_hat.squeeze(1).float(),
322 | hps.data.filter_length,
323 | hps.data.n_mel_channels,
324 | hps.data.sampling_rate,
325 | hps.data.hop_length,
326 | hps.data.win_length,
327 | hps.data.mel_fmin,
328 | hps.data.mel_fmax
329 | )
330 | image_dict = {
331 | "gen/mel": utils.plot_spectrogram_to_numpy(y_hat_mel[0].cpu().numpy())
332 | }
333 | audio_dict = {
334 | "gen/audio": y_hat[0,:,:y_hat_lengths[0]]
335 | }
336 | if global_step == 0:
337 | image_dict.update({"gt/mel": utils.plot_spectrogram_to_numpy(mel[0].cpu().numpy())})
338 | audio_dict.update({"gt/audio": y[0,:,:y_lengths[0]]})
339 |
340 | utils.summarize(
341 | writer=writer_eval,
342 | global_step=global_step,
343 | images=image_dict,
344 | audios=audio_dict,
345 | audio_sampling_rate=hps.data.sampling_rate
346 | )
347 | generator.train()
348 |
349 |
350 | if __name__ == "__main__":
351 |
352 | """
353 | hps = utils.get_hparams()
354 | train_dataset = TextAudioLoader(hps.data.training_files, hps.data)
355 | train_sampler = DistributedBucketSampler(
356 | train_dataset,
357 | 64,
358 | [32,300,400,500,600,700,800,900,1000],
359 | num_replicas=1,
360 | rank=0,
361 | shuffle=True)
362 | collate_fn = TextAudioCollate()
363 | train_loader = DataLoader(train_dataset, num_workers=8, shuffle=False, pin_memory=True,
364 | collate_fn=collate_fn, batch_sampler=train_sampler)
365 |
366 | for data in train_loader:
367 | pass
368 | """
369 | os.environ[
370 | "TORCH_DISTRIBUTED_DEBUG"
371 | ] = "DETAIL"
372 | main()
373 |
--------------------------------------------------------------------------------
/data_utils.py:
--------------------------------------------------------------------------------
1 | import time
2 | import os
3 | import random
4 | import numpy as np
5 | import torch
6 | import torch.utils.data
7 |
8 | import commons
9 | from mel_processing import spectrogram_torch
10 | from utils import load_wav_to_torch, load_filepaths_and_text
11 | from text import text_to_sequence, cleaned_text_to_sequence
12 |
13 |
14 | class TextAudioLoader(torch.utils.data.Dataset):
15 | """
16 | 1) loads audio, text pairs
17 | 2) normalizes text and converts them to sequences of integers
18 | 3) computes spectrograms from audio files.
19 | """
20 | def __init__(self, audiopaths_and_text, hparams):
21 | self.audiopaths_and_text = load_filepaths_and_text(audiopaths_and_text)
22 | self.text_cleaners = hparams.text_cleaners
23 | self.max_wav_value = hparams.max_wav_value
24 | self.sampling_rate = hparams.sampling_rate
25 | self.filter_length = hparams.filter_length
26 | self.hop_length = hparams.hop_length
27 | self.win_length = hparams.win_length
28 | self.sampling_rate = hparams.sampling_rate
29 |
30 | self.cleaned_text = getattr(hparams, "cleaned_text", False)
31 |
32 | self.add_blank = hparams.add_blank
33 | self.min_text_len = getattr(hparams, "min_text_len", 1)
34 | self.max_text_len = getattr(hparams, "max_text_len", 190)
35 |
36 | random.seed(1234)
37 | random.shuffle(self.audiopaths_and_text)
38 | self._filter()
39 |
40 |
41 | def _filter(self):
42 | """
43 | Filter text & store spec lengths
44 | """
45 | # Store spectrogram lengths for Bucketing
46 | # wav_length ~= file_size / (wav_channels * Bytes per dim) = file_size / (1 * 2)
47 | # spec_length = wav_length // hop_length
48 |
49 | audiopaths_and_text_new = []
50 | lengths = []
51 | for audiopath, text in self.audiopaths_and_text:
52 | text = text.split(" ")
53 | if self.min_text_len <= len(text) and len(text) <= self.max_text_len:
54 | audiopaths_and_text_new.append([audiopath, text])
55 | lengths.append(os.path.getsize(audiopath) // (2 * self.hop_length))
56 | self.audiopaths_and_text = audiopaths_and_text_new
57 | self.lengths = lengths
58 |
59 | def get_audio_text_pair(self, audiopath_and_text):
60 | # separate filename and text
61 | audiopath, text = audiopath_and_text[0], audiopath_and_text[1]
62 | text = self.get_text(text)
63 | spec, wav = self.get_audio(audiopath)
64 | return (text, spec, wav)
65 |
66 | def get_audio(self, filename):
67 | #print(filename)
68 | audio, sampling_rate = load_wav_to_torch(filename)
69 | if sampling_rate != self.sampling_rate:
70 | raise ValueError("{} {} SR doesn't match target {} SR".format(
71 | sampling_rate, self.sampling_rate))
72 |
73 | #audio_norm = audio / self.max_wav_value
74 | max_val = torch.max(audio)
75 | min_val = torch.min(audio)
76 | audio_norm = audio
77 |
78 | audio_norm = audio_norm.unsqueeze(0)
79 | spec_filename = filename.replace(".wav", ".spec.pt")
80 | if os.path.exists(spec_filename):
81 | spec = torch.load(spec_filename)
82 | else:
83 | spec = spectrogram_torch(audio_norm, self.filter_length,
84 | self.sampling_rate, self.hop_length, self.win_length,
85 | center=False)
86 | spec = torch.squeeze(spec, 0)
87 | if spec.size(1) == -1:
88 | print("ERROR SPEC")
89 | torch.save(spec, spec_filename)
90 | return spec, audio_norm
91 |
92 | def get_text(self, text):
93 | if self.cleaned_text:
94 | text_norm = cleaned_text_to_sequence(text)
95 | else:
96 | text_norm = text_to_sequence(text, self.text_cleaners)
97 | if self.add_blank:
98 | text_norm = commons.intersperse(text_norm, 0)
99 | text_norm = torch.LongTensor(text_norm)
100 | return text_norm
101 |
102 | def __getitem__(self, index):
103 | return self.get_audio_text_pair(self.audiopaths_and_text[index])
104 |
105 | def __len__(self):
106 | return len(self.audiopaths_and_text)
107 |
108 |
109 | class TextAudioCollate():
110 | """ Zero-pads model inputs and targets
111 | """
112 | def __init__(self, return_ids=False):
113 | self.return_ids = return_ids
114 |
115 | def __call__(self, batch):
116 | """Collate's training batch from normalized text and aduio
117 | PARAMS
118 | ------
119 | batch: [text_normalized, spec_normalized, wav_normalized]
120 | """
121 | # Right zero-pad all one-hot text sequences to max input length
122 | """
123 | try:
124 | _, ids_sorted_decreasing = torch.sort(
125 | torch.LongTensor([x[1].size(1) for x in batch]),
126 | dim=0, descending=True)
127 | except:
128 | print("STOP")
129 |
130 | temp_list=[]
131 | for idx, x in enumerate(batch):
132 | temp = x[1]
133 | temp = temp.size(1)
134 | temp_list.append(temp)
135 | print(idx)
136 | """
137 | _, ids_sorted_decreasing = torch.sort(
138 | torch.LongTensor([x[1].size(1) for x in batch]),
139 | dim=0, descending=True)
140 | max_text_len = max([len(x[0]) for x in batch])
141 | max_spec_len = max([x[1].size(1) for x in batch])
142 | max_wav_len = max([x[2].size(1) for x in batch])
143 |
144 | text_lengths = torch.LongTensor(len(batch))
145 | spec_lengths = torch.LongTensor(len(batch))
146 | wav_lengths = torch.LongTensor(len(batch))
147 |
148 | text_padded = torch.LongTensor(len(batch), max_text_len)
149 | spec_padded = torch.FloatTensor(len(batch), batch[0][1].size(0), max_spec_len)
150 | wav_padded = torch.FloatTensor(len(batch), 1, max_wav_len)
151 | text_padded.zero_()
152 | spec_padded.zero_()
153 | wav_padded.zero_()
154 | for i in range(len(ids_sorted_decreasing)):
155 | row = batch[ids_sorted_decreasing[i]]
156 |
157 | text = row[0]
158 | text_padded[i, :text.size(0)] = text
159 | text_lengths[i] = text.size(0)
160 |
161 | spec = row[1]
162 | spec_padded[i, :, :spec.size(1)] = spec
163 | spec_lengths[i] = spec.size(1)
164 |
165 | wav = row[2]
166 | wav_padded[i, :, :wav.size(1)] = wav
167 | wav_lengths[i] = wav.size(1)
168 |
169 | if self.return_ids:
170 | return text_padded, text_lengths, spec_padded, spec_lengths, wav_padded, wav_lengths, ids_sorted_decreasing
171 | return text_padded, text_lengths, spec_padded, spec_lengths, wav_padded, wav_lengths
172 |
173 |
174 | """Multi speaker version"""
175 | class TextAudioSpeakerLoader(torch.utils.data.Dataset):
176 | """
177 | 1) loads audio, speaker_id, text pairs
178 | 2) normalizes text and converts them to sequences of integers
179 | 3) computes spectrograms from audio files.
180 | """
181 | def __init__(self, audiopaths_sid_text, hparams):
182 | self.audiopaths_sid_text = load_filepaths_and_text(audiopaths_sid_text)
183 | self.text_cleaners = hparams.text_cleaners
184 | self.max_wav_value = hparams.max_wav_value
185 | self.sampling_rate = hparams.sampling_rate
186 | self.filter_length = hparams.filter_length
187 | self.hop_length = hparams.hop_length
188 | self.win_length = hparams.win_length
189 | self.sampling_rate = hparams.sampling_rate
190 |
191 | self.cleaned_text = getattr(hparams, "cleaned_text", False)
192 |
193 | self.add_blank = hparams.add_blank
194 | self.min_text_len = getattr(hparams, "min_text_len", 1)
195 | self.max_text_len = getattr(hparams, "max_text_len", 190)
196 |
197 | random.seed(1234)
198 | random.shuffle(self.audiopaths_sid_text)
199 | self._filter()
200 |
201 | def _filter(self):
202 | """
203 | Filter text & store spec lengths
204 | """
205 | # Store spectrogram lengths for Bucketing
206 | # wav_length ~= file_size / (wav_channels * Bytes per dim) = file_size / (1 * 2)
207 | # spec_length = wav_length // hop_length
208 |
209 | audiopaths_sid_text_new = []
210 | lengths = []
211 | for audiopath, sid, text in self.audiopaths_sid_text:
212 | if self.min_text_len <= len(text) and len(text) <= self.max_text_len:
213 | audiopaths_sid_text_new.append([audiopath, sid, text])
214 | lengths.append(os.path.getsize(audiopath) // (2 * self.hop_length))
215 | self.audiopaths_sid_text = audiopaths_sid_text_new
216 | self.lengths = lengths
217 |
218 | def get_audio_text_speaker_pair(self, audiopath_sid_text):
219 | # separate filename, speaker_id and text
220 | audiopath, sid, text = audiopath_sid_text[0], audiopath_sid_text[1], audiopath_sid_text[2]
221 | text = self.get_text(text)
222 | spec, wav = self.get_audio(audiopath)
223 | sid = self.get_sid(sid)
224 | return (text, spec, wav, sid)
225 |
226 | def get_audio(self, filename):
227 | audio, sampling_rate = load_wav_to_torch(filename)
228 | if sampling_rate != self.sampling_rate:
229 | raise ValueError("{} {} SR doesn't match target {} SR".format(
230 | sampling_rate, self.sampling_rate))
231 | #audio_norm = audio / self.max_wav_value
232 | audio_norm = audio_norm.unsqueeze(0)
233 | spec_filename = filename.replace(".wav", ".spec.pt")
234 | if os.path.exists(spec_filename):
235 | spec = torch.load(spec_filename)
236 | else:
237 | spec = spectrogram_torch(audio_norm, self.filter_length,
238 | self.sampling_rate, self.hop_length, self.win_length,
239 | center=False)
240 | spec = torch.squeeze(spec, 0)
241 | torch.save(spec, spec_filename)
242 |
243 | return spec, audio_norm
244 |
245 | def get_text(self, text):
246 | if self.cleaned_text:
247 | text_norm = cleaned_text_to_sequence(text)
248 | else:
249 | text_norm = text_to_sequence(text, self.text_cleaners)
250 | if self.add_blank:
251 | text_norm = commons.intersperse(text_norm, 0)
252 | text_norm = torch.LongTensor(text_norm)
253 | return text_norm
254 |
255 | def get_sid(self, sid):
256 | sid = torch.LongTensor([int(sid)])
257 | return sid
258 |
259 | def __getitem__(self, index):
260 | return self.get_audio_text_speaker_pair(self.audiopaths_sid_text[index])
261 |
262 | def __len__(self):
263 | return len(self.audiopaths_sid_text)
264 |
265 |
266 | class TextAudioSpeakerCollate():
267 | """ Zero-pads model inputs and targets
268 | """
269 | def __init__(self, return_ids=False):
270 | self.return_ids = return_ids
271 |
272 | def __call__(self, batch):
273 | """Collate's training batch from normalized text, audio and speaker identities
274 | PARAMS
275 | ------
276 | batch: [text_normalized, spec_normalized, wav_normalized, sid]
277 | """
278 | # Right zero-pad all one-hot text sequences to max input length
279 | _, ids_sorted_decreasing = torch.sort(
280 | torch.LongTensor([x[1].size(1) for x in batch]),
281 | dim=0, descending=True)
282 |
283 | max_text_len = max([len(x[0]) for x in batch])
284 | max_spec_len = max([x[1].size(1) for x in batch])
285 | max_wav_len = max([x[2].size(1) for x in batch])
286 |
287 | text_lengths = torch.LongTensor(len(batch))
288 | spec_lengths = torch.LongTensor(len(batch))
289 | wav_lengths = torch.LongTensor(len(batch))
290 | sid = torch.LongTensor(len(batch))
291 |
292 | text_padded = torch.LongTensor(len(batch), max_text_len)
293 | spec_padded = torch.FloatTensor(len(batch), batch[0][1].size(0), max_spec_len)
294 | wav_padded = torch.FloatTensor(len(batch), 1, max_wav_len)
295 | text_padded.zero_()
296 | spec_padded.zero_()
297 | wav_padded.zero_()
298 | for i in range(len(ids_sorted_decreasing)):
299 | row = batch[ids_sorted_decreasing[i]]
300 |
301 | text = row[0]
302 | text_padded[i, :text.size(0)] = text
303 | text_lengths[i] = text.size(0)
304 |
305 | spec = row[1]
306 | spec_padded[i, :, :spec.size(1)] = spec
307 | spec_lengths[i] = spec.size(1)
308 |
309 | wav = row[2]
310 | wav_padded[i, :, :wav.size(1)] = wav
311 | wav_lengths[i] = wav.size(1)
312 |
313 | sid[i] = row[3]
314 |
315 | if self.return_ids:
316 | return text_padded, text_lengths, spec_padded, spec_lengths, wav_padded, wav_lengths, sid, ids_sorted_decreasing
317 | return text_padded, text_lengths, spec_padded, spec_lengths, wav_padded, wav_lengths, sid
318 |
319 |
320 | class DistributedBucketSampler(torch.utils.data.distributed.DistributedSampler):
321 | """
322 | Maintain similar input lengths in a batch.
323 | Length groups are specified by boundaries.
324 | Ex) boundaries = [b1, b2, b3] -> any batch is included either {x | b1 < length(x) <=b2} or {x | b2 < length(x) <= b3}.
325 |
326 | It removes samples which are not included in the boundaries.
327 | Ex) boundaries = [b1, b2, b3] -> any x s.t. length(x) <= b1 or length(x) > b3 are discarded.
328 | """
329 | def __init__(self, dataset, batch_size, boundaries, num_replicas=None, rank=None, shuffle=True):
330 | super().__init__(dataset, num_replicas=num_replicas, rank=rank, shuffle=shuffle)
331 | self.lengths = dataset.lengths
332 | self.batch_size = batch_size
333 | self.boundaries = boundaries
334 |
335 | self.buckets, self.num_samples_per_bucket = self._create_buckets()
336 | self.total_size = sum(self.num_samples_per_bucket)
337 | self.num_samples = self.total_size // self.num_replicas
338 |
339 | def _create_buckets(self):
340 | buckets = [[] for _ in range(len(self.boundaries) - 1)]
341 | for i in range(len(self.lengths)):
342 | length = self.lengths[i]
343 | idx_bucket = self._bisect(length)
344 | if idx_bucket != -1:
345 | buckets[idx_bucket].append(i)
346 |
347 | for i in range(len(buckets) - 1, 0, -1):
348 | if len(buckets[i]) == 0:
349 | buckets.pop(i)
350 | self.boundaries.pop(i+1)
351 |
352 | num_samples_per_bucket = []
353 | for i in range(len(buckets)):
354 | len_bucket = len(buckets[i])
355 | total_batch_size = self.num_replicas * self.batch_size
356 | rem = (total_batch_size - (len_bucket % total_batch_size)) % total_batch_size
357 | num_samples_per_bucket.append(len_bucket + rem)
358 | return buckets, num_samples_per_bucket
359 |
360 | def __iter__(self):
361 | # deterministically shuffle based on epoch
362 | g = torch.Generator()
363 | g.manual_seed(self.epoch)
364 |
365 | indices = []
366 | if self.shuffle:
367 | for bucket in self.buckets:
368 | indices.append(torch.randperm(len(bucket), generator=g).tolist())
369 | else:
370 | for bucket in self.buckets:
371 | indices.append(list(range(len(bucket))))
372 |
373 | batches = []
374 | for i in range(len(self.buckets)):
375 | bucket = self.buckets[i]
376 | len_bucket = len(bucket)
377 | ids_bucket = indices[i]
378 | num_samples_bucket = self.num_samples_per_bucket[i]
379 |
380 | # add extra samples to make it evenly divisible
381 | rem = num_samples_bucket - len_bucket
382 | ids_bucket = ids_bucket + ids_bucket * (rem // len_bucket) + ids_bucket[:(rem % len_bucket)]
383 |
384 | # subsample
385 | ids_bucket = ids_bucket[self.rank::self.num_replicas]
386 |
387 | # batching
388 | for j in range(len(ids_bucket) // self.batch_size):
389 | batch = [bucket[idx] for idx in ids_bucket[j*self.batch_size:(j+1)*self.batch_size]]
390 | batches.append(batch)
391 |
392 | if self.shuffle:
393 | batch_ids = torch.randperm(len(batches), generator=g).tolist()
394 | batches = [batches[i] for i in batch_ids]
395 | self.batches = batches
396 |
397 | assert len(self.batches) * self.batch_size == self.num_samples
398 | return iter(self.batches)
399 |
400 | def _bisect(self, x, lo=0, hi=None):
401 | if hi is None:
402 | hi = len(self.boundaries) - 1
403 |
404 | if hi > lo:
405 | mid = (hi + lo) // 2
406 | if self.boundaries[mid] < x and x <= self.boundaries[mid+1]:
407 | return mid
408 | elif x <= self.boundaries[mid]:
409 | return self._bisect(x, lo, mid)
410 | else:
411 | return self._bisect(x, mid + 1, hi)
412 | else:
413 | return -1
414 |
415 | def __len__(self):
416 | return self.num_samples // self.batch_size
417 |
--------------------------------------------------------------------------------
/dataset/ita/transcript_utf8.txt:
--------------------------------------------------------------------------------
1 | RECITATION324_001:女の子がキッキッ嬉しそう。,オンナノコガキッキッウレシソー。
2 | RECITATION324_002:ツァツォに旅行した。,ツァツォニリョコーシタ。
3 | RECITATION324_003:民衆がテュルリー宮殿に侵入した。,ミンシュウガテュルリーキュウデンニシンニュウシタ。
4 | RECITATION324_004:ハイチ共和国でトゥーサンルーヴェルテュールが勝利を収められたのは、実際黄熱病のおかげだった。,ハイチキョーワコクデトゥーサンルーヴェルテュールガショーリヲオサメラレタノワ、ジッサイオーネツビョーノオカゲダッタ。
5 | RECITATION324_005:レジャンドルは民衆をテュルリー宮殿に招いた。,レジャンドルワミンシュウヲテュルリーキュウデンニマネータ。
6 | RECITATION324_006:助言はできないとデュパンは言った。,ジョゲンワデキナイトデュパンワイッタ。
7 | RECITATION324_007:フランス人シェフと日本人シェフは全然違う。,フランスジンシェフトニホンジンシェフワゼンゼンチガウ。
8 | RECITATION324_008:中国の外交団にアタッシェとして派遣された。,チュウゴクノガイコーダンニアタッシェトシテハケンサレタ。
9 | RECITATION324_009:ファシズム勢力との総力戦に臨む。,ファシズムセーリョクトノソーリョクセンニノゾム。
10 | RECITATION324_010:家具商人のフィシェルは、荷車と仔馬を貸してくれた。,カグショーニンノフィシェルワ、ニグルマトコウマヲカシテクレタ。
11 | RECITATION324_011:ローカル路線にはファンも多い。,ローカルロセンニワファンモオオイ。
12 | RECITATION324_012:フェイントで相手をかわしてからシュートでフィニッシュした。,フェイントデアイテヲカワシテカラシュートデフィニッシュシタ。
13 | RECITATION324_013:1877、プフェファーにより浸透現象が発見された。,センハッピャクナナジュウナナ、プフェファーニヨリシントーゲンショーガハッケンサレタ。
14 | RECITATION324_014:揺れるフェリーに乗るのは私にとって苦行です。,ユレルフェリーニノルノワワタシニトッテクギョーデス。
15 | RECITATION324_015:ホルロ・アラ・ティタルッフォという特別なお料理も出ました。,ホルロアラティタルッフォトユウトクベツナオリョーリモデマシタ。
16 | RECITATION324_016:笛の音がなるとウサギのキッドが早速ぴょんと跳ねた。,フエノオトガナルトウサギノキッドガサッソクピョントハネタ。
17 | RECITATION324_017:あの旅客は噂のキャフェに行くようです。,アノリョキャクワウワサノキャフェニイクヨーデス。
18 | RECITATION324_018:目標は一等賞です。,モクヒョーワイットーショーデス。
19 | RECITATION324_019:ウサギのキッドは気分よくピョン、またピョンと飛び続けた。,ウサギノキッドワキブンヨクピョン、マタピョントトビツヅケタ。
20 | RECITATION324_020:アフタヌーンティーを楽しみましょう。,アフタヌーンティーヲタノシミマショー。
21 | RECITATION324_021:彼女はティピカルなフェミニストです。,カノジョワティピカルナフェミニストデス。
22 | RECITATION324_022:助手たちとミッツィは探している書類を見つけられなかった。,ジョシュタチトミッツィワサガシテイルショルイヲミツケラレナカッタ。
23 | RECITATION324_023:フィレンツェ、パドヴァ、ヴェネツィアはどれもイタリアの都市です。,フィレンツェ、パドヴァ、ヴェネツィアワドレモイタリアノトシデス。
24 | RECITATION324_024:楽譜に次のように書いてあるのが、エーフェリチェです。,ガクフニツギノヨーニカイテアルノガ、エーフェリチェデス。
25 | RECITATION324_025:ショペンハウエルとニーチェの哲学書を本棚から取り出した。,ショペンハウエルトニーチェノテツガクショヲホンダナカラトリダシタ。
26 | RECITATION324_026:早速召使い全員に知らせましょう。,サッソクメシツカイゼンインニシラセマショー。
27 | RECITATION324_027:重い綿入を脱いで、あわせに着替える。,オモイワタイレヲヌイデ、アワセニキガエル。
28 | RECITATION324_028:ボストンで、とあるチョプスイ屋へ入って夕飯を食った。,ボストンデ、トアルチョプスイヤエハイッテユウハンヲクッタ。
29 | RECITATION324_029:ろくすっぽ休憩をとらず働いた。,ロクスッポキュウケーヲトラズハタライタ。
30 | RECITATION324_030:かつて一人で国府に侵入した。,カツテヒトリデコクフニシンニュウシタ。
31 | RECITATION324_031:だが、今日お前がここへ御入来になったのは、どんなご用なのかな?,ダガ、キョーオマエガココエゴジュライニナッタノワ、ドンナゴヨーナノカナ?
32 | RECITATION324_032:サブフランチャイザーを増やして目指せ百店舗。,サブフランチャイザーヲフヤシテメザセヒャクテンポ。
33 | RECITATION324_033:四国でお遍路を行脚しよう。,シコクデオヘンロヲアンギャシヨー。
34 | RECITATION324_034:いつもの通りギャンギャン泣き出しました。,イツモノトオリギャンギャンナキダシマシタ。
35 | RECITATION324_035:先生は、立ったままニュースを見ていました。,センセーワ、タッタママニュースヲミテイマシタ。
36 | RECITATION324_036:私はギョッと目を見開いた。,ワタシワギョットメヲミヒライタ。
37 | RECITATION324_037:友達へニューイヤーカードを送ろう。,トモダチエニューイヤーカードヲオクロー。
38 | RECITATION324_038:家政婦は休みにおしゃれなアウターウェアに身を包み一人で屋台を楽しみました。,カセーフワヤスミニオシャレナアウターウェアニミヲツツミヒトリデヤタイヲタノシミマシタ。
39 | RECITATION324_039:ウォッカのお供には塩漬けのきゅうりがあいます。,ウォッカノオトモニワシオヅケノキュウリガアイマス。
40 | RECITATION324_040:山の向こうのミュンヒェンの人たちが攻撃をしかけた。,ヤマノムコーノミュンヒェンノヒトタチガコーゲキヲシカケタ。
41 | RECITATION324_041:ボスニア国境からの攻撃により、十一月にヴァリェヴォが占領された。,ボスニアコッキョーカラノコーゲキニヨリ、ジュウイチガツニヴァリェヴォガセンリョーサレタ。
42 | RECITATION324_042:シルヴィウスはデュボアと呼ばれていたフランスのユグノーの家に生まれた。,シルヴィウスワデュボアトヨバレテイタフランスノユグノーノイエニウマレタ。
43 | RECITATION324_043:そのほかに私に出来ることはなかったのです、百合枝は涙声になった。,ソノホカニワタシニデキルコトワナカッタノデス、ユリエワナミダゴエニナッタ。
44 | RECITATION324_044:ガル博士百体近く。,ガルハカセヒャクタイチカク。
45 | RECITATION324_045:日本政府からの百兆円を超える予算要求。,ニホンセーフカラノヒャクチョーエンヲコエルヨサンヨーキュウ。
46 | RECITATION324_046:写経の美しさに私は仰天してしまった。,シャキョーノウツクシサニワタシワギョーテンシテシマッタ。
47 | RECITATION324_047:ソプラノ歌手ポリランダチョは歌劇アイーダの特別名歌手と評判です。,ソプラノカシュポリランダチョワカゲキアイーダノトクベツメーカシュトヒョーバンデス。
48 | RECITATION324_048:貴方には最初百ポンド渡します。,アナタニワサイショヒャクポンドワタシマス。
49 | RECITATION324_049:社長からの指示です。,シャチョーカラノシジデス。
50 | RECITATION324_050:どうも気まぐれというものは多少メフィスティックなものであるらしい。,ドーモキマグレトユウモノワタショーメフィスティックナモノデアルラシイ。
51 | RECITATION324_051:蛙がピョコピョコ飛び回っています。,カエルガピョコピョコトビマワッテイマス。
52 | RECITATION324_052:魔境に足を踏み入れる。,マキョーニアシヲフミイレル。
53 | RECITATION324_053:ヴァンダーヴォットタイム中は、いわゆるパーティーのようで晴れやかです。,ヴァンダーヴォットタイムチュウワ、イワユルパーティーノヨーデハレヤカデス。
54 | RECITATION324_054:スピリッツとは蒸留酒の事です。,スピリッツトワジョーリュウシュノコトデス。
55 | RECITATION324_055:ヌルシアのベネディクトゥスはアポロン神殿を壊し、ベネディクト会の修道院を建てた。,ヌルシアノベネディクトゥスワアポロンシンデンヲコワシ、ベネディクトカイノシュウドーインヲタテタ。
56 | RECITATION324_056:ちょうどそのとき、デストゥパーゴがコップをもって立ちあがりました。,チョードソノトキ、デストゥパーゴガコップヲモッテタチアガリマシタ。
57 | RECITATION324_057:パフィーのグッズが残らず部屋に落ち着いた。,パフィーノグッズガノコラズヘヤニオチツイタ。
58 | RECITATION324_058:エピファーノフは財布を無くした。,エピファーノフワサイフヲナクシタ。
59 | RECITATION324_059:ポピュラーなソフトを使いセキュアな状態を復旧する。,ポピュラーナソフトヲツカイセキュアナジョータイヲフッキュウスル。
60 | RECITATION324_060:チョコの在庫あったかな?,チョコノザイコアッタカナ?
61 | RECITATION324_061:おめえ、この仕込みにゃあ、どのくれえ時間かかるか知ってっか。,オメエ、コノシコミニャア、ドノクレエジカンカカルカシッテッカ。
62 | RECITATION324_062:それに、このほうが体のためにゃずっといいんだからね。,ソレニ、コノホーガカラダノタメニャズットイインダカラネ。
63 | RECITATION324_063:夏休みに、トラアヴェミュンへ旅行した。,ナツヤスミニ、トラアヴェミュンエリョコーシタ。
64 | RECITATION324_064:ここで一緒にウェイクフィールドの叔母を待った。,ココデイッショニウェイクフィールドノオバヲマッタ。
65 | RECITATION324_065:八つになるウォルターと一緒に出た兄弟がいたが、ウォルターだけ発見された。,ヤッツニナルウォルタートイッショニデタキョーダイガイタガ、ウォルターダケハッケンサレタ。
66 | RECITATION324_066:最初のジョブはウォーリアがいいと思います。,サイショノジョブワウォーリアガイイトオモイマス。
67 | RECITATION324_067:およそ六百メートル先を右折です。,オヨソロッピャクメートルサキヲウセツデス。
68 | RECITATION324_068:新店オープンのレセプションに沢山のお客さんを招待した。,シンテンオープンノレセプションニタクサンノオキャクサンヲショータイシタ。
69 | RECITATION324_069:脚本作者ピエール・オービュルナンの給仕クレマンが、主人の書斎の戸を大切そうに開いた。,キャクホンサクシャピエールオービュルナンノキュウジクレマンガ、シュジンノショサイノトヲタイセツソーニヒライタ。
70 | RECITATION324_070:われわれは、天主教徒か長老教会派のもので、天主教徒が多数を占めている。,ワレワレワ、テンシュキョートカチョーローキョーカイハノモノデ、テンシュキョートガタスウヲシメテイル。
71 | RECITATION324_071:結局のところお互い五十歩百歩だ。,ケッキョクノトコロオタガイゴジッポヒャッポダ。
72 | RECITATION324_072:突拍子もない話だが、決して嘘ではない。,トッピョーシモナイハナシダガ、ケッシテウソデワナイ。
73 | RECITATION324_073:ネットで懸案の解決を目指す。,ネットデケンアンノカイケツヲメザス。
74 | RECITATION324_074:切れ味鋭いペティナイフは使い勝手が良い。,キレアジスルドイペティナイフワツカイガッテガヨイ。
75 | RECITATION324_075:指をくわえてぴゅーと一声口笛を吹いた。,ユビヲクワエテピュートヒトコエクチブエヲフイタ。
76 | RECITATION324_076:クレンペ教頭は無骨な男だが、自分の学問の秘密には深く浸っていた。,クレンペキョートーワブコツナオトコダガ、ジブンノガクモンノヒミツニワフカクヒタッテイタ。
77 | RECITATION324_077:尻尾ふりたて、ひげくいそらす。,シッポフリタテ、ヒゲクイソラス。
78 | RECITATION324_078:すべての獲物を望みどおりに狙う技術がある。,スベテノエモノヲノゾミドオリニネラウギジュツガアル。
79 | RECITATION324_079:タコのグニャグニャした感触が嫌だ。,タコノグニャグニャシタカンショクガイヤダ。
80 | RECITATION324_080:私たちは、抽象的意識的自己を否定することで、本当の自己とは身心一如だということを知る。,ワタシタチワ、チュウショーテキイシキテキジコヲヒテースルコトデ、ホントーノジコトワシンジンイチニョダトユウコトヲシル。
81 | RECITATION324_081:鹿島明神が釘で刺し貫いて、魚が動かないようにしている。,カシマミョージンガクギデサシツラヌイテ、サカナガウゴカナイヨーニシテイル。
82 | RECITATION324_082:私は手始めに、同業者から話を聞く努力をした。,ワタシワテハジメニ、ドーギョーシャカラハナシヲキクドリョクヲシタ。
83 | RECITATION324_083:とてもうれしそうにぴょんぴょん跳ねて出ていった。,トテモウレシソーニピョンピョンハネテデテイッタ。
84 | RECITATION324_084:二分だけのオルガン演奏で終わってしまった。,ニフンダケノオルガンエンソーデオワッテシマッタ。
85 | RECITATION324_085:ニセ教会に騙されるな。,ニセキョーカイニダマサレルナ。
86 | RECITATION324_086:およそ百年前には、薬剤として薬屋で売っていた。,オヨソヒャクネンマエニワ、ヤクザイトシテクスリヤデウッテイタ。
87 | RECITATION324_087:いっそ脚本家を目指した方がいいかとも考えた。,イッソキャクホンカヲメザシタホーガイイカトモカンガエタ。
88 | RECITATION324_088:この書物に誤謬があっても、純一でない何ものにもインフェクトしないでしょう。,コノショモツニゴビュウガアッテモ、ジュンイツデナイナニモノニモインフェクトシナイデショー。
89 | RECITATION324_089:仏教はインド由来の宗教です。,ブッキョーワインドユライノシュウキョーデス。
90 | RECITATION324_090:キャリーバッグは旅行に必須。,キャリーバッグワリョコーニヒッス。
91 | RECITATION324_091:本番前はメチャメチャ不安になる。,ホンバンマエワメチャメチャフアンニナル。
92 | RECITATION324_092:三角関数においてピュタゴラスの定理は必須です。,サンカクカンスウニオイテピュタゴラスノテーリワヒッスデス。
93 | RECITATION324_093:著名なラニョン博士が患者と接していた。,チョメーナラニョンハカセガカンジャトセッシテイタ。
94 | RECITATION324_094:おもちゃの刀を持った少年が、お百度石に寄りかかっている。,オモチャノカタナヲモッタショーネンガ、オヒャクドイシニヨリカカッテイル。
95 | RECITATION324_095:食料の補給が急務であると伝えられた。,ショクリョーノホキュウガキュウムデアルトツタエラレタ。
96 | RECITATION324_096:展示会であの作品のみ不評だった。,テンジカイデアノサクヒンノミフヒョーダッタ。
97 | RECITATION324_097:客人をもてなすのは当然です。,キャクジンヲモテナスノワトーゼンデス。
98 | RECITATION324_098:旅行客が楽しめるように工夫しましょう。,リョコーキャクガタノシメルヨーニクフウシマショー。
99 | RECITATION324_099:こんな冗談のようなニュースはない。,コンナジョーダンノヨーナニュースワナイ。
100 | RECITATION324_100:小さい星をたくさん描いた、水飲みグラスはよくある。,チイサイホシヲタクサンエガイタ、ミズノミグラスワヨクアル。
101 | RECITATION324_101:柄は、猫の尻尾でもあるように、尖端をぶるぶると震わせながら、動いていく。,エワ、ネコノシッポデモアルヨーニ、センタンヲブルブルトフルワセナガラ、ウゴイテイク。
102 | RECITATION324_102:開店当初プリンが一番売れていた。,カイテントーショプリンガイチバンウレテイタ。
103 | RECITATION324_103:ロナルドホープ大尉が大将のマンションへ急行しました。,ロナルドホープタイイガタイショーノマンションエキュウコーシマシタ。
104 | RECITATION324_104:日刊センティナル紙のヘプバンです。,ニッカンセンティナルシノヘプバンデス。
105 | RECITATION324_105:この宝石は、ひとつ百万円以上のお値段です。,コノホーセキワ、ヒトツヒャクマンエンイジョーノオネダンデス。
106 | RECITATION324_106:チョウチョと仲良くなるんだから。,チョーチョトナカヨクナルンダカラ。
107 | RECITATION324_107:宇宙では、エントロピーは無際限に増大している。,ウチュウデワ、エントロピーワムサイゲンニゾーダイシテイル。
108 | RECITATION324_108:川の中流に集落がある。,カワノチュウリュウニシュウラクガアル。
109 | RECITATION324_109:是非お話させて頂きたいと思います。,ゼヒオハナシサセテイタダキタイトオモイマス。
110 | RECITATION324_110:お隣さんが蒟蒻を持っていらっしゃる。,オトナリサンガコンニャクヲモッテイラッシャル。
111 | RECITATION324_111:パーティーは楽しむものです。,パーティーワタノシムモノデス。
112 | RECITATION324_112:おてつと大きく書かれた番茶茶碗は、これらの人々の前に置かれた。,オテツトオオキクカカレタバンチャジャワンワ、コレラノヒトビトノマエニオカレタ。
113 | RECITATION324_113:私のポケットの中には携帯電話が入っています。,ワタシノポケットノナカニワケータイデンワガハイッテイマス。
114 | RECITATION324_114:彼は今度は牧場へ行って、沼地で小悪魔の尻尾一つ見つけました。,カレワコンドワボクジョーエイッテ、ヌマチデコアクマノシッポヒトツミツケマシタ。
115 | RECITATION324_115:五行説による占いがあるという情報あり。,ゴギョーセツニヨルウラナイガアルトユウジョーホーアリ。
116 | RECITATION324_116:テンプル君、既に真逆だと言った。,テンプルクン、スデニマギャクダトイッタ。
117 | RECITATION324_117:世界中の様々なモニュメントを訪ね歩いた。,セカイジュウノサマザマナモニュメントヲタズネアルイタ。
118 | RECITATION324_118:アンソニー・ホプキンスは有名な俳優です。,アンソニーホプキンスワユウメーナハイユウデス。
119 | RECITATION324_119:彼女は出来るだけぴったりと耳をあてて聴きました。,カノジョワデキルダケピッタリトミミヲアテテキキマシタ。
120 | RECITATION324_120:茶一つ参らぬか、まあいいで。,チャヒトツマイラヌカ、マアイイデ。
121 | RECITATION324_121:ボヤですんでよかった。,ボヤデスンデヨカッタ。
122 | RECITATION324_122:モンタギュ・ゴーシ卿がマンチェスターに来た。,モンタギュゴーシキョーガマンチェスターニキタ。
123 | RECITATION324_123:ウィスキーの水割りをガッツリ飲んだ。,ウィスキーノミズワリヲガッツリノンダ。
124 | RECITATION324_124:これやお祭りを若いものに見せるにゃ持ってこいだ。,コレヤオマツリヲワカイモノニミセルニャモッテコイダ。
125 | RECITATION324_125:私はイメージカラーをピンクに決めた。,ワタシワイメージカラーヲピンクニキメタ。
126 | RECITATION324_126:ムニャムニャ、もう食べれません。,ムニャムニャ、モータベレマセン。
127 | RECITATION324_127:満洲は雨季以外には雨が少ないと言われているが、わたしが満洲にあるあいだは、大戦中のせいか、ずいぶん雨が多かった。,マンシュウワウキイガイニワアメガスクナイトイワレテイルガ、ワタシガマンシュウニアルアイダワ、タイセンチュウノセーカ、ズイブンアメガオオカッタ。
128 | RECITATION324_128:均一居酒屋では一番売れても二人で八千円くらいだ。,キンイツイザカヤデワイチバンウレテモフタリデハッセンエンクライダ。
129 | RECITATION324_129:願いをかなえる。,ネガイヲカナエル。
130 | RECITATION324_130:最初辛かったけど、花や園芸が好きだったから、失意が癒やされないこともない。,サイショツラカッタケド、ハナヤエンゲーガスキダッタカラ、シツイガイヤサレナイコトモナイ。
131 | RECITATION324_131:ペピス爺さんはもう寝るらしい。,ペピスジイサンワモーネルラシイ。
132 | RECITATION324_132:直ぐウィルキンソンを呼びに行け。,スグウィルキンソンヲヨビニイケ。
133 | RECITATION324_133:お昼前ジャスパーさん宅へ再びお邪魔しました。,オヒルマエジャスパーサンタクエフタタビオジャマシマシタ。
134 | RECITATION324_134:その竜の百の頭が恐ろしい。,ソノリュウノヒャクノアタマガオソロシイ。
135 | RECITATION324_135:必要なミョウバンの量はプリントに書いてあります。,ヒツヨーナミョーバンノリョーワプリントニカイテアリマス。
136 | RECITATION324_136:マリー・ロジェはパヴェサンタンの家を出た。,マリーロジェワパヴェサンタンノイエヲデタ。
137 | RECITATION324_137:読み進むにつれ、ますます興味が湧いた。,ヨミススムニツレ、マスマスキョーミガワイタ。
138 | RECITATION324_138:笑いかけながら一二歩近寄った。,ワライカケナガライチニホチカヨッタ。
139 | RECITATION324_139:地表を緑化して、温暖化を抑止する能力を強くする。,チヒョーヲリョクカシテ、オンダンカヲヨクシスルノーリョクヲツヨクスル。
140 | RECITATION324_140:ハサミでプツッと切った切れ端をペットにあげた。,ハサミデプツットキッタキレハシヲペットニアゲタ。
141 | RECITATION324_141:ホームランを打つ。,ホームランヲウツ。
142 | RECITATION324_142:プレゼントをギャロウェイさんに渡してください。,プレゼントヲギャロウェイサンニワタシテクダサイ。
143 | RECITATION324_143:ケプラーの法則について直接私に聞いてきた。,ケプラーノホーソクニツイテチョクセツワタシニキイテキタ。
144 | RECITATION324_144:ウェンディーズはハンバーガー屋さんです。,ウェンディーズワハンバーガーヤサンデス。
145 | RECITATION324_145:しかし氷河はアルプスだけにあるものではない。,シカシヒョーガワアルプスダケニアルモノデワナイ。
146 | RECITATION324_146:この先百年も抹茶は衰退しない。,コノサキヒャクネンモマッチャワスイタイシナイ。
147 | RECITATION324_147:自分を評価するのは会社であって、行き過ぎた自己表現は失脚につながる。,ジブンヲヒョーカスルノワカイシャデアッテ、イキスギタジコヒョーゲンワシッキャクニツナガル。
148 | RECITATION324_148:夜に吹く風のヒュウヒュウという音が私を不安にさせる。,ヨルニフクカゼノヒュウヒュウトユウオトガワタシヲフアンニサセル。
149 | RECITATION324_149:可愛い華奢な女の子。,カワイイキャシャナオンナノコ。
150 | RECITATION324_150:水中の金魚をすくうためのポイ。,スイチュウノキンギョヲスクウタメノポイ。
151 | RECITATION324_151:グレンエルギンはウィスキーの蒸留所です。,グレンエルギンワウィスキーノジョーリュウジョデス。
152 | RECITATION324_152:一寸法師が、ヒョコヒョコと彼の方へ近づいた。,イッスンボーシガ、ヒョコヒョコトカレノホーエチカヅイタ。
153 | RECITATION324_153:連中はリビングでぺちゃくちゃ喋って、警戒していない。,レンチュウワリビングデペチャクチャシャベッテ、ケーカイシテイナイ。
154 | RECITATION324_154:平一郎はシャツ一枚になって絹物の布団の中へ潜りこんだ。,ヘーイチローワシャツイチマイニナッテキヌモノノフトンノナカエモグリコンダ。
155 | RECITATION324_155:下京区に引っ越す。,シモギョークニヒッコス。
156 | RECITATION324_156:彼の言葉に一種不思議な感覚を覚えた。,カレノコトバニイッシュフシギナカンカクヲオボエタ。
157 | RECITATION324_157:この事業所には百人以上の人が勤めています。,コノジギョーショニワヒャクニンイジョーノヒトガツトメテイマス。
158 | RECITATION324_158:わたしの家ばかりでなく、近所の住居といわず、商店といわず、バラックの家々ではみな草花を植えている。,ワタシノイエバカリデナク、キンジョノジュウキョトイワズ、ショーテントイワズ、バラックノイエイエデワミナクサバナヲウエテイル。
159 | RECITATION324_159:どうせ私は馬の世話をせにゃならんから、外へ行こう。,ドーセワタシワウマノセワヲセニャナランカラ、ソトエイコー。
160 | RECITATION324_160:ヤン・セチャンというお笑い芸人。,ヤンセチャントユウオワライゲーニン。
161 | RECITATION324_161:男が妙な顔をして、一瞬残忍になった。,オトコガミョーナカオヲシテ、イッシュンザンニンニナッタ。
162 | RECITATION324_162:普及活動に幻滅した。,フキュウカツドーニゲンメツシタ。
163 | RECITATION324_163:雨がぽつぽつ降りだした。,アメガポツポツフリダシタ。
164 | RECITATION324_164:ペリウィンクルやプランティンはブルーアイです。,ペリウィンクルヤプランティンワブルーアイデス。
165 | RECITATION324_165:姫や侍女たちが、キンポウゲやタンポポの花を持って、彼の方へ駆け寄っていった。,ヒメヤジジョタチガ、キンポーゲヤタンポポノハナヲモッテ、カレノホーエカケヨッテイッタ。
166 | RECITATION324_166:皆の協力のおかげで帰郷できた。,ミンナノキョーリョクノオカゲデキキョーデキタ。
167 | RECITATION324_167:ウォルターとウォードが入室すると、ノラが真っ赤になった。,ウォルタートウォードガニュウシツスルト、ノラガマッカニナッタ。
168 | RECITATION324_168:今の持ち札ではあがれずに終わる。,イマノモチフダデワアガレズニオワル。
169 | RECITATION324_169:勉強中は話しかけないで。,ベンキョーチュウワハナシカケナイデ。
170 | RECITATION324_170:レパードの花壇が枯れ果てた。,レパードノカダンガカレハテタ。
171 | RECITATION324_171:蒸留酒にミョウバンを加える。,ジョーリュウシュニミョーバンヲクワエル。
172 | RECITATION324_172:取っつきにくい女中が三人いる。,トッツキニクイジョチュウガサンニンイル。
173 | RECITATION324_173:レインボーブリッジは東京の名所。,レインボーブリッジワトーキョーノメーショ。
174 | RECITATION324_174:卑怯者は悪党です。,ヒキョーモノワアクトーデス。
175 | RECITATION324_175:突然海へ飛び込んだ。,トツゼンウミエトビコンダ。
176 | RECITATION324_176:仕事はどっさりとあります。,シゴトワドッサリトアリマス。
177 | RECITATION324_177:葉巻パイプはありましたか。,ハマキパイプワアリマシタカ。
178 | RECITATION324_178:八百屋に行って百円で大根を買った。,ヤオヤニイッテヒャクエンデダイコンヲカッタ。
179 | RECITATION324_179:般若とは鬼女の能面の事です。,ハンニャトワキジョノノーメンノコトデス。
180 | RECITATION324_180:日本へ行くには船か飛行機が必要です。,ニホンエイクニワフネカヒコーキガヒツヨーデス。
181 | RECITATION324_181:しかしパーで回るのも難しい。,シカシパーデマワルノモムズカシイ。
182 | RECITATION324_182:のぼせないように入浴するにはお湯の量と温度が大事。,ノボセナイヨーニニュウヨクスルニワオユノリョートオンドガダイジ。
183 | RECITATION324_183:鬼太郎くんは冗談半分で盗みに入って怪我をした。,キタロークンワジョーダンハンブンデヌスミニハイッテケガヲシタ。
184 | RECITATION324_184:バーニ医師がピシッと答えた。,バーニイシガピシットコタエタ。
185 | RECITATION324_185:男の妙な動きが怪しい。,オトコノミョーナウゴキガアヤシイ。
186 | RECITATION324_186:私の病気は先天性なのです。,ワタシノビョーキワセンテンセーナノデス。
187 | RECITATION324_187:三国志の関羽という将軍はすごく有名です。,サンゴクシノカンウトユウショーグンワスゴクユウメーデス。
188 | RECITATION324_188:過酷な業務に耐える。,カコクナギョームニタエル。
189 | RECITATION324_189:町の女房らしい二人連れが、日傘を持って入ってきた。,マチノニョーボーラシイフタリヅレガ、ヒガサヲモッテハイッテキタ。
190 | RECITATION324_190:名をツァウォツキイといった。,ナヲツァウォツキイトイッタ。
191 | RECITATION324_191:飲み会の参加を拒否した。,ノミカイノサンカヲキョヒシタ。
192 | RECITATION324_192:夫人が仰天したのも無理はない。,フジンガギョーテンシタノモムリワナイ。
193 | RECITATION324_193:セファドールはめまいを抑える薬です。,セファドールワメマイヲオサエルクスリデス。
194 | RECITATION324_194:明の一訓詁学者は、宋代典籍の一つにあげてある茶せんの形状を思い起こすに苦しんでいる。,ミンノイチクンコガクシャワ、ソーダイテンセキノヒトツニアゲテアルチャセンノケージョーヲオモイオコスニクルシンデイル。
195 | RECITATION324_195:深海魚は見た目は悪いがおいしいことが多い。,シンカイギョワミタメワワルイガオイシイコトガオオイ。
196 | RECITATION324_196:ニューヨークでイヴニングポストの記事に注目した。,ニューヨークデイヴニングポストノキジニチュウモクシタ。
197 | RECITATION324_197:確かに牛乳とコーンフレークの相性は抜群だ。,タシカニギュウニュウトコーンフレークノアイショーワバツグンダ。
198 | RECITATION324_198:その一は、明治三十七年の九月八日か九日の夜とおぼえている。,ソノイチワ、メージサンジュウナナネンノクガツヨーカカココノカノヨルトオボエテイル。
199 | RECITATION324_199:マルメゾンの店主はジェシーとは仲良しだ。,マルメゾンノテンシュワジェシートワナカヨシダ。
200 | RECITATION324_200:釣竿を肩にかけた処士あり。,ツリザオヲカタニカケタショシアリ。
201 | RECITATION324_201:最新鋭機に乗り込む。,サイシンエーキニノリコム。
202 | RECITATION324_202:誰かが後ろへ来て、変な声で叫んだのでぞっとした。,ダレカガウシロエキテ、ヘンナコエデサケンダノデゾットシタ。
203 | RECITATION324_203:おおでらの石段の前に立ち止まって、その出て来るのを待ちあわせた。,オオデラノイシダンノマエニタチドマッテ、ソノデテクルノヲマチアワセタ。
204 | RECITATION324_204:未解決の懸案を持って重役と対峙する。,ミカイケツノケンアンヲモッテジュウヤクトタイジスル。
205 | RECITATION324_205:薄月の光が庭を照らす。,ウスヅキノヒカリガニワヲテラス。
206 | RECITATION324_206:犯人がどっちの部屋へ入ったかわからない。,ハンニンガドッチノヘヤエハイッタカワカラナイ。
207 | RECITATION324_207:渓谷から出た氷河が一本に合流する。,ケーコクカラデタヒョーガガイッポンニゴーリュウスル。
208 | RECITATION324_208:ディスカッションを進める。,ディスカッションヲススメル。
209 | RECITATION324_209:九頭竜明神を祭るために灯篭をながす。,クズリュウミョージンヲマツルタメニトーローヲナガス。
210 | RECITATION324_210:今回の資料作りは深い思慮を必要としたが、先日やっと終了した。,コンカイノシリョーヅクリワフカイシリョヲヒツヨートシタガ、センジツヤットシュウリョーシタ。
211 | RECITATION324_211:骨子をしっかりと組み立てる。,コッシヲシッカリトクミタテル。
212 | RECITATION324_212:気球にのって空を楽しむ。,キキュウニノッテソラヲタノシム。
213 | RECITATION324_213:批評ばかりでなく対案も出すべき。,ヒヒョーバカリデナクタイアンモダスベキ。
214 | RECITATION324_214:かれらは幕のあいだに木戸の外を散歩しているのである。,カレラワマクノアイダニキドノソトヲサンポシテイルノデアル。
215 | RECITATION324_215:過去の数々の奇病が治るようになりつつある。,カコノカズカズノキビョーガナオルヨーニナリツツアル。
216 | RECITATION324_216:購入者はポンプの修理が必要なことに気がついた。,コーニュウシャワポンプノシュウリガヒツヨーナコトニキガツイタ。
217 | RECITATION324_217:彼自身は、レジ業務につきたいと思っている。,カレジシンワ、レジギョームニツキタイトオモッテイル。
218 | RECITATION324_218:地毛は金色なんです。,ジゲワキンイロナンデス。
219 | RECITATION324_219:鉛筆は折れやすくて不便です。,エンピツワオレヤスクテフベンデス。
220 | RECITATION324_220:ヒポクラテスは医学の父と呼ばれます。,ヒポクラテスワイガクノチチトヨバレマス。
221 | RECITATION324_221:ところが商人は、国ざかいのすぐ近くへ住まって、やはり前と同じようにやっています。,トコロガショーニンワ、クニザカイノスグチカクエスマッテ、ヤハリマエトオナジヨーニヤッテイマス。
222 | RECITATION324_222:今まで明るかった二階の窓は、急にまっくらになってしまいました。,イママデアカルカッタニカイノマドワ、キュウニマックラニナッテシマイマシタ。
223 | RECITATION324_223:アスファルトに囲まれた中にケヤキの木が一本。,アスファルトニカコマレタナカニケヤキノキガイッポン。
224 | RECITATION324_224:名札を用意する。,ナフダヲヨーイスル。
225 | RECITATION324_225:マッチョな男性はモテるそう。,マッチョナダンセーワモテルソー。
226 | RECITATION324_226:社務所の人の話に嘘はなかった。,シャムショノヒトノハナシニウソワナカッタ。
227 | RECITATION324_227:行楽シーズンの京都は人でいっぱい。,コーラクシーズンノキョートワヒトデイッパイ。
228 | RECITATION324_228:どこからかパチパチと音が聞こえる。,ドコカラカパチパチトオトガキコエル。
229 | RECITATION324_229:プロ野球はどのチームが優勝するだろう?,プロヤキュウワドノチームガユウショースルダロー?
230 | RECITATION324_230:しかし、これではまるで私が誘拐しましたと自首して出るようなもので、そんな馬鹿なことをするやつはあるまい。,シカシ、コレデワマルデワタシガユウカイシマシタトジシュシテデルヨーナモノデ、ソンナバカナコトヲスルヤツワアルマイ。
231 | RECITATION324_231:切望しつつ、主を待つ。,セツボーシツツ、ヌシヲマツ。
232 | RECITATION324_232:しばらくしてパチパチという音も止んだ。,シバラクシテパチパチトユウオトモヤンダ。
233 | RECITATION324_233:身分をわきまえず放った狂言。,ミブンヲワキマエズハナッタキョーゲン。
234 | RECITATION324_234:天を翔ける竜の姿は神秘的だ。,テンヲカケルリュウノスガタワシンピテキダ。
235 | RECITATION324_235:私の精神と一脈相通じるものがあると思いました。,ワタシノセーシントイチミャクアイツウジルモノガアルトオモイマシタ。
236 | RECITATION324_236:皆も球場に行きましょう。,ミンナモキュウジョーニイキマショー。
237 | RECITATION324_237:コペルニクスはポーランドの天文学者です。,コペルニクスワポーランドノテンモンガクシャデス。
238 | RECITATION324_238:海沿いの旅館は眺めがいい。,ウミゾイノリョカンワナガメガイイ。
239 | RECITATION324_239:集中すると周りが見えない。,シュウチュウスルトマワリガミエナイ。
240 | RECITATION324_240:春木座は今日の本郷座である。,ハルキザワコンニチノホンゴーザデアル。
241 | RECITATION324_241:私の手を引っ張るようにして、手のひらへくれました。,ワタシノテヲヒッパルヨーニシテ、テノヒラエクレマシタ。
242 | RECITATION324_242:北海の荒波は、その氷の絶壁の根を噛んで、激しく飛沫を散らしている。,ホッカイノアラナミワ、ソノコオリノゼッペキノネヲカンデ、ハゲシクシブキヲチラシテイル。
243 | RECITATION324_243:戦意を喪失させるのが勝利への近道。,センイヲソーシツサセルノガショーリエノチカミチ。
244 | RECITATION324_244:がちょうを飼う。,ガチョーヲカウ。
245 | RECITATION324_245:ふぁふぁと笑いながら楽しく手拍子。,ファファトワライナガラタノシクテビョーシ。
246 | RECITATION324_246:従軍記者は大尉相当の待遇を受ける。,ジュウグンキシャワタイイソートーノタイグウヲウケル。
247 | RECITATION324_247:茶碗にかかるほど、シャツの袖のふくらかなので、掻き抱く体に茶碗を持った。,チャワンニカカルホド、シャツノソデノフクラカナノデ、カキイダクテーニチャワンヲモッタ。
248 | RECITATION324_248:色々隠して今日まで犯人と共にいる。,イロイロカクシテキョーマデハンニントトモニイル。
249 | RECITATION324_249:浦子は寝ながら息を引いた。,ウラコワネナガライキヲヒイタ。
250 | RECITATION324_250:兄が邪険にされた。,アニガジャケンニサレタ。
251 | RECITATION324_251:彼は不服そうに呟いた。,カレワフフクソーニツブヤイタ。
252 | RECITATION324_252:摸造品ばかりでなく、本物のドイツ将校や兵卒のヘルメットを売っているのもある。,モゾーヒンバカリデナク、ホンモノノドイツショーコーヤヘーソツノヘルメットヲウッテイルノモアル。
253 | RECITATION324_253:彼女と一緒にいると落ち着きます。,カノジョトイッショニイルトオチツキマス。
254 | RECITATION324_254:困ってる人に向けて寄付をしました。,コマッテルヒトニムケテキフヲシマシタ。
255 | RECITATION324_255:落ち込んでいるのか、うつむいてじっとしている。,オチコンデイルノカ、ウツムイテジットシテイル。
256 | RECITATION324_256:改良が進むとパンはどんどんおいしくなる。,カイリョーガススムトパンワドンドンオイシクナル。
257 | RECITATION324_257:こんなことを言いながら、気の短いおじいさんは下駄を突っかけて、そそくさと出て行ってしまった。,コンナコトヲイイナガラ、キノミジカイオジイサンワゲタヲツッカケテ、ソソクサトデテイッテシマッタ。
258 | RECITATION324_258:彼女と初デートの今日は夢うつつ。,カノジョトハツデートノキョーワユメウツツ。
259 | RECITATION324_259:おなじ東京の名をよぶにも、今後はおそらく旧東京と新東京とに区別されるであろう。,オナジトーキョーノナヲヨブニモ、コンゴワオソラクキュウトーキョートシントーキョートニクベツサレルデアロー。
260 | RECITATION324_260:腰振りを二分間続ける。,コシフリヲニフンカンツヅケル。
261 | RECITATION324_261:臆病者が逃げ出した。,オクビョーモノガニゲダシタ。
262 | RECITATION324_262:絵葉書と一緒に銀色のルアーをマッシュに送った。,エハガキトイッショニギンイロノルアーヲマッシュニオクッタ。
263 | RECITATION324_263:オムライスにはケチャップが一番。,オムライスニワケチャップガイチバン。
264 | RECITATION324_264:ストレスは適度に発散しましょう。,ストレスワテキドニハッサンシマショー。
265 | RECITATION324_265:この人よりぞ始まりける。,コノヒトヨリゾハジマリケル。
266 | RECITATION324_266:中学生の時、避暑旅行中に体調を崩した。,チュウガクセーノトキ、ヒショリョコーチュウニタイチョーヲクズシタ。
267 | RECITATION324_267:軍医は病院の門に入るのである。,グンイワビョーインノモンニハイルノデアル。
268 | RECITATION324_268:一日中明るい白夜は、一切太陽が沈まないことで起こります。,イチニチジュウアカルイビャクヤワ、イッサイタイヨーガシズマナイコトデオコリマス。
269 | RECITATION324_269:もう、あなたにばかりも精一杯、誰にも見せられます体ではないんです。,モー、アナタニバカリモセーイッパイ、ダレニモミセラレマスカラダデワナインデス。
270 | RECITATION324_270:みんな揃って海に飛び込んだ。,ミンナソロッテウミニトビコンダ。
271 | RECITATION324_271:なんだそりゃ、到底無理なお願いだ。,ナンダソリャ、トーテームリナオネガイダ。
272 | RECITATION324_272:腸チフスは怖い病気。,チョーチフスワコワイビョーキ。
273 | RECITATION324_273:排球はバレーボールの事です。,ハイキュウワバレーボールノコトデス。
274 | RECITATION324_274:マッチを買いに入ったのかな。,マッチヲカイニハイッタノカナ。
275 | RECITATION324_275:盆栽は風情がある。,ボンサイワフゼーガアル。
276 | RECITATION324_276:やがて陪審員は合議をするために法廷を出て行った。,ヤガテバイシンインワゴーギヲスルタメニホーテーヲデテイッタ。
277 | RECITATION324_277:芸術の求める永遠性に疑問を感じる。,ゲージュツノモトメルエーエンセーニギモンヲカンジル。
278 | RECITATION324_278:聞きつけて、件の嫗、ぶるぶるとかぶりをふった。,キキツケテ、クダンノオーナ、ブルブルトカブリヲフッタ。
279 | RECITATION324_279:キェルツェを通ってドビェに、ザリピェからミェイに行く。,キェルツェヲトオッテドビェニ、ザリピェカラミェイニイク。
280 | RECITATION324_280:マリアーンスケー・ラーズニェを訪れる。,マリアーンスケーラーズニェヲオトズレル。
281 | RECITATION324_281:乳牛を見ながら、レテュの入ったピッツァを食べる。,ニュウギュウヲミナガラ、レテュノハイッタピッツァヲタベル。
282 | RECITATION324_282:ウドゥの奏者を施療した。,ウドゥノソーシャヲセリョーシタ。
283 | RECITATION324_283:インスティテュートで、リデュースの話と併せて、ルデュックの話も聞いた。,インスティテュートデ、リデュースノハナシトアワセテ、ルデュックノハナシモキイタ。
284 | RECITATION324_284:ギェナーを見てイェーイと叫ぶ。,ギェナーヲミテイェーイトサケブ。
285 | RECITATION324_285:スィーディーを聞きながら、でゃーこんを食べる。,スィーディーヲキキナガラ、デャーコンヲタベル。
286 | RECITATION324_286:テョさんはズィーブラを見た。,テョサンワズィーブラヲミタ。
287 | RECITATION324_287:レヴォリューション。レギュレーション。エデュケーション。,レヴォリューション。レギュレーション。エデュケーション。
288 | RECITATION324_288:ブレンドデョート。ラーテャン。,ブレンドデョート。ラーテャン。
289 | RECITATION324_289:あっあの。いっいえ。えっえぇ。おっおい。んーとね。,アッアノ。イッイエ。エッエェ。オッオイ。ンートネ。
290 | RECITATION324_290:いぶかしげに見上げた雨雲から、琥珀色のドラゴンがギュンと現れた。,イブカシゲニミアゲタアマグモカラ、コハクイロノドラゴンガギュントアラワレタ。
291 | RECITATION324_291:布でギュギュっとヌンチャクを縛る。,ヌノデギュギュットヌンチャクヲシバル。
292 | RECITATION324_292:服を脱ぐが、いつも上下が逆さまだ。,フクヲヌグガ、イツモジョーゲガサカサマダ。
293 | RECITATION324_293:放課後の音楽室で、高音を頑張って出した。,ホーカゴノオンガクシツデ、コーオンヲガンバッテダシタ。
294 | RECITATION324_294:モゴモゴしながら言うギャグは面白くない。,モゴモゴシナガラユウギャグワオモシロクナイ。
295 | RECITATION324_295:海水魚の漁業の一環として、稚魚が育てられている。,カイスイギョノギョギョーノイッカントシテ、チギョガソダテラレテイル。
296 | RECITATION324_296:ムンムンとした熱気に、あの淡水魚もへとへとになっている。,ムンムントシタネッキニ、アノタンスイギョモヘトヘトニナッテイル。
297 | RECITATION324_297:ヘスティア所長は、十二音音楽の作法を知っている。,ヘスティアショチョーワ、ジュウニオンオンガクノサホーヲシッテイル。
298 | RECITATION324_298:主催者は、このフェスのキャパが小さいことを、セシルから聞いた。,シュサイシャワ、コノフェスノキャパガチイサイコトヲ、セシルカラキイタ。
299 | RECITATION324_299:母は、サフランライスと、さつまいもの入ったシチューと、ポトフをハフハフしながら食べた。,ハハワ、サフランライスト、サツマイモノハイッタシチュート、ポトフヲハフハフシナガラタベタ。
300 | RECITATION324_300:そして、左京と千紗はヘファ駅に着いた。,ソシテ、サキョートチサワヘファエキニツイタ。
301 | RECITATION324_301:根本と曽原は主君を批判した。,ネモトトソハラワシュクンヲヒハンシタ。
302 | RECITATION324_302:ケケっと笑いながら、津原はパトカーに乗った。,ケケットワライナガラ、ツハラワパトカーニノッタ。
303 | RECITATION324_303:キュキュッと鳴らした靴でパスを出した。,キュキュットナラシタクツデパスヲダシタ。
304 | RECITATION324_304:ティファニーはパピーにムギュッと抱き着きながら、チュチュッとキスをし、センキュと言った。,ティファニーワパピーニムギュットダキツキナガラ、チュチュットキスヲシ、センキュトイッタ。
305 | RECITATION324_305:その義軍は、一ヘクタールほふく前進をした。,ソノギグンワ、イチヘクタールホフクゼンシンヲシタ。
306 | RECITATION324_306:へへっと、きゃつは媚びへつらった。,ヘヘット、キャツワコビヘツラッタ。
307 | RECITATION324_307:ほとんどの被調査者は、写真を車載した。,ホトンドノヒチョーサシャワ、シャシンヲシャサイシタ。
308 | RECITATION324_308:補佐が、一酸化炭素中毒になるというハプニングは起きなかった。,ホサガ、イッサンカタンソチュウドクニナルトユウハプニングワオキナカッタ。
309 | RECITATION324_309:スチューデントが被災するファクターを、可能な限り取り払う。,スチューデントガヒサイスルファクターヲ、カノーナカギリトリハラウ。
310 | RECITATION324_310:カフェとは、ブレックファストとして、フォカッチャを食べれる場所でもある。,カフェトワ、ブレックファストトシテ、フォカッチャヲタベレルバショデモアル。
311 | RECITATION324_311:普通、初級者では、高音を伸ばすことはできない。,フツウ、ショキュウシャデワ、コーオンヲノバスコトワデキナイ。
312 | RECITATION324_312:彼からしたら、左中間から見る景色は貴重だった。,カレカラシタラ、サチュウカンカラミルケシキワキチョーダッタ。
313 | RECITATION324_313:シェパードと同居中に、フォスターはその格付け表を見た。,シェパードトドーキョチュウニ、フォスターワソノカクヅケヒョーヲミタ。
314 | RECITATION324_314:去々年、虚数とヘ長調について学んだ。,キョキョネン、キョスウトヘチョーチョーニツイテマナンダ。
315 | RECITATION324_315:脚立の上でヒュヒューと風が吹くと、彼は背筋を伸ばした。,キャタツノウエデヒュヒュートカゼガフクト、カレワセスジヲノバシタ。
316 | RECITATION324_316:昼にはペスカトーレを、夜には寿司をパクパク食べた。,ヒルニワペスカトーレヲ、ヨルニワスシヲパクパクタベタ。
317 | RECITATION324_317:ケフィアに関するこの本は、初版では三百部くらいだったが、次から波及的に増加した。,ケフィアニカンスルコノホンワ、ショハンデワサンビャクブクライダッタガ、ツギカラハキュウテキニゾーカシタ。
318 | RECITATION324_318:皮膚が私のフェチである。,ヒフガワタシノフェチデアル。
319 | RECITATION324_319:社販で巨富を築くという、彼の目論見は途中でへし折られた。,シャハンデキョフヲキズクトユウ、カレノモクロミワトチュウデヘシオラレタ。
320 | RECITATION324_320:左表のとおりの支出になることが、ある意味わが社の社風である。,サヒョーノトオリノシシュツニナルコトガ、アルイミワガシャノシャフウデアル。
321 | RECITATION324_321:この古風な酒瓢は故郷のものだ。,コノコフウナシュヒョーワコキョーノモノダ。
322 | RECITATION324_322:そのほつれが腐敗しているというのは、誇張した表現だと思う。,ソノホツレガフハイシテイルトユウノワ、コチョーシタヒョーゲンダトオモウ。
323 | RECITATION324_323:その映画の出演者である彼が、主犯である可能性はフィフティーフィフティーだ。,ソノエーガノシュツエンシャデアルカレガ、シュハンデアルカノーセーワフィフティーフィフティーダ。
324 | RECITATION324_324:チュクンの波長は、パツンと共通している。,チュクンノハチョーワ、パツントキョーツウシテイル。
325 | EMOTION100_001:えっ嘘でしょ。,エッウソデショ。
326 | EMOTION100_002:シュヴァイツァーは見習うべき人間です。,シュヴァイツァーワミナラウベキニンゲンデス。
327 | EMOTION100_003:デーヴィスさんはとても疲れているように見える。,デーヴィスサンワトテモツカレテイルヨーニミエル。
328 | EMOTION100_004:スティーヴはジェーンから手紙をもらった。,スティーヴワジェーンカラテガミヲモラッタ。
329 | EMOTION100_005:彼女はモーツァルトやベートーヴェンといった、古典派の作曲家が好きだ。,カノジョワモーツァルトヤベートーヴェントイッタ、コテンハノサッキョクカガスキダ。
330 | EMOTION100_006:ストラットフォード・オン・エイヴォンは、シェイクスピアの生まれたところですが、毎年多くの観光客が訪れます。,ストラットフォードオンエイヴォンワ、シェイクスピアノウマレタトコロデスガ、マイトシオオクノカンコーキャクガオトズレマス。
331 | EMOTION100_007:彼はピューマを慣らすのに、大いに骨を折った。,カレワピューマヲナラスノニ、オオイニホネヲオッタ。
332 | EMOTION100_008:彼が解雇されるとは妙な話だ。,カレガカイコサレルトワミョーナハナシダ。
333 | EMOTION100_009:クリスはヴァンパイア・ナイトを倒した。,クリスワヴァンパイアナイトヲタオシタ。
334 | EMOTION100_010:彼のあだ名は言い得て妙だよね。,カレノアダナワイイエテミョーダヨネ。
335 | EMOTION100_011:イタリア旅行で彼は、いくつか景勝の地として有名な都市、例えば、ナポリやフィレンツェを訪れた。,イタリアリョコーデカレワ、イクツカケーショーノチトシテユウメーナトシ、タトエバ、ナポリヤフィレンツェヲオトズレタ。
336 | EMOTION100_012:ゼロという概念は、ヒンドゥー文化に由来している。,ゼロトユウガイネンワ、ヒンドゥーブンカニユライシテイル。
337 | EMOTION100_013:そのいたずら娘は何食わぬ顔をした。,ソノイタズラムスメワナニクワヌカオヲシタ。
338 | EMOTION100_014:スミスさん、ピエール・デュボワをご紹介しますわ。私の親友なの。,スミスサン、ピエールデュボワヲゴショーカイシマスワ。ワタシノシンユウナノ。
339 | EMOTION100_015:どーすんの、このお店。完ッ全に閑古鳥が鳴いちゃってるじゃない。,ドースンノ、コノオミセ。カンッゼンニカンコドリガナイチャッテルジャナイ。
340 | EMOTION100_016:頂上に着くと皆でヤッホーと叫んだ。,チョージョーニツクトミンナデヤッホートサケンダ。
341 | EMOTION100_017:あっベルが鳴ってる。,アッベルガナッテル。
342 | EMOTION100_018:彼女は彼にぴょこんとおじぎをした。,カノジョワカレニピョコントオジギヲシタ。
343 | EMOTION100_019:男子生徒のめいめいが、帽子に学校のバッジをつけています。,ダンシセートノメーメーガ、ボーシニガッコーノバッジヲツケテイマス。
344 | EMOTION100_020:ヒューズが飛んだ。,ヒューズガトンダ。
345 | EMOTION100_021:私はポピュラー音楽を聞きたい。,ワタシワポピュラーオンガクヲキキタイ。
346 | EMOTION100_022:猫はにゃーにゃーと鳴く。,ネコワニャーニャートナク。
347 | EMOTION100_023:私の一番上の兄が父の名代としてその会合に出席した。,ワタシノイチバンウエノアニガチチノミョーダイトシテソノカイゴーニシュッセキシタ。
348 | EMOTION100_024:彼は首相にインタビューした。,カレワシュショーニインタビューシタ。
349 | EMOTION100_025:その会社の急速な成長は、その独特な戦略によるものだった。,ソノカイシャノキュウソクナセーチョーワ、ソノドクトクナセンリャクニヨルモノダッタ。
350 | EMOTION100_026:私はいつもミネラルウォーターを持ち歩いています。,ワタシワイツモミネラルウォーターヲモチアルイテイマス。
351 | EMOTION100_027:彼女はハンドバッグを開けて家の鍵を探してみたが、見つからなかった。,カノジョワハンドバッグヲアケテイエノカギヲサガシテミタガ、ミツカラナカッタ。
352 | EMOTION100_028:彼女はスタッフをまとめていけると思いますか?,カノジョワスタッフヲマトメテイケルトオモイマスカ?
353 | EMOTION100_029:牛乳はあなたの体に良いだろう、毎日飲んだほうがいい。,ギュウニュウワアナタノカラダニヨイダロー、マイニチノンダホーガイイ。
354 | EMOTION100_030:あなたは流感になりかけているか、もっと重い病気かもしれません。,アナタワリュウカンニナリカケテイルカ、モットオモイビョーキカモシレマセン。
355 | EMOTION100_031:彼女はその事件を、生き生きとした筆致で描写した。,カノジョワソノジケンヲ、イキイキトシタヒッチデビョーシャシタ。
356 | EMOTION100_032:彼は自らの生涯を、インドでの病人の治療に捧げるつもりだ。,カレワミズカラノショーガイヲ、インドデノビョーニンノチリョーニササゲルツモリダ。
357 | EMOTION100_033:奇妙な男で、彼は人から話し掛けられないと口をきかない。,キミョーナオトコデ、カレワヒトカラハナシカケラレナイトクチヲキカナイ。
358 | EMOTION100_034:我々はその山脈で土着のガイドを雇った。,ワレワレワソノサンミャクデドチャクノガイドヲヤトッタ。
359 | EMOTION100_035:彼女は息子に家で行儀よくするように言った。,カノジョワムスコニイエデギョーギヨクスルヨーニイッタ。
360 | EMOTION100_036:彼はライフルを拾い上げ、それで標的をねらった。,カレワライフルヲヒロイアゲ、ソレデヒョーテキヲネラッタ。
361 | EMOTION100_037:私はこの本に八百円を払った。,ワタシワコノホンニハッピャクエンヲハラッタ。
362 | EMOTION100_038:気分が悪くて入院したが、結果的にはたいしたことはなかった。,キブンガワルクテニュウインシタガ、ケッカテキニワタイシタコトワナカッタ。
363 | EMOTION100_039:アフィ狙いの釣り記事ですね。英語関係のコミュのあちこちにマルチポストしています。,アフィネライノツリキジデスネ。エーゴカンケーノコミュノアチコチニマルチポストシテイマス。
364 | EMOTION100_040:トラベラーズチェックを現金に替えてくれるのはこの窓口ですか?,トラベラーズチェックヲゲンキンニカエテクレルノワコノマドグチデスカ?
365 | EMOTION100_041:本日の映画は、サウンド・オブ・ミュージックでございます。,ホンジツノエーガワ、サウンドオブミュージックデゴザイマス。
366 | EMOTION100_042:概してわれわれ日本人は、外国語を話すのに少し臆病すぎる。,ガイシテワレワレニホンジンワ、ガイコクゴヲハナスノニスコシオクビョースギル。
367 | EMOTION100_043:店の人は私のことを知るようになり、私はいつも同じウェイトレスに応対してもらっていた。,ミセノヒトワワタシノコトヲシルヨーニナリ、ワタシワイツモオナジウェイトレスニオータイシテモラッテイタ。
368 | EMOTION100_044:この丘からは何百万という星が見える。,コノオカカラワナンビャクマントユウホシガミエル。
369 | EMOTION100_045:彼女は大学に入学したら、親から経済的に独立しようと思っていた。,カノジョワダイガクニニュウガクシタラ、オヤカラケーザイテキニドクリツシヨートオモッテイタ。
370 | EMOTION100_046:サブマリンのペリスコープが、水中からにょっきり突き出ていた。,サブマリンノペリスコープガ、スイチュウカラニョッキリツキデテイタ。
371 | EMOTION100_047:別にブルマに特別な関心があるわけじゃない。,ベツニブルマニトクベツナカンシンガアルワケジャナイ。
372 | EMOTION100_048:そういうフェティシズムはないと思う。,ソーユウフェティシズムワナイトオモウ。
373 | EMOTION100_049:ウッド夫人が作ってくれるおいしい田舎風の料理を食べたし、ミルクをたくさん飲みました。,ウッドフジンガツクッテクレルオイシイイナカフウノリョーリヲタベタシ、ミルクヲタクサンノミマシタ。
374 | EMOTION100_050:私の妻が瓶をわってしまったので、台所の床は牛乳だらけになっている。,ワタシノツマガビンヲワッテシマッタノデ、ダイドコロノユカワギュウニュウダラケニナッテイル。
375 | EMOTION100_051:喧嘩をしていた二人の子供は、お互いにしかめっ面をして座っていた。,ケンカヲシテイタフタリノコドモワ、オタガイニシカメッツラヲシテスワッテイタ。
376 | EMOTION100_052:事業を継続しながら、事業が依拠している不動産を、切り売りしていくことなど非現実的なのだ。,ジギョーヲケーゾクシナガラ、ジギョーガイキョシテイルフドーサンヲ、キリウリシテイクコトナドヒゲンジツテキナノダ。
377 | EMOTION100_053:しかしペパーバーグは、そのオウムを研究することによって、動物に対する考え方が変わったと言っている。,シカシペパーバーグワ、ソノオームヲケンキュウスルコトニヨッテ、ドーブツニタイスルカンガエカタガカワッタトイッテイル。
378 | EMOTION100_054:パックマンがある条件を満たすと、追ってくるモンスターを逆襲して食べることができる。,パックマンガアルジョーケンヲミタスト、オッテクルモンスターヲギャクシュウシテタベルコトガデキル。
379 | EMOTION100_055:その数百年後に、フォークが西洋のテーブルに現れることになるが、ただちに受け入れられたわけではなかった。,ソノスウヒャクネンゴニ、フォークガセーヨーノテーブルニアラワレルコトニナルガ、タダチニウケイレラレタワケデワナカッタ。
380 | EMOTION100_056:トップのリーダーは犬の行動学ではアルファと呼ばれ、以下ベータ、ガンマと続きます。,トップノリーダーワイヌノコードーガクデワアルファトヨバレ、イカベータ、ガンマトツヅキマス。
381 | EMOTION100_057:ウィーンまでは歩くとどのくらいかかりますか?,ウィーンマデワアルクトドノクライカカリマスカ?
382 | EMOTION100_058:すみません、この辺に詳しくないんです。,スミマセン、コノヘンニクワシクナインデス。
383 | EMOTION100_059:目標は授業設計をするときの、学生の思考を触発するメディア教材の選択および、活用方法について理解することである。,モクヒョーワジュギョーセッケーヲスルトキノ、ガクセーノシコーヲショクハツスルメディアキョーザイノセンタクオヨビ、カツヨーホーホーニツイテリカイスルコトデアル。
384 | EMOTION100_060:とりあえず店の前、掃除しといてくれ。打ち水も頼む。,トリアエズミセノマエ、ソージシトイテクレ。ウチミズモタノム。
385 | EMOTION100_061:人々はトーナメントが始まる何ヶ月も前に、これらの入場券を買う。,ヒトビトワトーナメントガハジマルナンカゲツモマエニ、コレラノニュウジョーケンヲカウ。
386 | EMOTION100_062:彼女の魅力は言葉では表現できない、とその芸術家は叫んだ。,カノジョノミリョクワコトバデワヒョーゲンデキナイ、トソノゲージュツカワサケンダ。
387 | EMOTION100_063:事象として簡単なことを、いかにも難しそうに表現する人は、あまり頭がよさそうではない。,ジショートシテカンタンナコトヲ、イカニモムズカシソーニヒョーゲンスルヒトワ、アマリアタマガヨサソーデワナイ。
388 | EMOTION100_064:デザインも、アーチ型のロゴデザインにより、現代的で登場感、躍動感あるものに仕上げました。,デザインモ、アーチガタノロゴデザインニヨリ、ゲンダイテキデトージョーカン、ヤクドーカンアルモノニシアゲマシタ。
389 | EMOTION100_065:そんなに慌てて運転して、一体どこへ行こうってんだよ。,ソンナニアワテテウンテンシテ、イッタイドコエイコーッテンダヨ。
390 | EMOTION100_066:時間はあるんだから、安全運転してくれよ。,ジカンワアルンダカラ、アンゼンウンテンシテクレヨ。
391 | EMOTION100_067:ディスプレイはモニタともいい、コンピュータなどの機器から出力される静止画、または動画の映像信号を表示する機器である。,ディスプレイワモニタトモイイ、コンピュータナドノキキカラシュツリョクサレルセーシガ、マタワドーガノエーゾーシンゴーヲヒョージスルキキデアル。
392 | EMOTION100_068:撃ち合いが少し静まったとき、パパが走ってフラットに行って、私たちにサンドイッチを持ってきてくれたわ。,ウチアイガスコシシズマッタトキ、パパガハシッテフラットニイッテ、ワタシタチニサンドイッチヲモッテキテクレタワ。
393 | EMOTION100_069:ギリシャのフットボールの試合では、一方のチームの選手は、相手チームの陣地のラインの向こう側にボールを持ち込もうとしたのです。,ギリシャノフットボールノシアイデワ、イッポーノチームノセンシュワ、アイテチームノジンチノラインノムコーガワニボールヲモチコモートシタノデス。
394 | EMOTION100_070:泳者のシンディー・ニコラスは、へとへとになって泳ぎ切った後、ドーバーでかろうじて陸に上がってきたが、海峡水泳協会のスポークスマンは、彼女がとても元気であると発表した。,エーシャノシンディーニコラスワ、ヘトヘトニナッテオヨギキッタアト、ドーバーデカロージテリクニアガッテキタガ、カイキョースイエーキョーカイノスポークスマンワ、カノジョガトテモゲンキデアルトハッピョーシタ。
395 | EMOTION100_071:若い男女が人里離れた洋館で恐怖の一夜を過ごすという、ホラーの定番スタイルだ。,ワカイダンジョガヒトザトハナレタヨーカンデキョーフノイチヤヲスゴストユウ、ホラーノテーバンスタイルダ。
396 | EMOTION100_072:一つには、西洋人ではない人々が自分たち独自の文化に誇りを持ち始めてきたためと、また一つには、フォークを使わないそれらの地域は最も高い出生率の地域を抱えているという理由から、このことは当たっている。,ヒトツニワ、セーヨージンデワナイヒトビトガジブンタチドクジノブンカニホコリヲモチハジメテキタタメト、マタヒトツニワ、フォークヲツカワナイソレラノチイキワモットモタカイシュッショーリツノチイキヲカカエテイルトユウリユウカラ、コノコトワアタッテイル。
397 | EMOTION100_073:私たちは恐怖の中で生きていて、苦しんでいるの。,ワタシタチワキョーフノナカデイキテイテ、クルシンデイルノ。
398 | EMOTION100_074:太陽も花も楽しめないし、私たちの子供時代も楽しめないのよ。,タイヨーモハナモタノシメナイシ、ワタシタチノコドモジダイモタノシメナイノヨ。
399 | EMOTION100_075:弊社のエンジニアが日本国内で販売されている同様の製品と仕様を比較した結果、非常に競合力があると判断いたしました。,ヘーシャノエンジニアガニホンコクナイデハンバイサレテイルドーヨーノセーヒントシヨーヲヒカクシタケッカ、ヒジョーニキョーゴーリョクガアルトハンダンイタシマシタ。
400 | EMOTION100_076:ノースウエスタン大学の研究者、アイリーン・ペパーバーグは、オウムは人の口まねをするだけでなく言葉の意味を学ぶことができることを発見しつつある。,ノースウエスタンダイガクノケンキュウシャ、アイリーンペパーバーグワ、オームワヒトノクチマネヲスルダケデナクコトバノイミヲマナブコトガデキルコトヲハッケンシツツアル。
401 | EMOTION100_077:名前をテョといいます。,ナマエヲテョトイイマス。
402 | EMOTION100_078:ぴゅうぴゅう風が吹きこんでくる。,ピュウピュウカゼガフキコンデクル。
403 | EMOTION100_079:キェー。ギェー。イェーイ。,キェー。ギェー。イェーイ。
404 | EMOTION100_080:ひぇーん。びぇーん。ぴぇーん。,ヒェーン。ビェーン。ピェーン。
405 | EMOTION100_081:プリミェー。ミェルン。ニェン。,プリミェー。ミェルン。ニェン。
406 | EMOTION100_082:ステューデント。ダブルデュアル。,ステューデント。ダブルデュアル。
407 | EMOTION100_083:エテュード。エデュケーショナル。サブスティテューション。,エテュード。エデュケーショナル。サブスティテューション。
408 | EMOTION100_084:ジャデャクシュ。,ジャデャクシュ。
409 | EMOTION100_085:ブレンドデョート。,ブレンドデョート。
410 | EMOTION100_086:イデュスルファーゼ。,イデュスルファーゼ。
411 | EMOTION100_087:あっあの。,アッアノ。
412 | EMOTION100_088:いっいえ。,イッイエ。
413 | EMOTION100_089:えっえぇ。,エッエェ。
414 | EMOTION100_090:おっおい。,オッオイ。
415 | EMOTION100_091:んーとね。,ンートネ。
416 | EMOTION100_092:アンツィオ。,アンツィオ。
417 | EMOTION100_093:エンツォ。,エンツォ。
418 | EMOTION100_094:カートゥーン。,カートゥーン。
419 | EMOTION100_095:スィーディー。,スィーディー。
420 | EMOTION100_096:ズィーブラ。,ズィーブラ。
421 | EMOTION100_097:デピュティーガバナー。,デピュティーガバナー。
422 | EMOTION100_098:エリュシオン。,エリュシオン。
423 | EMOTION100_099:ガリェント。,ガリェント。
424 | EMOTION100_100:ラーテャン。,ラーテャン。
--------------------------------------------------------------------------------