Upload full repo excluding dump_40, dump_100, precomputed_tokens, precomputed_data
Browse filesThis view is limited to 50 files because it contains too many changes. See raw diff
- .gitattributes +15 -0
- Configs/config.yml +114 -0
- Configs/config_codec.yml +133 -0
- Configs/config_codec_hybrid.yml +118 -0
- Configs/config_codec_hybrid_temporal.yml +110 -0
- Configs/config_codec_mel_speaker.yml +112 -0
- Configs/config_codec_speaker.yml +110 -0
- Configs/config_codec_v2.yml +127 -0
- Configs/config_codec_v3.yml +131 -0
- Configs/config_fsq_flow_convnext.yml +78 -0
- Configs/config_ft.yml +111 -0
- Configs/config_gemma_audio.yml +74 -0
- Configs/config_libritts.yml +113 -0
- Configs/config_predictors_speaker.yml +61 -0
- Configs/config_predictors_speaker_diffusion.yml +60 -0
- Configs/config_predictors_speaker_flow.yml +89 -0
- Configs/config_predictors_speaker_flow_context.yml +103 -0
- Configs/config_predictors_speaker_flow_context_temporal.yml +88 -0
- Configs/config_predictors_streaming_dit.yml +100 -0
- Configs/config_stage2_masked.yml +69 -0
- Data/OOD_texts.txt +3 -0
- Data/add.py +31 -0
- Data/check_list.py +68 -0
- Data/dd.py +123 -0
- Data/del_amp.py +58 -0
- Data/delete_silence.py +22 -0
- Data/fashion.txt +0 -0
- Data/fashion_train.txt +0 -0
- Data/filet_train.py +332 -0
- Data/finalfinal.txt +3 -0
- Data/harry.txt +3 -0
- Data/luf_norm.py +429 -0
- Data/merged_train.txt +0 -0
- Data/merged_train_sorted.txt +0 -0
- Data/merged_train_test.txt +23 -0
- Data/merged_val.txt +106 -0
- Data/normalize_log.csv +3 -0
- Data/syspin.txt +3 -0
- Data/texts/check.py +102 -0
- Data/texts/cor.py +139 -0
- Data/texts/dataset.txt +0 -0
- Data/texts/fin.txt +3 -0
- Data/texts/merge.py +46 -0
- Data/train_3.txt +3 -0
- Data/train_3_filtered.txt +3 -0
- Data/train_3_filtered_1.txt +3 -0
- Data/train_3_filtered_dur.txt +3 -0
- Data/train_3_filtered_dur_fixed.txt +3 -0
- Data/train_3_filtered_dur_fixed_copy.txt +3 -0
- Data/train_3_filtered_dur_fixed_speakers.txt +3 -0
.gitattributes
CHANGED
|
@@ -33,3 +33,18 @@ saved_model/**/* filter=lfs diff=lfs merge=lfs -text
|
|
| 33 |
*.zip filter=lfs diff=lfs merge=lfs -text
|
| 34 |
*.zst filter=lfs diff=lfs merge=lfs -text
|
| 35 |
*tfevents* filter=lfs diff=lfs merge=lfs -text
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 33 |
*.zip filter=lfs diff=lfs merge=lfs -text
|
| 34 |
*.zst filter=lfs diff=lfs merge=lfs -text
|
| 35 |
*tfevents* filter=lfs diff=lfs merge=lfs -text
|
| 36 |
+
Data/OOD_texts.txt filter=lfs diff=lfs merge=lfs -text
|
| 37 |
+
Data/finalfinal.txt filter=lfs diff=lfs merge=lfs -text
|
| 38 |
+
Data/harry.txt filter=lfs diff=lfs merge=lfs -text
|
| 39 |
+
Data/normalize_log.csv filter=lfs diff=lfs merge=lfs -text
|
| 40 |
+
Data/syspin.txt filter=lfs diff=lfs merge=lfs -text
|
| 41 |
+
Data/texts/fin.txt filter=lfs diff=lfs merge=lfs -text
|
| 42 |
+
Data/train_3.txt filter=lfs diff=lfs merge=lfs -text
|
| 43 |
+
Data/train_3_filtered.txt filter=lfs diff=lfs merge=lfs -text
|
| 44 |
+
Data/train_3_filtered_1.txt filter=lfs diff=lfs merge=lfs -text
|
| 45 |
+
Data/train_3_filtered_dur.txt filter=lfs diff=lfs merge=lfs -text
|
| 46 |
+
Data/train_3_filtered_dur_fixed.txt filter=lfs diff=lfs merge=lfs -text
|
| 47 |
+
Data/train_3_filtered_dur_fixed_copy.txt filter=lfs diff=lfs merge=lfs -text
|
| 48 |
+
Data/train_3_filtered_dur_fixed_speakers.txt filter=lfs diff=lfs merge=lfs -text
|
| 49 |
+
infer_outputs/sample_01.wav filter=lfs diff=lfs merge=lfs -text
|
| 50 |
+
infer_outputs/story.wav filter=lfs diff=lfs merge=lfs -text
|
Configs/config.yml
ADDED
|
@@ -0,0 +1,114 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
log_dir: "again_wavlm"
|
| 2 |
+
first_stage_path: ""
|
| 3 |
+
save_freq: 2
|
| 4 |
+
log_interval: 10
|
| 5 |
+
device: "cuda"
|
| 6 |
+
epochs_1st: 150 # number of epochs for first stage training (pre-training)
|
| 7 |
+
epochs_2nd: 100 # number of peochs for second stage training (joint training)
|
| 8 |
+
batch_size: 32
|
| 9 |
+
max_len: 8000 # maximum number of frameSs
|
| 10 |
+
pretrained_model: "again_wavlm/epoch_flow_00108.pth"
|
| 11 |
+
second_stage_load_pretrained: false # set to true if the pre-trained model is for 2nd stage
|
| 12 |
+
load_only_params: false # set to true if do not want to load epoch numbers and optimizer parameters
|
| 13 |
+
|
| 14 |
+
F0_path: "Utils/JDC/epoch_000401_final.pth"
|
| 15 |
+
ASR_config: "Utils/ASR/config.yml"
|
| 16 |
+
ASR_path: "Utils/ASR/epoch_000801.pth"
|
| 17 |
+
PLBERT_dir: 'Utils/PLBERT/'
|
| 18 |
+
|
| 19 |
+
data_params:
|
| 20 |
+
|
| 21 |
+
#train_data: "Data/train_3_filtered_dur_fixed_speakers_test.txt"
|
| 22 |
+
train_data: "Data/train_3_filtered_dur_fixed_speakers_test.txt"
|
| 23 |
+
val_data: "Data/val_3_filtered_fixed_speakers.txt"
|
| 24 |
+
root_path: "../tts_model"
|
| 25 |
+
OOD_data: "Data/OOD_texts.txt"
|
| 26 |
+
min_length: 50 # sample until texts with this size are obtained for OOD texts
|
| 27 |
+
|
| 28 |
+
preprocess_params:
|
| 29 |
+
sr: 44100
|
| 30 |
+
spect_params:
|
| 31 |
+
n_fft: 4096
|
| 32 |
+
win_length: 2400
|
| 33 |
+
hop_length: 600
|
| 34 |
+
|
| 35 |
+
model_params:
|
| 36 |
+
multispeaker: false
|
| 37 |
+
|
| 38 |
+
dim_in: 64
|
| 39 |
+
hidden_dim: 512
|
| 40 |
+
max_conv_dim: 512
|
| 41 |
+
n_layer: 3
|
| 42 |
+
n_mels: 128
|
| 43 |
+
|
| 44 |
+
n_token: 178 # number of phoneme tokens
|
| 45 |
+
max_dur: 75 # maximum duration of a single phoneme
|
| 46 |
+
style_dim: 64 # style vector size
|
| 47 |
+
style_dim_ac: 128 # style vector size
|
| 48 |
+
dropout: 0.1
|
| 49 |
+
|
| 50 |
+
# config for decoder
|
| 51 |
+
decoder:
|
| 52 |
+
type: 'ringformer' # either hifigan or istftnet
|
| 53 |
+
resblock_kernel_sizes: [3,7,11]
|
| 54 |
+
upsample_rates : [12,10]
|
| 55 |
+
upsample_initial_channel: 512
|
| 56 |
+
resblock_dilation_sizes: [[1,3,5], [1,3,5], [1,3,5]]
|
| 57 |
+
upsample_kernel_sizes: [24, 20]
|
| 58 |
+
gen_istft_n_fft: 30
|
| 59 |
+
gen_istft_hop_size: 5
|
| 60 |
+
|
| 61 |
+
# speech language model config
|
| 62 |
+
slm:
|
| 63 |
+
model: 'microsoft/wavlm-base-plus'
|
| 64 |
+
sr: 16000 # sampling rate of SLM
|
| 65 |
+
hidden: 768 # hidden size of SLM
|
| 66 |
+
nlayers: 13 # number of layers of SLM
|
| 67 |
+
initial_channel: 64 # initial channels of SLM discriminator head
|
| 68 |
+
|
| 69 |
+
# style diffusion model config
|
| 70 |
+
diffusion:
|
| 71 |
+
embedding_mask_proba: 0.2
|
| 72 |
+
# transformer config
|
| 73 |
+
transformer:
|
| 74 |
+
num_layers: 4
|
| 75 |
+
num_heads: 4
|
| 76 |
+
head_features: 32
|
| 77 |
+
multiplier: 4
|
| 78 |
+
|
| 79 |
+
# diffusion distribution config
|
| 80 |
+
dist:
|
| 81 |
+
sigma_data: 0.5 # placeholder for estimate_sigma_data set to false
|
| 82 |
+
mean_data: 0.1
|
| 83 |
+
acoustic: 0.46
|
| 84 |
+
prosodic: 0.46
|
| 85 |
+
pitch: 0.46
|
| 86 |
+
|
| 87 |
+
acoustic_mean: 0.4
|
| 88 |
+
prosodic_mean: 0.4
|
| 89 |
+
pitch_mean: 0.4
|
| 90 |
+
estimate_sigma_data: true # estimate sigma_data from the current batch if set to true
|
| 91 |
+
mean: -0.0
|
| 92 |
+
std: 0.3
|
| 93 |
+
|
| 94 |
+
loss_params:
|
| 95 |
+
|
| 96 |
+
lambda_mel: 10. # mel reconstruction loss
|
| 97 |
+
lambda_gen: 1. # generator loss
|
| 98 |
+
lambda_slm: 1. # slm feature matching loss
|
| 99 |
+
TMA_epoch: 10 # TMA starting epoch (1st stage)
|
| 100 |
+
lambda_mag: 0.5
|
| 101 |
+
optimizer_params:
|
| 102 |
+
lr: 0.0001 # general learning rate
|
| 103 |
+
bert_lr: 0.00001 # learning rate for PLBERT
|
| 104 |
+
ft_lr: 0.00002 # learning rate for acoustic modules
|
| 105 |
+
|
| 106 |
+
slmadv_params:
|
| 107 |
+
min_len: 400 # minimum length of samples
|
| 108 |
+
max_len: 600 # maximum length of samples
|
| 109 |
+
batch_percentage: 0.5 # to prevent out of memory, only use half of the original batch size
|
| 110 |
+
iter: 15 # update the discriminator every this iterations of generator update
|
| 111 |
+
thresh: 5 # gradient norm above which the gradient is scaled
|
| 112 |
+
scale: 0.01 # gradient scaling factor for predictors from SLM discriminators
|
| 113 |
+
sig: 1.5 # sigma for differentiable duration modeling
|
| 114 |
+
|
Configs/config_codec.yml
ADDED
|
@@ -0,0 +1,133 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
# Codec Training Configuration
|
| 2 |
+
# ==============================================================================
|
| 3 |
+
# This config is for training the RVQ-VAE codec vocoder
|
| 4 |
+
# Based on config.yml but with codec-specific settings
|
| 5 |
+
# ==============================================================================
|
| 6 |
+
|
| 7 |
+
log_dir: "codec_training"
|
| 8 |
+
save_freq: 2
|
| 9 |
+
log_interval: 10
|
| 10 |
+
device: "cuda"
|
| 11 |
+
|
| 12 |
+
# Training epochs
|
| 13 |
+
epochs_codec: 100
|
| 14 |
+
|
| 15 |
+
batch_size: 5 # Reduced due to additional codec memory
|
| 16 |
+
max_len: 8000
|
| 17 |
+
|
| 18 |
+
# Pretrained models (optional - for warm starting)
|
| 19 |
+
pretrained_model: "codec_training/epoch_codec_00018.pth" # Base model for text/style encoders
|
| 20 |
+
pretrained_codec: "codec_training/epoch_codec_00018.pth" # Set to load a pretrained codec
|
| 21 |
+
|
| 22 |
+
# Quantizer warmup (gradually increase number of quantizers)
|
| 23 |
+
quantizer_warmup_steps: 10000
|
| 24 |
+
min_quantizers: 1
|
| 25 |
+
|
| 26 |
+
# Data
|
| 27 |
+
data_params:
|
| 28 |
+
train_data: "Data/train_3_filtered_dur_fixed_speakers_test.txt"
|
| 29 |
+
val_data: "Data/val_3_filtered_fixed_speakers.txt"
|
| 30 |
+
root_path: "../tts_model"
|
| 31 |
+
OOD_data: "Data/OOD_texts.txt"
|
| 32 |
+
min_length: 50
|
| 33 |
+
|
| 34 |
+
preprocess_params:
|
| 35 |
+
sr: 44100
|
| 36 |
+
spect_params:
|
| 37 |
+
n_fft: 4096
|
| 38 |
+
win_length: 2400
|
| 39 |
+
hop_length: 600
|
| 40 |
+
|
| 41 |
+
# Model parameters
|
| 42 |
+
model_params:
|
| 43 |
+
multispeaker: false
|
| 44 |
+
|
| 45 |
+
dim_in: 64
|
| 46 |
+
hidden_dim: 512
|
| 47 |
+
max_conv_dim: 512
|
| 48 |
+
n_layer: 3
|
| 49 |
+
n_mels: 128
|
| 50 |
+
|
| 51 |
+
n_token: 178
|
| 52 |
+
max_dur: 75
|
| 53 |
+
style_dim: 64
|
| 54 |
+
style_dim_ac: 128
|
| 55 |
+
dropout: 0.1
|
| 56 |
+
|
| 57 |
+
# === CODEC SETTINGS ===
|
| 58 |
+
# Latent dimension for RVQ
|
| 59 |
+
codec_latent_dim: 512
|
| 60 |
+
|
| 61 |
+
# Number of RVQ codebooks (more = higher quality, more tokens)
|
| 62 |
+
num_quantizers: 8
|
| 63 |
+
|
| 64 |
+
# Codebook size (vocabulary size per quantizer)
|
| 65 |
+
codebook_size: 4096
|
| 66 |
+
|
| 67 |
+
# Compression strides (total compression = product)
|
| 68 |
+
# [2, 2, 2] = 8x compression
|
| 69 |
+
codec_strides: [1]
|
| 70 |
+
|
| 71 |
+
# Decoder/Vocoder config
|
| 72 |
+
decoder:
|
| 73 |
+
type: 'ringformer'
|
| 74 |
+
resblock_kernel_sizes: [3, 7, 11]
|
| 75 |
+
upsample_rates: [12, 10]
|
| 76 |
+
upsample_initial_channel: 512
|
| 77 |
+
resblock_dilation_sizes: [[1, 3, 5], [1, 3, 5], [1, 3, 5]]
|
| 78 |
+
upsample_kernel_sizes: [24, 20]
|
| 79 |
+
gen_istft_n_fft: 30
|
| 80 |
+
gen_istft_hop_size: 5
|
| 81 |
+
|
| 82 |
+
# SLM for perceptual loss
|
| 83 |
+
slm:
|
| 84 |
+
model: 'microsoft/wavlm-base-plus'
|
| 85 |
+
sr: 16000
|
| 86 |
+
hidden: 768
|
| 87 |
+
nlayers: 13
|
| 88 |
+
initial_channel: 64
|
| 89 |
+
|
| 90 |
+
# Style diffusion (not used in codec training but needed for model building)
|
| 91 |
+
diffusion:
|
| 92 |
+
embedding_mask_proba: 0.2
|
| 93 |
+
transformer:
|
| 94 |
+
num_layers: 4
|
| 95 |
+
num_heads: 4
|
| 96 |
+
head_features: 32
|
| 97 |
+
multiplier: 4
|
| 98 |
+
dist:
|
| 99 |
+
sigma_data: 0.5
|
| 100 |
+
mean_data: 0.1
|
| 101 |
+
acoustic: 0.46
|
| 102 |
+
prosodic: 0.46
|
| 103 |
+
pitch: 0.46
|
| 104 |
+
acoustic_mean: 0.4
|
| 105 |
+
prosodic_mean: 0.4
|
| 106 |
+
pitch_mean: 0.4
|
| 107 |
+
estimate_sigma_data: true
|
| 108 |
+
mean: -0.0
|
| 109 |
+
std: 0.3
|
| 110 |
+
|
| 111 |
+
# Optimizer
|
| 112 |
+
optimizer_params:
|
| 113 |
+
lr: 1.0e-4
|
| 114 |
+
pct_start: 0.0
|
| 115 |
+
|
| 116 |
+
# Loss weights
|
| 117 |
+
loss_params:
|
| 118 |
+
# Waveform losses
|
| 119 |
+
lambda_mel: 10.0 # Multi-resolution STFT
|
| 120 |
+
lambda_gen: 1.0 # GAN generator loss
|
| 121 |
+
lambda_slm: 1.0 # Speech language model loss
|
| 122 |
+
lambda_mag: 0.5 # Magnitude/phase loss
|
| 123 |
+
|
| 124 |
+
# Codec-specific losses
|
| 125 |
+
lambda_codec: 1.0 # Overall codec loss weight
|
| 126 |
+
lambda_pitch: 1.0 # Pitch reconstruction
|
| 127 |
+
lambda_energy: 1.0 # Energy reconstruction
|
| 128 |
+
lambda_text: 2.0 # Text embedding reconstruction
|
| 129 |
+
lambda_commitment: 0.25 # VQ commitment loss
|
| 130 |
+
lambda_diversity: 0.02 # Codebook diversity regularization
|
| 131 |
+
|
| 132 |
+
# GAN training starts after this epoch
|
| 133 |
+
TMA_epoch: 15
|
Configs/config_codec_hybrid.yml
ADDED
|
@@ -0,0 +1,118 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
# Hybrid Codec Training Configuration
|
| 2 |
+
# ==============================================================================
|
| 3 |
+
# HYBRID APPROACH:
|
| 4 |
+
# - Text stays CONTINUOUS (not quantized) for better intelligibility
|
| 5 |
+
# - Pitch, Energy, Style are QUANTIZED via FSQ for prosodic compression
|
| 6 |
+
# - Everything is downsampled to compressed representation
|
| 7 |
+
# ==============================================================================
|
| 8 |
+
|
| 9 |
+
log_dir: "hybrid_codec_training"
|
| 10 |
+
save_freq: 1
|
| 11 |
+
log_interval: 10
|
| 12 |
+
device: "cuda"
|
| 13 |
+
|
| 14 |
+
# Training epochs
|
| 15 |
+
epochs_codec: 100
|
| 16 |
+
|
| 17 |
+
batch_size: 4
|
| 18 |
+
max_len: 8000
|
| 19 |
+
|
| 20 |
+
# Pretrained models
|
| 21 |
+
pretrained_model: "hybrid_codec_training/epoch_hybrid_codec_00017.pth" # Base model for text/style encoders
|
| 22 |
+
pretrained_hybrid_codec: "hybrid_codec_training/epoch_hybrid_codec_00017.pth" # Set to load a pretrained hybrid codec
|
| 23 |
+
|
| 24 |
+
# Data
|
| 25 |
+
data_params:
|
| 26 |
+
train_data: "Data/train_3_filtered_dur_fixed_speakers_test.txt"
|
| 27 |
+
val_data: "Data/val_3_filtered_fixed_speakers.txt"
|
| 28 |
+
root_path: "../tts_model"
|
| 29 |
+
OOD_data: "Data/OOD_texts.txt"
|
| 30 |
+
min_length: 50
|
| 31 |
+
|
| 32 |
+
preprocess_params:
|
| 33 |
+
sr: 44100
|
| 34 |
+
spect_params:
|
| 35 |
+
n_fft: 4096
|
| 36 |
+
win_length: 2400
|
| 37 |
+
hop_length: 600
|
| 38 |
+
|
| 39 |
+
# Model parameters
|
| 40 |
+
model_params:
|
| 41 |
+
multispeaker: false
|
| 42 |
+
|
| 43 |
+
dim_in: 64
|
| 44 |
+
hidden_dim: 512
|
| 45 |
+
max_conv_dim: 512
|
| 46 |
+
n_layer: 3
|
| 47 |
+
n_mels: 128
|
| 48 |
+
|
| 49 |
+
n_token: 178
|
| 50 |
+
max_dur: 75
|
| 51 |
+
style_dim: 64
|
| 52 |
+
style_dim_ac: 128
|
| 53 |
+
dropout: 0.1
|
| 54 |
+
|
| 55 |
+
# === HYBRID CODEC SETTINGS ===
|
| 56 |
+
# Prosody latent dimension (for pitch/energy/style only)
|
| 57 |
+
# Text goes through separately and stays continuous
|
| 58 |
+
prosody_latent_dim: 256
|
| 59 |
+
|
| 60 |
+
# Hidden dimension for decoder
|
| 61 |
+
codec_hidden_dim: 512
|
| 62 |
+
|
| 63 |
+
# FSQ levels for prosody quantization
|
| 64 |
+
# Product = codebook size (4^6 = 4096 codes)
|
| 65 |
+
# Only prosody is quantized - text stays continuous!
|
| 66 |
+
fsq_levels: [4, 4, 4, 4, 4]
|
| 67 |
+
|
| 68 |
+
# Compression strides (applies to BOTH prosody and text)
|
| 69 |
+
# [2, 2] = 4x compression
|
| 70 |
+
# Text is downsampled but NOT quantized
|
| 71 |
+
codec_strides: [2]
|
| 72 |
+
|
| 73 |
+
# Decoder/Vocoder config
|
| 74 |
+
decoder:
|
| 75 |
+
type: 'ringformer'
|
| 76 |
+
resblock_kernel_sizes: [3, 7, 11]
|
| 77 |
+
upsample_rates: [12, 10] # Product: 480, matches 600 * 4 / 5
|
| 78 |
+
upsample_initial_channel: 512
|
| 79 |
+
resblock_dilation_sizes: [[1, 3, 5], [1, 3, 5], [1, 3, 5]]
|
| 80 |
+
upsample_kernel_sizes: [24,20]
|
| 81 |
+
gen_istft_n_fft: 30
|
| 82 |
+
gen_istft_hop_size: 5
|
| 83 |
+
|
| 84 |
+
# SLM for perceptual loss
|
| 85 |
+
slm:
|
| 86 |
+
model: 'microsoft/wavlm-base-plus'
|
| 87 |
+
sr: 16000
|
| 88 |
+
hidden: 768
|
| 89 |
+
nlayers: 13
|
| 90 |
+
initial_channel: 64
|
| 91 |
+
|
| 92 |
+
# Style diffusion (not used in codec training but needed for model building)
|
| 93 |
+
diffusion:
|
| 94 |
+
embedding_mask_proba: 0.2
|
| 95 |
+
transformer:
|
| 96 |
+
num_layers: 4
|
| 97 |
+
num_heads: 4
|
| 98 |
+
head_features: 32
|
| 99 |
+
multiplier: 4
|
| 100 |
+
dist:
|
| 101 |
+
sigma_data: 0.5
|
| 102 |
+
mean_data: 0.1
|
| 103 |
+
|
| 104 |
+
# Loss weights
|
| 105 |
+
loss_params:
|
| 106 |
+
TMA_epoch: 10
|
| 107 |
+
lambda_mel: 20.0
|
| 108 |
+
lambda_gen: 1.0
|
| 109 |
+
lambda_slm: 1.0
|
| 110 |
+
lambda_mag: 0.2
|
| 111 |
+
lambda_entropy: 50.0 # Increased to encourage codebook utilization
|
| 112 |
+
lambda_f0: 1.0
|
| 113 |
+
lambda_style: 1.0
|
| 114 |
+
|
| 115 |
+
# Optimizer
|
| 116 |
+
optimizer_params:
|
| 117 |
+
lr: 0.0001
|
| 118 |
+
pct_start: 0.0
|
Configs/config_codec_hybrid_temporal.yml
ADDED
|
@@ -0,0 +1,110 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
# Hybrid Codec with WINDOWED Temporal Style Training Configuration
|
| 2 |
+
# ==============================================================================
|
| 3 |
+
# KEY DIFFERENCE:
|
| 4 |
+
# - Style encoder uses large overlapping windows (~3sec) instead of T//16
|
| 5 |
+
# - Captures timbre/speaker characteristics, NOT phoneme-level detail
|
| 6 |
+
# - Output: [B, num_windows, 32] where num_windows depends on audio length
|
| 7 |
+
# - Prevents style encoder from overfitting to phoneme content
|
| 8 |
+
# ==============================================================================
|
| 9 |
+
|
| 10 |
+
log_dir: "hybrid_temporal_codec_training"
|
| 11 |
+
save_freq: 1
|
| 12 |
+
log_interval: 10
|
| 13 |
+
device: "cuda"
|
| 14 |
+
|
| 15 |
+
# Training epochs
|
| 16 |
+
# Pre-TMA: 6 epochs (warmup), TMA: 14 epochs (decay)
|
| 17 |
+
epochs_codec: 20
|
| 18 |
+
|
| 19 |
+
batch_size: 6
|
| 20 |
+
max_len: 7000
|
| 21 |
+
|
| 22 |
+
# n_mels - 40 by default for temporal style encoder
|
| 23 |
+
n_mels: 40
|
| 24 |
+
|
| 25 |
+
# Pretrained models
|
| 26 |
+
pretrained_model: ""
|
| 27 |
+
|
| 28 |
+
# Data
|
| 29 |
+
data_params:
|
| 30 |
+
train_data: "../my_tts_dataset_v2/train_list_filtered_german.txt"
|
| 31 |
+
val_data: "../my_tts_dataset_v2/val_list_filtered_german.txt"
|
| 32 |
+
root_path: "../my_tts_dataset_v2"
|
| 33 |
+
OOD_data: "Data/OOD_texts.txt"
|
| 34 |
+
min_length: 50
|
| 35 |
+
|
| 36 |
+
preprocess_params:
|
| 37 |
+
sr: 44100
|
| 38 |
+
spect_params:
|
| 39 |
+
n_fft: 2048
|
| 40 |
+
win_length: 1764
|
| 41 |
+
hop_length: 441
|
| 42 |
+
|
| 43 |
+
# Model parameters
|
| 44 |
+
model_params:
|
| 45 |
+
multispeaker: false
|
| 46 |
+
|
| 47 |
+
dim_in: 64
|
| 48 |
+
hidden_dim: 512
|
| 49 |
+
max_conv_dim: 512
|
| 50 |
+
n_layer: 3
|
| 51 |
+
n_mels: 40 # 40 mels for temporal style encoder
|
| 52 |
+
|
| 53 |
+
n_token: 176
|
| 54 |
+
max_dur: 75
|
| 55 |
+
style_dim: 32 # Windowed timbre style dimension (spatial)
|
| 56 |
+
style_dim_ac: 128 # Pooled style dimension for comparison
|
| 57 |
+
dropout: 0.1
|
| 58 |
+
|
| 59 |
+
# === HYBRID TEMPORAL CODEC SETTINGS ===
|
| 60 |
+
# Prosody latent dimension
|
| 61 |
+
prosody_latent_dim: 512
|
| 62 |
+
|
| 63 |
+
# Hidden dimension for decoder
|
| 64 |
+
codec_hidden_dim: 512
|
| 65 |
+
|
| 66 |
+
# FSQ levels for prosody quantization
|
| 67 |
+
fsq_levels: [4, 4, 4, 4, 4,4]
|
| 68 |
+
#fsq_levels: [8, 8, 8, 8]
|
| 69 |
+
# Compression strides
|
| 70 |
+
codec_strides: [2]
|
| 71 |
+
|
| 72 |
+
# Decoder/Vocoder config
|
| 73 |
+
decoder:
|
| 74 |
+
type: 'ringformer'
|
| 75 |
+
resblock_kernel_sizes: [3, 7, 11]
|
| 76 |
+
upsample_rates: [7, 7]
|
| 77 |
+
upsample_initial_channel: 512
|
| 78 |
+
resblock_dilation_sizes: [[1, 3, 5], [1, 3, 5], [1, 3, 5]]
|
| 79 |
+
upsample_kernel_sizes: [14,14]
|
| 80 |
+
gen_istft_n_fft: 36
|
| 81 |
+
gen_istft_hop_size: 9
|
| 82 |
+
|
| 83 |
+
# SLM for perceptual loss
|
| 84 |
+
slm:
|
| 85 |
+
model: 'microsoft/wavlm-base-plus'
|
| 86 |
+
sr: 16000
|
| 87 |
+
hidden: 768
|
| 88 |
+
nlayers: 13
|
| 89 |
+
initial_channel: 64
|
| 90 |
+
|
| 91 |
+
|
| 92 |
+
|
| 93 |
+
# Loss weights
|
| 94 |
+
loss_params:
|
| 95 |
+
TMA_epoch: 4 # TMA starts at epoch 4 (after 4 warmup epochs)
|
| 96 |
+
lambda_mel: 10.0
|
| 97 |
+
lambda_gen: 1.0
|
| 98 |
+
lambda_slm: 1.0
|
| 99 |
+
lambda_mag: 0.2
|
| 100 |
+
lambda_entropy: 50.0
|
| 101 |
+
lambda_f0: 1.0
|
| 102 |
+
lambda_style: 2.0
|
| 103 |
+
|
| 104 |
+
# Optimizer with LR scheduling
|
| 105 |
+
# Schedule: decay from 1e-4 to 1e-5 during pre-TMA (epochs 0-6), then constant 1e-5 during TMA (epochs 6-18)
|
| 106 |
+
optimizer_params:
|
| 107 |
+
lr: 1e-5 # Starting learning rate (pre-TMA)
|
| 108 |
+
min_lr: 1e-5 # Final LR (TMA phase, constant)
|
| 109 |
+
decay_epochs: 6 # Decay happens during pre-TMA phase
|
| 110 |
+
pct_start: 0.33 # 6/18 = 0.33 of training is decay phase
|
Configs/config_codec_mel_speaker.yml
ADDED
|
@@ -0,0 +1,112 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
# Mel Speaker Codec Training Configuration
|
| 2 |
+
# ==============================================================================
|
| 3 |
+
# KEY FEATURES:
|
| 4 |
+
# - Input: mel spectrogram + pitch (NO text embeddings, NO energy)
|
| 5 |
+
# - Learnable speaker embeddings: nn.Embedding(num_speakers, speaker_dim)
|
| 6 |
+
# - Speaker conditioning via AdaIN1d throughout decoder
|
| 7 |
+
# - F0 prediction from latent representation
|
| 8 |
+
# - codec_strides=[4] for ~25Hz token rate
|
| 9 |
+
#
|
| 10 |
+
# This codec encodes mel spectrogram and pitch into a latent representation,
|
| 11 |
+
# quantizes it with FSQ, predicts pitch, and decodes to waveform using
|
| 12 |
+
# speaker embeddings for voice identity.
|
| 13 |
+
# ==============================================================================
|
| 14 |
+
|
| 15 |
+
log_dir: "mel_speaker_codec_training"
|
| 16 |
+
save_freq: 1
|
| 17 |
+
log_interval: 10
|
| 18 |
+
device: "cuda"
|
| 19 |
+
|
| 20 |
+
# Training epochs
|
| 21 |
+
epochs_codec: 50
|
| 22 |
+
|
| 23 |
+
batch_size: 8
|
| 24 |
+
max_len: 6000
|
| 25 |
+
|
| 26 |
+
# n_mels - for mel spectrogram input
|
| 27 |
+
n_mels: 100
|
| 28 |
+
|
| 29 |
+
# Dump directory for preprocessed data
|
| 30 |
+
dump_dir: "./dump_100"
|
| 31 |
+
|
| 32 |
+
# Pretrained models
|
| 33 |
+
pretrained_model: "mel_speaker_codec_training/epoch_mel_speaker_codec_00002.pth"
|
| 34 |
+
load_only_params: false
|
| 35 |
+
|
| 36 |
+
# Data
|
| 37 |
+
data_params:
|
| 38 |
+
train_data: "../my_tts_dataset_v2/train_list_filtered_german.txt"
|
| 39 |
+
val_data: "../my_tts_dataset_v2/val_list_filtered_german.txt"
|
| 40 |
+
root_path: "../my_tts_dataset_v2"
|
| 41 |
+
OOD_data: "Data/OOD_texts.txt"
|
| 42 |
+
min_length: 50
|
| 43 |
+
|
| 44 |
+
preprocess_params:
|
| 45 |
+
sr: 44100
|
| 46 |
+
spect_params:
|
| 47 |
+
n_fft: 2048
|
| 48 |
+
win_length: 1764
|
| 49 |
+
hop_length: 441
|
| 50 |
+
|
| 51 |
+
# Model parameters
|
| 52 |
+
model_params:
|
| 53 |
+
# === SPEAKER EMBEDDING SETTINGS ===
|
| 54 |
+
num_speakers: 11 # Number of speakers (IDs 0-10)
|
| 55 |
+
speaker_dim: 64 # Speaker embedding dimension
|
| 56 |
+
|
| 57 |
+
# === MEL INPUT SETTINGS ===
|
| 58 |
+
n_mels: 100 # Mel spectrogram bins
|
| 59 |
+
|
| 60 |
+
# === LATENT/CODEC SETTINGS ===
|
| 61 |
+
latent_dim: 512 # Latent dimension
|
| 62 |
+
hidden_dim: 512 # Hidden dimension for encoder/decoder
|
| 63 |
+
|
| 64 |
+
# FSQ levels for quantization
|
| 65 |
+
fsq_levels: [4, 4, 4, 4, 4, 4] # 4096 codes
|
| 66 |
+
#fsq_levels: [4, 4, 4, 8]
|
| 67 |
+
# Compression strides - 4x for ~25Hz token rate
|
| 68 |
+
# 44100 / 441 / 4 = 25 Hz
|
| 69 |
+
codec_strides: [2]
|
| 70 |
+
|
| 71 |
+
# === PHONEME PREDICTOR SETTINGS ===
|
| 72 |
+
n_phonemes: 176 # Phoneme vocabulary size
|
| 73 |
+
num_languages: 10 # Number of languages for conditioning
|
| 74 |
+
language_dim: 64 # Language embedding dimension
|
| 75 |
+
|
| 76 |
+
# Decoder/Vocoder config (matches config_codec_speaker.yml)
|
| 77 |
+
decoder:
|
| 78 |
+
type: 'ringformer'
|
| 79 |
+
resblock_kernel_sizes: [3, 7, 11]
|
| 80 |
+
upsample_rates: [7, 9]
|
| 81 |
+
upsample_initial_channel: 512
|
| 82 |
+
resblock_dilation_sizes: [[1, 3, 5], [1, 3, 5], [1, 3, 5]]
|
| 83 |
+
upsample_kernel_sizes: [14, 18]
|
| 84 |
+
gen_istft_n_fft: 28
|
| 85 |
+
gen_istft_hop_size: 7
|
| 86 |
+
|
| 87 |
+
# SLM for perceptual loss
|
| 88 |
+
slm:
|
| 89 |
+
model: 'microsoft/wavlm-base-plus'
|
| 90 |
+
sr: 16000
|
| 91 |
+
hidden: 768
|
| 92 |
+
nlayers: 13
|
| 93 |
+
initial_channel: 64
|
| 94 |
+
|
| 95 |
+
|
| 96 |
+
# Loss weights
|
| 97 |
+
loss_params:
|
| 98 |
+
TMA_epoch: -1 # TMA (adversarial) starts at epoch 4
|
| 99 |
+
lambda_mel: 20.0 # STFT reconstruction loss
|
| 100 |
+
lambda_gen: 1.0 # Generator adversarial loss
|
| 101 |
+
lambda_slm: 1.0 # WavLM perceptual loss
|
| 102 |
+
lambda_mag: 0.2 # Magnitude/phase loss
|
| 103 |
+
lambda_entropy: 50.0 # FSQ entropy/commitment loss
|
| 104 |
+
lambda_f0: 1.0 # F0 prediction loss
|
| 105 |
+
lambda_phoneme: 0.5 # Phoneme prediction loss (frame-level CE)
|
| 106 |
+
|
| 107 |
+
# Optimizer
|
| 108 |
+
optimizer_params:
|
| 109 |
+
lr: 1e-5
|
| 110 |
+
min_lr: 1e-5
|
| 111 |
+
decay_epochs: 15
|
| 112 |
+
pct_start: 0.33
|
Configs/config_codec_speaker.yml
ADDED
|
@@ -0,0 +1,110 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
# Speaker Codec Training Configuration
|
| 2 |
+
# ==============================================================================
|
| 3 |
+
# KEY FEATURES:
|
| 4 |
+
# - Learnable speaker embeddings: nn.Embedding(11, 128)
|
| 5 |
+
# - Speaker IDs 0-10 for 11 speakers
|
| 6 |
+
# - Speaker conditioning via AdaIN1d throughout decoder
|
| 7 |
+
# - NO mel-based style encoder - purely speaker ID based
|
| 8 |
+
# ==============================================================================
|
| 9 |
+
|
| 10 |
+
log_dir: "speaker_codec_training"
|
| 11 |
+
save_freq: 1
|
| 12 |
+
log_interval: 10
|
| 13 |
+
device: "cuda"
|
| 14 |
+
|
| 15 |
+
# Training epochs
|
| 16 |
+
epochs_codec: 20
|
| 17 |
+
|
| 18 |
+
batch_size: 6
|
| 19 |
+
max_len: 7000
|
| 20 |
+
|
| 21 |
+
# n_mels - for mel spectrogram extraction (used for loss calculation)
|
| 22 |
+
n_mels: 40
|
| 23 |
+
|
| 24 |
+
# Pretrained models
|
| 25 |
+
pretrained_model: ""
|
| 26 |
+
load_only_params: false
|
| 27 |
+
|
| 28 |
+
# Data
|
| 29 |
+
data_params:
|
| 30 |
+
train_data: "../my_tts_dataset_v2/train_list_filtered_german.txt"
|
| 31 |
+
val_data: "../my_tts_dataset_v2/val_list_filtered_german.txt"
|
| 32 |
+
root_path: "../my_tts_dataset_v2"
|
| 33 |
+
OOD_data: "Data/OOD_texts.txt"
|
| 34 |
+
min_length: 50
|
| 35 |
+
|
| 36 |
+
preprocess_params:
|
| 37 |
+
sr: 44100
|
| 38 |
+
spect_params:
|
| 39 |
+
n_fft: 2048
|
| 40 |
+
win_length: 1764
|
| 41 |
+
hop_length: 441
|
| 42 |
+
|
| 43 |
+
# Model parameters
|
| 44 |
+
model_params:
|
| 45 |
+
multispeaker: true # Enable multi-speaker mode
|
| 46 |
+
|
| 47 |
+
dim_in: 64
|
| 48 |
+
hidden_dim: 512
|
| 49 |
+
max_conv_dim: 512
|
| 50 |
+
n_layer: 3
|
| 51 |
+
n_mels: 40
|
| 52 |
+
|
| 53 |
+
n_token: 176
|
| 54 |
+
max_dur: 75
|
| 55 |
+
dropout: 0.1
|
| 56 |
+
|
| 57 |
+
# === SPEAKER EMBEDDING SETTINGS ===
|
| 58 |
+
num_speakers: 11 # 11 speakers: IDs 0-10
|
| 59 |
+
speaker_dim: 128 # 128-dim learnable embeddings
|
| 60 |
+
|
| 61 |
+
# === CODEC SETTINGS ===
|
| 62 |
+
# Prosody latent dimension
|
| 63 |
+
prosody_latent_dim: 512
|
| 64 |
+
|
| 65 |
+
# Hidden dimension for decoder
|
| 66 |
+
codec_hidden_dim: 512
|
| 67 |
+
|
| 68 |
+
# FSQ levels for prosody quantization
|
| 69 |
+
fsq_levels: [4, 4, 4, 4, 4, 4]
|
| 70 |
+
|
| 71 |
+
# Compression strides
|
| 72 |
+
codec_strides: [4]
|
| 73 |
+
|
| 74 |
+
# Decoder/Vocoder config
|
| 75 |
+
decoder:
|
| 76 |
+
type: 'ringformer'
|
| 77 |
+
resblock_kernel_sizes: [3, 7, 11]
|
| 78 |
+
upsample_rates: [7, 9]
|
| 79 |
+
upsample_initial_channel: 512
|
| 80 |
+
resblock_dilation_sizes: [[1, 3, 5], [1, 3, 5], [1, 3, 5]]
|
| 81 |
+
upsample_kernel_sizes: [14, 18]
|
| 82 |
+
gen_istft_n_fft: 28
|
| 83 |
+
gen_istft_hop_size: 7
|
| 84 |
+
|
| 85 |
+
# SLM for perceptual loss
|
| 86 |
+
slm:
|
| 87 |
+
model: 'microsoft/wavlm-base-plus'
|
| 88 |
+
sr: 16000
|
| 89 |
+
hidden: 768
|
| 90 |
+
nlayers: 13
|
| 91 |
+
initial_channel: 64
|
| 92 |
+
|
| 93 |
+
|
| 94 |
+
# Loss weights
|
| 95 |
+
loss_params:
|
| 96 |
+
TMA_epoch: 4 # TMA starts at epoch 4
|
| 97 |
+
lambda_mel: 10.0
|
| 98 |
+
lambda_gen: 1.0
|
| 99 |
+
lambda_slm: 1.0
|
| 100 |
+
lambda_mag: 0.2
|
| 101 |
+
lambda_entropy: 50.0
|
| 102 |
+
lambda_f0: 1.0
|
| 103 |
+
# Note: No lambda_style since we use learnable embeddings
|
| 104 |
+
|
| 105 |
+
# Optimizer
|
| 106 |
+
optimizer_params:
|
| 107 |
+
lr: 1e-5
|
| 108 |
+
min_lr: 1e-5
|
| 109 |
+
decay_epochs: 6
|
| 110 |
+
pct_start: 0.33
|
Configs/config_codec_v2.yml
ADDED
|
@@ -0,0 +1,127 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
# config_codec_v2.yml
|
| 2 |
+
# ==============================================================================
|
| 3 |
+
# Configuration for TTS Codec V2 Training
|
| 4 |
+
#
|
| 5 |
+
# Key features:
|
| 6 |
+
# - Style is tokenized from noised mel spectrogram
|
| 7 |
+
# - Style tokens are very coarse temporal (~2-8 Hz)
|
| 8 |
+
# - Content tokens from prosody + text (separate from style)
|
| 9 |
+
# ==============================================================================
|
| 10 |
+
|
| 11 |
+
log_dir: "codec_v2_training"
|
| 12 |
+
save_freq: 2
|
| 13 |
+
log_interval: 10
|
| 14 |
+
device: "cuda"
|
| 15 |
+
epochs_codec: 100
|
| 16 |
+
batch_size: 16
|
| 17 |
+
max_len: 8000
|
| 18 |
+
|
| 19 |
+
# Pretrained models
|
| 20 |
+
pretrained_model: "again_wavlm/epoch_flow_00108.pth" # For text encoder
|
| 21 |
+
pretrained_codec: "" # Path to resume codec training
|
| 22 |
+
|
| 23 |
+
data_params:
|
| 24 |
+
train_data: "Data/train_3_filtered_dur_fixed_speakers_test.txt"
|
| 25 |
+
val_data: "Data/val_3_filtered_fixed_speakers.txt"
|
| 26 |
+
root_path: "../tts_model"
|
| 27 |
+
min_length: 50
|
| 28 |
+
|
| 29 |
+
preprocess_params:
|
| 30 |
+
sr: 44100
|
| 31 |
+
spect_params:
|
| 32 |
+
n_fft: 4096
|
| 33 |
+
win_length: 2400
|
| 34 |
+
hop_length: 600
|
| 35 |
+
|
| 36 |
+
model_params:
|
| 37 |
+
multispeaker: false
|
| 38 |
+
|
| 39 |
+
# Base model dimensions
|
| 40 |
+
dim_in: 64
|
| 41 |
+
hidden_dim: 512
|
| 42 |
+
max_conv_dim: 512
|
| 43 |
+
n_layer: 3
|
| 44 |
+
n_mels: 80 # 80 mel bands for style encoder input
|
| 45 |
+
|
| 46 |
+
n_token: 178
|
| 47 |
+
max_dur: 75
|
| 48 |
+
style_dim: 64
|
| 49 |
+
style_dim_ac: 128
|
| 50 |
+
dropout: 0.1
|
| 51 |
+
|
| 52 |
+
# ==========================================================================
|
| 53 |
+
# CODEC V2 SPECIFIC PARAMETERS
|
| 54 |
+
# ==========================================================================
|
| 55 |
+
|
| 56 |
+
# Style encoder settings
|
| 57 |
+
# style_compression=16 at hop_length=600 (44.1kHz) = ~4.6 Hz style tokens
|
| 58 |
+
# style_compression=32 = ~2.3 Hz style tokens (more coarse)
|
| 59 |
+
style_compression: 16
|
| 60 |
+
style_dim_codec: 64
|
| 61 |
+
style_fsq_levels: [8, 8, 8, 8] # 4096 style codes
|
| 62 |
+
|
| 63 |
+
# Content encoder settings
|
| 64 |
+
# content_strides=[2] = 2x compression
|
| 65 |
+
content_strides: [2]
|
| 66 |
+
content_fsq_levels: [8, 8, 8, 8, 8, 8] # 262144 content codes
|
| 67 |
+
|
| 68 |
+
# Codec latent dimensions
|
| 69 |
+
codec_latent_dim: 256
|
| 70 |
+
codec_hidden_dim: 512
|
| 71 |
+
|
| 72 |
+
# Decoder config (same as ringformer)
|
| 73 |
+
decoder:
|
| 74 |
+
type: 'ringformer'
|
| 75 |
+
resblock_kernel_sizes: [3, 7, 11]
|
| 76 |
+
upsample_rates: [4, 6, 10] # Will be auto-computed based on compression
|
| 77 |
+
upsample_initial_channel: 512
|
| 78 |
+
resblock_dilation_sizes: [[1, 3, 5], [1, 3, 5], [1, 3, 5]]
|
| 79 |
+
upsample_kernel_sizes: [24, 20]
|
| 80 |
+
gen_istft_n_fft: 30
|
| 81 |
+
gen_istft_hop_size: 5
|
| 82 |
+
|
| 83 |
+
# SLM for WavLM loss
|
| 84 |
+
slm:
|
| 85 |
+
model: 'microsoft/wavlm-base-plus'
|
| 86 |
+
sr: 16000
|
| 87 |
+
hidden: 768
|
| 88 |
+
nlayers: 13
|
| 89 |
+
initial_channel: 64
|
| 90 |
+
|
| 91 |
+
# Diffusion config (not used in codec but needed for model building)
|
| 92 |
+
diffusion:
|
| 93 |
+
embedding_mask_proba: 0.2
|
| 94 |
+
transformer:
|
| 95 |
+
num_layers: 4
|
| 96 |
+
num_heads: 4
|
| 97 |
+
head_features: 32
|
| 98 |
+
multiplier: 4
|
| 99 |
+
dist:
|
| 100 |
+
sigma_data: 0.5
|
| 101 |
+
mean_data: 0.1
|
| 102 |
+
acoustic: 0.46
|
| 103 |
+
prosodic: 0.46
|
| 104 |
+
pitch: 0.46
|
| 105 |
+
acoustic_mean: 0.4
|
| 106 |
+
prosodic_mean: 0.4
|
| 107 |
+
pitch_mean: 0.4
|
| 108 |
+
estimate_sigma_data: true
|
| 109 |
+
mean: -0.0
|
| 110 |
+
std: 0.3
|
| 111 |
+
|
| 112 |
+
optimizer_params:
|
| 113 |
+
lr: 1.0e-4
|
| 114 |
+
pct_start: 0.0
|
| 115 |
+
|
| 116 |
+
loss_params:
|
| 117 |
+
lambda_mel: 45.0 # Mel reconstruction loss
|
| 118 |
+
lambda_gen: 1.0 # Generator adversarial loss
|
| 119 |
+
lambda_slm: 1.0 # SLM (WavLM) feature matching loss
|
| 120 |
+
lambda_mag: 1.0 # Magnitude/phase loss
|
| 121 |
+
lambda_style_entropy: 1.0 # Style FSQ entropy regularization
|
| 122 |
+
lambda_content_entropy: 1.0 # Content FSQ entropy regularization
|
| 123 |
+
TMA_epoch: 5 # Epoch to start adversarial training
|
| 124 |
+
|
| 125 |
+
# Style noise schedule (for robustness)
|
| 126 |
+
style_noise_start: 0.5 # Initial noise level for style encoder
|
| 127 |
+
style_noise_end: 0.1 # Final noise level (decays over epochs)
|
Configs/config_codec_v3.yml
ADDED
|
@@ -0,0 +1,131 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
# config_codec_v3.yml
|
| 2 |
+
# ==============================================================================
|
| 3 |
+
# Config for TTS Codec V2 with COARSE STYLE TOKENS
|
| 4 |
+
#
|
| 5 |
+
# Style is now [B, 8, T//32] - very coarse temporal tokens from noised mel
|
| 6 |
+
# NOT a continuous vector anymore!
|
| 7 |
+
# ==============================================================================
|
| 8 |
+
|
| 9 |
+
log_dir: "codec_v3_training"
|
| 10 |
+
save_freq: 2
|
| 11 |
+
log_interval: 10
|
| 12 |
+
device: "cuda"
|
| 13 |
+
epochs_codec: 100
|
| 14 |
+
batch_size: 10
|
| 15 |
+
max_len: 8000
|
| 16 |
+
|
| 17 |
+
# Pretrained model for text encoder (optional)
|
| 18 |
+
pretrained_model: ""
|
| 19 |
+
pretrained_codec: "" # Set to load existing codec checkpoint
|
| 20 |
+
|
| 21 |
+
data_params:
|
| 22 |
+
train_data: "Data/train_3_filtered_dur_fixed_speakers_test.txt"
|
| 23 |
+
val_data: "Data/val_3_filtered_fixed_speakers.txt"
|
| 24 |
+
root_path: "../tts_model"
|
| 25 |
+
min_length: 50
|
| 26 |
+
|
| 27 |
+
preprocess_params:
|
| 28 |
+
sr: 44100
|
| 29 |
+
spect_params:
|
| 30 |
+
n_fft: 4096
|
| 31 |
+
win_length: 2400
|
| 32 |
+
hop_length: 600
|
| 33 |
+
|
| 34 |
+
model_params:
|
| 35 |
+
multispeaker: false
|
| 36 |
+
dim_in: 64
|
| 37 |
+
hidden_dim: 512
|
| 38 |
+
max_conv_dim: 512
|
| 39 |
+
n_layer: 3
|
| 40 |
+
n_mels: 40 # Use 40 mels for style encoder
|
| 41 |
+
|
| 42 |
+
n_token: 178
|
| 43 |
+
max_dur: 75
|
| 44 |
+
|
| 45 |
+
# Style is now COARSE TOKENS, not a continuous vector!
|
| 46 |
+
# These are codec-specific style settings
|
| 47 |
+
style_dim: 64 # Base style dim (for old models)
|
| 48 |
+
style_dim_ac: 128 # Acoustic style (for old models)
|
| 49 |
+
|
| 50 |
+
# ==========================================================================
|
| 51 |
+
# CODEC V2 STYLE - Temporal style from mel (like original StyleEncoder but temporal)
|
| 52 |
+
# ==========================================================================
|
| 53 |
+
# Style tokens: [B, style_dim_codec, T // style_compression]
|
| 54 |
+
# e.g., [B, 128, T//16] -> temporal style matching original style_dim_ac
|
| 55 |
+
|
| 56 |
+
style_dim_codec: 128 # Match style_dim_ac from original StyleEncoder
|
| 57 |
+
style_compression: 16 # 16x compression -> ~4.6 Hz at 44.1kHz/600hop
|
| 58 |
+
|
| 59 |
+
# Style FSQ: Increased capacity significantly
|
| 60 |
+
# [8, 8, 8, 8, 5] -> ~16k codes, 5 dimensions
|
| 61 |
+
style_fsq_levels: [4, 4, 4, 4, 4]
|
| 62 |
+
|
| 63 |
+
# Noise added to mel during style encoding (for robustness)
|
| 64 |
+
style_noise_min: 0.0 # Minimum noise level
|
| 65 |
+
style_noise_max: 0.0 # Maximum noise level (decays during training)
|
| 66 |
+
|
| 67 |
+
# ==========================================================================
|
| 68 |
+
# CODEC V2 CONTENT - Fine-grained content from pitch/energy/text
|
| 69 |
+
# ==========================================================================
|
| 70 |
+
# Content tokens: [B, latent_dim, T // content_compression]
|
| 71 |
+
# e.g., [B, 256, T//2] means 256-dim content at ~36 Hz (fine-grained!)
|
| 72 |
+
|
| 73 |
+
codec_latent_dim: 256 # Content latent dimension
|
| 74 |
+
codec_hidden_dim: 512 # Decoder hidden dimension
|
| 75 |
+
content_strides: [2] # 2x compression -> ~36 Hz at 44.1kHz/600hop
|
| 76 |
+
|
| 77 |
+
# Content FSQ: 4^5 = 1024 content codes (smaller for 500 samples)
|
| 78 |
+
# Fine temporal resolution with reasonable codebook size
|
| 79 |
+
content_fsq_levels: [4, 4, 4, 4, 4]
|
| 80 |
+
|
| 81 |
+
# ==========================================================================
|
| 82 |
+
# DECODER
|
| 83 |
+
# ==========================================================================
|
| 84 |
+
decoder:
|
| 85 |
+
type: 'ringformer'
|
| 86 |
+
resblock_kernel_sizes: [3, 7, 11]
|
| 87 |
+
resblock_dilation_sizes: [[1, 3, 5], [1, 3, 5], [1, 3, 5]]
|
| 88 |
+
upsample_rates: [4, 6, 10] # 4*6*10 = 240 (for 2x content compression)
|
| 89 |
+
upsample_kernel_sizes: [8, 12, 20]
|
| 90 |
+
upsample_initial_channel: 512
|
| 91 |
+
gen_istft_n_fft: 30
|
| 92 |
+
gen_istft_hop_size: 5
|
| 93 |
+
|
| 94 |
+
# ==========================================================================
|
| 95 |
+
# SLM (Speech Language Model) for discriminator
|
| 96 |
+
# ==========================================================================
|
| 97 |
+
slm:
|
| 98 |
+
model: 'microsoft/wavlm-base-plus'
|
| 99 |
+
sr: 16000
|
| 100 |
+
hidden: 768
|
| 101 |
+
nlayers: 13
|
| 102 |
+
initial_channel: 64
|
| 103 |
+
|
| 104 |
+
|
| 105 |
+
|
| 106 |
+
# ==========================================================================
|
| 107 |
+
# LOSS WEIGHTS
|
| 108 |
+
# ==========================================================================
|
| 109 |
+
loss_params:
|
| 110 |
+
# Reconstruction losses
|
| 111 |
+
lambda_mel: 10.0 # Multi-resolution STFT loss
|
| 112 |
+
lambda_mag: 1.0 # Magnitude/phase loss for iSTFT
|
| 113 |
+
|
| 114 |
+
# Adversarial losses
|
| 115 |
+
lambda_gen: 1.0 # Generator adversarial loss
|
| 116 |
+
lambda_slm: 1.0 # WavLM feature matching loss
|
| 117 |
+
TMA_epoch: 20 # Start adversarial training at epoch 5
|
| 118 |
+
|
| 119 |
+
# F0 prediction loss (decoder predicts F0 from content tokens)
|
| 120 |
+
lambda_f0: 10.0 # F0 reconstruction loss
|
| 121 |
+
|
| 122 |
+
# FSQ entropy losses (encourage codebook utilization)
|
| 123 |
+
lambda_style_fsq: 1.0 # Style FSQ entropy regularization
|
| 124 |
+
lambda_content_fsq: 1.0 # Content FSQ entropy regularization
|
| 125 |
+
|
| 126 |
+
# ==========================================================================
|
| 127 |
+
# OPTIMIZER
|
| 128 |
+
# ==========================================================================
|
| 129 |
+
optimizer_params:
|
| 130 |
+
lr: 0.0001
|
| 131 |
+
pct_start: 0.0
|
Configs/config_fsq_flow_convnext.yml
ADDED
|
@@ -0,0 +1,78 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
# config_fsq_flow_convnext.yml
|
| 2 |
+
# ==============================================================================
|
| 3 |
+
# Configuration for FSQ Flow Predictor with ConvNeXt V2 Text Encoder
|
| 4 |
+
# ==============================================================================
|
| 5 |
+
|
| 6 |
+
log_dir: "fsq_flow_convnext_training"
|
| 7 |
+
|
| 8 |
+
# Training hyperparameters
|
| 9 |
+
batch_size: 32
|
| 10 |
+
epochs: 100
|
| 11 |
+
lr: 7e-5
|
| 12 |
+
warmup_steps: 500
|
| 13 |
+
flow_weight: 1.0 # Weight for flow matching loss (boost to speed up convergence)
|
| 14 |
+
ctc_weight: 0.1 # Weight for CTC auxiliary loss
|
| 15 |
+
duration_pred_weight: 1.0 # Weight for duration prediction (reduced to avoid crowding flow gradients)
|
| 16 |
+
cfg_dropout: 0.2 # CFG training dropout prob (20% full cond drop + 20% spk/lang drop)
|
| 17 |
+
dur_sampling_prob: 0.1 # Scheduled duration sampling: use predicted (rescaled) durations ~10% of steps
|
| 18 |
+
|
| 19 |
+
# Logging and saving
|
| 20 |
+
save_freq: 2 # Save every N epochs
|
| 21 |
+
log_interval: 20 # Log every N batches
|
| 22 |
+
val_interval: 30000 # Validate every N iterations
|
| 23 |
+
|
| 24 |
+
# Data parameters
|
| 25 |
+
data_params:
|
| 26 |
+
train_data: "../my_tts_dataset_v2/train_list_filtered_german.txt"
|
| 27 |
+
val_data: "../my_tts_dataset_v2/val_list_filtered_german.txt"
|
| 28 |
+
root_path: "../my_tts_dataset_v2"
|
| 29 |
+
min_length: 50
|
| 30 |
+
n_mels: 100
|
| 31 |
+
|
| 32 |
+
# Dump directory for preprocessed features
|
| 33 |
+
dump_dir: "./dump_100"
|
| 34 |
+
|
| 35 |
+
# Alignment and feature paths
|
| 36 |
+
alignment_train: "../data_preparation_v2/subsets/alignments_train.safetensors"
|
| 37 |
+
alignment_val: "../data_preparation_v2/subsets/alignments_val.safetensors"
|
| 38 |
+
stats_path: "dump_100/speaker_stats.json"
|
| 39 |
+
|
| 40 |
+
# Precomputed z_continuous directories (from extract_fsq_tokens_for_flow.py)
|
| 41 |
+
z_continuous_train: "precomputed_tokens/train/z_continuous"
|
| 42 |
+
z_continuous_val: "precomputed_tokens/val/z_continuous"
|
| 43 |
+
|
| 44 |
+
# Pretrained models
|
| 45 |
+
pretrained_model: "fsq_flow_convnext_training/model_epoch_20.pt" # Path to resume training
|
| 46 |
+
pretrained_codec: "mel_speaker_codec_training/epoch_mel_speaker_codec_00002.pth" # For validation decoding
|
| 47 |
+
|
| 48 |
+
# Model parameters
|
| 49 |
+
model_params:
|
| 50 |
+
# Text Encoder (ConvNeXt V2)
|
| 51 |
+
vocab_size: 183
|
| 52 |
+
text_dim: 512
|
| 53 |
+
text_num_layers: 4
|
| 54 |
+
text_kernel_size: 7
|
| 55 |
+
|
| 56 |
+
# Language & Speaker
|
| 57 |
+
num_languages: 10
|
| 58 |
+
language_dim: 64
|
| 59 |
+
n_speakers: 11
|
| 60 |
+
speaker_dim: 128
|
| 61 |
+
|
| 62 |
+
# FSQ Configuration (must match codec)
|
| 63 |
+
fsq_levels: [4, 4, 4, 4, 4, 4]
|
| 64 |
+
|
| 65 |
+
# Flow Matching Model (DiT)
|
| 66 |
+
hidden_dim: 512
|
| 67 |
+
flow_num_layers: 6
|
| 68 |
+
flow_num_heads: 8
|
| 69 |
+
|
| 70 |
+
# CTC
|
| 71 |
+
n_phonemes: 176
|
| 72 |
+
|
| 73 |
+
# Duration Predictor (Stochastic Flow-based)
|
| 74 |
+
duration_n_flows: 4
|
| 75 |
+
duration_kernel_size: 3
|
| 76 |
+
|
| 77 |
+
# Downsampling (100Hz frames -> 50Hz codec tokens)
|
| 78 |
+
codec_stride: 2
|
Configs/config_ft.yml
ADDED
|
@@ -0,0 +1,111 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
log_dir: "Models/LJSpeech"
|
| 2 |
+
save_freq: 5
|
| 3 |
+
log_interval: 10
|
| 4 |
+
device: "cuda"
|
| 5 |
+
epochs: 50 # number of finetuning epoch (1 hour of data)
|
| 6 |
+
batch_size: 8
|
| 7 |
+
max_len: 400 # maximum number of frames
|
| 8 |
+
pretrained_model: "Models/LibriTTS/epochs_2nd_00020.pth"
|
| 9 |
+
second_stage_load_pretrained: true # set to true if the pre-trained model is for 2nd stage
|
| 10 |
+
load_only_params: true # set to true if do not want to load epoch numbers and optimizer parameters
|
| 11 |
+
|
| 12 |
+
F0_path: "Utils/JDC/bst.t7"
|
| 13 |
+
ASR_config: "Utils/ASR/config.yml"
|
| 14 |
+
ASR_path: "Utils/ASR/epoch_00080.pth"
|
| 15 |
+
PLBERT_dir: 'Utils/PLBERT/'
|
| 16 |
+
|
| 17 |
+
data_params:
|
| 18 |
+
train_data: "Data/train_list.txt"
|
| 19 |
+
val_data: "Data/val_list.txt"
|
| 20 |
+
root_path: "/local/LJSpeech-1.1/wavs"
|
| 21 |
+
OOD_data: "Data/OOD_texts.txt"
|
| 22 |
+
min_length: 50 # sample until texts with this size are obtained for OOD texts
|
| 23 |
+
|
| 24 |
+
preprocess_params:
|
| 25 |
+
sr: 24000
|
| 26 |
+
spect_params:
|
| 27 |
+
n_fft: 2048
|
| 28 |
+
win_length: 1200
|
| 29 |
+
hop_length: 300
|
| 30 |
+
|
| 31 |
+
model_params:
|
| 32 |
+
multispeaker: true
|
| 33 |
+
|
| 34 |
+
dim_in: 64
|
| 35 |
+
hidden_dim: 512
|
| 36 |
+
max_conv_dim: 512
|
| 37 |
+
n_layer: 3
|
| 38 |
+
n_mels: 80
|
| 39 |
+
|
| 40 |
+
n_token: 178 # number of phoneme tokens
|
| 41 |
+
max_dur: 50 # maximum duration of a single phoneme
|
| 42 |
+
style_dim: 128 # style vector size
|
| 43 |
+
|
| 44 |
+
dropout: 0.2
|
| 45 |
+
|
| 46 |
+
# config for decoder
|
| 47 |
+
decoder:
|
| 48 |
+
type: 'hifigan' # either hifigan or istftnet
|
| 49 |
+
resblock_kernel_sizes: [3,7,11]
|
| 50 |
+
upsample_rates : [10,5,3,2]
|
| 51 |
+
upsample_initial_channel: 512
|
| 52 |
+
resblock_dilation_sizes: [[1,3,5], [1,3,5], [1,3,5]]
|
| 53 |
+
upsample_kernel_sizes: [20,10,6,4]
|
| 54 |
+
|
| 55 |
+
# speech language model config
|
| 56 |
+
slm:
|
| 57 |
+
model: 'microsoft/wavlm-base-plus'
|
| 58 |
+
sr: 16000 # sampling rate of SLM
|
| 59 |
+
hidden: 768 # hidden size of SLM
|
| 60 |
+
nlayers: 13 # number of layers of SLM
|
| 61 |
+
initial_channel: 64 # initial channels of SLM discriminator head
|
| 62 |
+
|
| 63 |
+
# style diffusion model config
|
| 64 |
+
diffusion:
|
| 65 |
+
embedding_mask_proba: 0.1
|
| 66 |
+
# transformer config
|
| 67 |
+
transformer:
|
| 68 |
+
num_layers: 3
|
| 69 |
+
num_heads: 8
|
| 70 |
+
head_features: 64
|
| 71 |
+
multiplier: 2
|
| 72 |
+
|
| 73 |
+
# diffusion distribution config
|
| 74 |
+
dist:
|
| 75 |
+
sigma_data: 0.2 # placeholder for estimate_sigma_data set to false
|
| 76 |
+
estimate_sigma_data: true # estimate sigma_data from the current batch if set to true
|
| 77 |
+
mean: -3.0
|
| 78 |
+
std: 1.0
|
| 79 |
+
|
| 80 |
+
loss_params:
|
| 81 |
+
lambda_mel: 5. # mel reconstruction loss
|
| 82 |
+
lambda_gen: 1. # generator loss
|
| 83 |
+
lambda_slm: 1. # slm feature matching loss
|
| 84 |
+
|
| 85 |
+
lambda_mono: 1. # monotonic alignment loss (TMA)
|
| 86 |
+
lambda_s2s: 1. # sequence-to-sequence loss (TMA)
|
| 87 |
+
|
| 88 |
+
lambda_F0: 1. # F0 reconstruction loss
|
| 89 |
+
lambda_norm: 1. # norm reconstruction loss
|
| 90 |
+
lambda_dur: 1. # duration loss
|
| 91 |
+
lambda_ce: 20. # duration predictor probability output CE loss
|
| 92 |
+
lambda_sty: 1. # style reconstruction loss
|
| 93 |
+
lambda_diff: 1. # score matching loss
|
| 94 |
+
|
| 95 |
+
diff_epoch: 10 # style diffusion starting epoch
|
| 96 |
+
joint_epoch: 30 # joint training starting epoch
|
| 97 |
+
|
| 98 |
+
optimizer_params:
|
| 99 |
+
lr: 0.0001 # general learning rate
|
| 100 |
+
bert_lr: 0.00001 # learning rate for PLBERT
|
| 101 |
+
ft_lr: 0.0001 # learning rate for acoustic modules
|
| 102 |
+
|
| 103 |
+
slmadv_params:
|
| 104 |
+
min_len: 400 # minimum length of samples
|
| 105 |
+
max_len: 500 # maximum length of samples
|
| 106 |
+
batch_percentage: 0.5 # to prevent out of memory, only use half of the original batch size
|
| 107 |
+
iter: 10 # update the discriminator every this iterations of generator update
|
| 108 |
+
thresh: 5 # gradient norm above which the gradient is scaled
|
| 109 |
+
scale: 0.01 # gradient scaling factor for predictors from SLM discriminators
|
| 110 |
+
sig: 1.5 # sigma for differentiable duration modeling
|
| 111 |
+
|
Configs/config_gemma_audio.yml
ADDED
|
@@ -0,0 +1,74 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
# config_gemma_audio.yml
|
| 2 |
+
# ==============================================================================
|
| 3 |
+
# Configuration for Gemma Audio Token LM Training
|
| 4 |
+
#
|
| 5 |
+
# This trains Gemma to predict audio tokens autoregressively with:
|
| 6 |
+
# - Text context: sliding window [prev2, prev1, CURRENT, next1]
|
| 7 |
+
# - Audio context: prev2_tokens, prev1_tokens
|
| 8 |
+
# ==============================================================================
|
| 9 |
+
|
| 10 |
+
# Output directory
|
| 11 |
+
log_dir: "gemma_audio_lm"
|
| 12 |
+
|
| 13 |
+
# ==============================================================================
|
| 14 |
+
# Training Parameters
|
| 15 |
+
# ==============================================================================
|
| 16 |
+
batch_size: 32 # Per-GPU batch size (increased for high VRAM)
|
| 17 |
+
gradient_accumulation_steps: 1 # No accumulation needed
|
| 18 |
+
epochs: 50
|
| 19 |
+
save_freq: 2 # Save every N epochs
|
| 20 |
+
log_interval: 50 # Log every N steps
|
| 21 |
+
|
| 22 |
+
# Optimization
|
| 23 |
+
learning_rate: 1.0e-4 # Base LR for audio components
|
| 24 |
+
warmup_steps: 1000 # Linear warmup steps
|
| 25 |
+
max_grad_norm: 1.0 # Gradient clipping
|
| 26 |
+
|
| 27 |
+
# Sequence lengths
|
| 28 |
+
max_token_len: 512 # Maximum audio token sequence length
|
| 29 |
+
|
| 30 |
+
# Resume training
|
| 31 |
+
resume_checkpoint: "" # Path to checkpoint to resume from
|
| 32 |
+
|
| 33 |
+
# ==============================================================================
|
| 34 |
+
# Data Parameters
|
| 35 |
+
# ==============================================================================
|
| 36 |
+
data_params:
|
| 37 |
+
train_data: "Data/train_3_filtered_dur_fixed_speakers_test.txt"
|
| 38 |
+
val_data: "Data/val_3_filtered_fixed_speakers.txt"
|
| 39 |
+
root_path: "../tts_model"
|
| 40 |
+
token_dir: "./precomputed_tokens" # Directory with extracted audio tokens
|
| 41 |
+
alignment_path: "align_outputs/alignments_train.safetensors"
|
| 42 |
+
alignment_path_val: "align_outputs/alignments_val.safetensors"
|
| 43 |
+
|
| 44 |
+
# ==============================================================================
|
| 45 |
+
# Model Parameters
|
| 46 |
+
# ==============================================================================
|
| 47 |
+
model_params:
|
| 48 |
+
# Gemma backbone
|
| 49 |
+
gemma_model: "google/gemma-3-4b-it" # Options: gemma-3-1b-it, gemma-2-2b-it, etc.
|
| 50 |
+
|
| 51 |
+
# Audio vocabulary (must match your codec FSQ levels)
|
| 52 |
+
# FSQ [4]*6 = 4096 codebook size
|
| 53 |
+
# FSQ [4]*8 = 65536 codebook size
|
| 54 |
+
audio_vocab_size: 4096
|
| 55 |
+
|
| 56 |
+
# LoRA configuration for efficient fine-tuning
|
| 57 |
+
use_lora: true
|
| 58 |
+
lora_r: 16 # LoRA rank
|
| 59 |
+
lora_alpha: 32 # LoRA alpha
|
| 60 |
+
lora_dropout: 0.05 # LoRA dropout
|
| 61 |
+
|
| 62 |
+
# Audio context encoder
|
| 63 |
+
audio_context_layers: 4 # Number of transformer layers for audio context
|
| 64 |
+
|
| 65 |
+
# ==============================================================================
|
| 66 |
+
# Preprocessing Parameters (from your existing config)
|
| 67 |
+
# ==============================================================================
|
| 68 |
+
preprocess_params:
|
| 69 |
+
sr: 44100
|
| 70 |
+
spect_params:
|
| 71 |
+
n_fft: 4096
|
| 72 |
+
win_length: 2400
|
| 73 |
+
hop_length: 600
|
| 74 |
+
n_mels: 128
|
Configs/config_libritts.yml
ADDED
|
@@ -0,0 +1,113 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
log_dir: "Models/LibriTTS"
|
| 2 |
+
first_stage_path: "first_stage.pth"
|
| 3 |
+
save_freq: 1
|
| 4 |
+
log_interval: 10
|
| 5 |
+
device: "cuda"
|
| 6 |
+
epochs_1st: 50 # number of epochs for first stage training (pre-training)
|
| 7 |
+
epochs_2nd: 30 # number of peochs for second stage training (joint training)
|
| 8 |
+
batch_size: 16
|
| 9 |
+
max_len: 300 # maximum number of frames
|
| 10 |
+
pretrained_model: ""
|
| 11 |
+
second_stage_load_pretrained: true # set to true if the pre-trained model is for 2nd stage
|
| 12 |
+
load_only_params: false # set to true if do not want to load epoch numbers and optimizer parameters
|
| 13 |
+
|
| 14 |
+
F0_path: "Utils/JDC/bst.t7"
|
| 15 |
+
ASR_config: "Utils/ASR/config.yml"
|
| 16 |
+
ASR_path: "Utils/ASR/epoch_00080.pth"
|
| 17 |
+
PLBERT_dir: 'Utils/PLBERT/'
|
| 18 |
+
|
| 19 |
+
data_params:
|
| 20 |
+
train_data: "Data/train_list.txt"
|
| 21 |
+
val_data: "Data/val_list.txt"
|
| 22 |
+
root_path: ""
|
| 23 |
+
OOD_data: "Data/OOD_texts.txt"
|
| 24 |
+
min_length: 50 # sample until texts with this size are obtained for OOD texts
|
| 25 |
+
|
| 26 |
+
preprocess_params:
|
| 27 |
+
sr: 24000
|
| 28 |
+
spect_params:
|
| 29 |
+
n_fft: 2048
|
| 30 |
+
win_length: 1200
|
| 31 |
+
hop_length: 300
|
| 32 |
+
|
| 33 |
+
model_params:
|
| 34 |
+
multispeaker: true
|
| 35 |
+
|
| 36 |
+
dim_in: 64
|
| 37 |
+
hidden_dim: 512
|
| 38 |
+
max_conv_dim: 512
|
| 39 |
+
n_layer: 3
|
| 40 |
+
n_mels: 80
|
| 41 |
+
|
| 42 |
+
n_token: 178 # number of phoneme tokens
|
| 43 |
+
max_dur: 50 # maximum duration of a single phoneme
|
| 44 |
+
style_dim: 128 # style vector size
|
| 45 |
+
|
| 46 |
+
dropout: 0.2
|
| 47 |
+
|
| 48 |
+
# config for decoder
|
| 49 |
+
decoder:
|
| 50 |
+
type: 'hifigan' # either hifigan or istftnet
|
| 51 |
+
resblock_kernel_sizes: [3,7,11]
|
| 52 |
+
upsample_rates : [10,5,3,2]
|
| 53 |
+
upsample_initial_channel: 512
|
| 54 |
+
resblock_dilation_sizes: [[1,3,5], [1,3,5], [1,3,5]]
|
| 55 |
+
upsample_kernel_sizes: [20,10,6,4]
|
| 56 |
+
|
| 57 |
+
# speech language model config
|
| 58 |
+
slm:
|
| 59 |
+
model: 'microsoft/wavlm-base-plus'
|
| 60 |
+
sr: 16000 # sampling rate of SLM
|
| 61 |
+
hidden: 768 # hidden size of SLM
|
| 62 |
+
nlayers: 13 # number of layers of SLM
|
| 63 |
+
initial_channel: 64 # initial channels of SLM discriminator head
|
| 64 |
+
|
| 65 |
+
# style diffusion model config
|
| 66 |
+
diffusion:
|
| 67 |
+
embedding_mask_proba: 0.1
|
| 68 |
+
# transformer config
|
| 69 |
+
transformer:
|
| 70 |
+
num_layers: 3
|
| 71 |
+
num_heads: 8
|
| 72 |
+
head_features: 64
|
| 73 |
+
multiplier: 2
|
| 74 |
+
|
| 75 |
+
# diffusion distribution config
|
| 76 |
+
dist:
|
| 77 |
+
sigma_data: 0.2 # placeholder for estimate_sigma_data set to false
|
| 78 |
+
estimate_sigma_data: true # estimate sigma_data from the current batch if set to true
|
| 79 |
+
mean: -3.0
|
| 80 |
+
std: 1.0
|
| 81 |
+
|
| 82 |
+
loss_params:
|
| 83 |
+
lambda_mel: 5. # mel reconstruction loss
|
| 84 |
+
lambda_gen: 1. # generator loss
|
| 85 |
+
lambda_slm: 1. # slm feature matching loss
|
| 86 |
+
|
| 87 |
+
lambda_mono: 1. # monotonic alignment loss (1st stage, TMA)
|
| 88 |
+
lambda_s2s: 1. # sequence-to-sequence loss (1st stage, TMA)
|
| 89 |
+
TMA_epoch: 5 # TMA starting epoch (1st stage)
|
| 90 |
+
|
| 91 |
+
lambda_F0: 1. # F0 reconstruction loss (2nd stage)
|
| 92 |
+
lambda_norm: 1. # norm reconstruction loss (2nd stage)
|
| 93 |
+
lambda_dur: 1. # duration loss (2nd stage)
|
| 94 |
+
lambda_ce: 20. # duration predictor probability output CE loss (2nd stage)
|
| 95 |
+
lambda_sty: 1. # style reconstruction loss (2nd stage)
|
| 96 |
+
lambda_diff: 1. # score matching loss (2nd stage)
|
| 97 |
+
|
| 98 |
+
diff_epoch: 10 # style diffusion starting epoch (2nd stage)
|
| 99 |
+
joint_epoch: 15 # joint training starting epoch (2nd stage)
|
| 100 |
+
|
| 101 |
+
optimizer_params:
|
| 102 |
+
lr: 0.0001 # general learning rate
|
| 103 |
+
bert_lr: 0.00001 # learning rate for PLBERT
|
| 104 |
+
ft_lr: 0.00001 # learning rate for acoustic modules
|
| 105 |
+
|
| 106 |
+
slmadv_params:
|
| 107 |
+
min_len: 400 # minimum length of samples
|
| 108 |
+
max_len: 500 # maximum length of samples
|
| 109 |
+
batch_percentage: 0.5 # to prevent out of memory, only use half of the original batch size
|
| 110 |
+
iter: 20 # update the discriminator every this iterations of generator update
|
| 111 |
+
thresh: 5 # gradient norm above which the gradient is scaled
|
| 112 |
+
scale: 0.01 # gradient scaling factor for predictors from SLM discriminators
|
| 113 |
+
sig: 1.5 # sigma for differentiable duration modeling
|
Configs/config_predictors_speaker.yml
ADDED
|
@@ -0,0 +1,61 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
# config_predictors_speaker.yml
|
| 2 |
+
# ==============================================================================
|
| 3 |
+
# Configuration for Duration and Token Predictors with Speaker ID
|
| 4 |
+
#
|
| 5 |
+
# ARCHITECTURE:
|
| 6 |
+
# - Duration Predictor: Text + Speaker ID -> Durations (Flow-based)
|
| 7 |
+
# - Token Predictor: Text + Durations + Speaker ID -> Codec Tokens
|
| 8 |
+
#
|
| 9 |
+
# No style vectors - only speaker embeddings for conditioning
|
| 10 |
+
# Codec uses stride [2] for 2x temporal compression
|
| 11 |
+
# ==============================================================================
|
| 12 |
+
|
| 13 |
+
log_dir: "predictors_speaker_training"
|
| 14 |
+
save_freq: 2
|
| 15 |
+
log_interval: 10
|
| 16 |
+
|
| 17 |
+
# Training
|
| 18 |
+
epochs: 100
|
| 19 |
+
batch_size: 32
|
| 20 |
+
lr: 1e-4
|
| 21 |
+
|
| 22 |
+
# Pretrained model (optional)
|
| 23 |
+
pretrained_model: ""
|
| 24 |
+
|
| 25 |
+
# Precomputed codec tokens (from extract_codec_tokens.py)
|
| 26 |
+
# These are the target tokens for the token predictor
|
| 27 |
+
codec_tokens_train: "precomputed_tokens/codec_tokens_train.safetensors"
|
| 28 |
+
codec_tokens_val: "precomputed_tokens/codec_tokens_val.safetensors"
|
| 29 |
+
|
| 30 |
+
# Data
|
| 31 |
+
data_params:
|
| 32 |
+
train_data: "Data/train_3_filtered_dur_fixed_speakers_test.txt"
|
| 33 |
+
val_data: "Data/val_3_filtered_fixed_speakers.txt"
|
| 34 |
+
root_path: "../tts_model"
|
| 35 |
+
min_length: 50
|
| 36 |
+
|
| 37 |
+
preprocess_params:
|
| 38 |
+
sr: 44100
|
| 39 |
+
spect_params:
|
| 40 |
+
n_fft: 4096
|
| 41 |
+
win_length: 2400
|
| 42 |
+
hop_length: 600
|
| 43 |
+
|
| 44 |
+
# Model parameters
|
| 45 |
+
model_params:
|
| 46 |
+
# Vocabulary
|
| 47 |
+
n_token: 178
|
| 48 |
+
|
| 49 |
+
# Speaker settings
|
| 50 |
+
n_speakers: 100
|
| 51 |
+
speaker_emb_dim: 256
|
| 52 |
+
|
| 53 |
+
# Model dimensions
|
| 54 |
+
hidden_dim: 512
|
| 55 |
+
|
| 56 |
+
# Codec settings (must match your trained codec in config_codec_hybrid.yml)
|
| 57 |
+
# codec_strides: [2, 2] means 4x temporal compression
|
| 58 |
+
# But if you want stride [2] only, use codec_stride: 2
|
| 59 |
+
codec_stride: 2 # Product of [2]
|
| 60 |
+
# FSQ codebook size: product of levels [4, 4, 4, 4, 4] = 4^5 = 1024
|
| 61 |
+
codebook_size: 1024
|
Configs/config_predictors_speaker_diffusion.yml
ADDED
|
@@ -0,0 +1,60 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
# config_predictors_speaker_diffusion.yml
|
| 2 |
+
# ==============================================================================
|
| 3 |
+
# Configuration for Token Predictor with Flow Matching + DiT
|
| 4 |
+
# ==============================================================================
|
| 5 |
+
|
| 6 |
+
log_dir: "predictors_speaker_diffusion_training"
|
| 7 |
+
|
| 8 |
+
# Training params
|
| 9 |
+
batch_size: 16
|
| 10 |
+
epochs: 100
|
| 11 |
+
save_freq: 2
|
| 12 |
+
log_interval: 10
|
| 13 |
+
lr: 1e-4
|
| 14 |
+
|
| 15 |
+
# Data params
|
| 16 |
+
data_params:
|
| 17 |
+
train_data: "./Data/train_list.txt"
|
| 18 |
+
val_data: "./Data/val_list.txt"
|
| 19 |
+
root_path: "/path/to/audio/root"
|
| 20 |
+
min_length: 50
|
| 21 |
+
|
| 22 |
+
# Model params
|
| 23 |
+
model_params:
|
| 24 |
+
n_speakers: 100
|
| 25 |
+
speaker_emb_dim: 256
|
| 26 |
+
hidden_dim: 512
|
| 27 |
+
n_token: 178
|
| 28 |
+
codec_stride: 2
|
| 29 |
+
|
| 30 |
+
# FSQ levels for codec tokens
|
| 31 |
+
fsq_levels: [4, 4, 4, 4, 4]
|
| 32 |
+
|
| 33 |
+
# Gemma 1B hidden dimension
|
| 34 |
+
gemma_dim: 1152
|
| 35 |
+
|
| 36 |
+
# Flow Matching params
|
| 37 |
+
flow_params:
|
| 38 |
+
# DiT encoder layers
|
| 39 |
+
n_layers_enc: 4
|
| 40 |
+
|
| 41 |
+
# Flow matching velocity network layers
|
| 42 |
+
n_layers_flow: 6
|
| 43 |
+
|
| 44 |
+
# ODE solver steps for inference
|
| 45 |
+
flow_steps: 20
|
| 46 |
+
|
| 47 |
+
# Classifier-free guidance scale
|
| 48 |
+
cfg_scale: 1.5
|
| 49 |
+
|
| 50 |
+
# Precomputed data paths
|
| 51 |
+
codec_tokens_train: "precomputed_tokens/codec_tokens_train.safetensors"
|
| 52 |
+
codec_tokens_val: "precomputed_tokens/codec_tokens_val.safetensors"
|
| 53 |
+
|
| 54 |
+
# Gemma embeddings (precomputed from raw_texts)
|
| 55 |
+
gemma_embeddings_train: "precomputed_tokens/gemma_embeddings_train.safetensors"
|
| 56 |
+
gemma_embeddings_val: "precomputed_tokens/gemma_embeddings_val.safetensors"
|
| 57 |
+
|
| 58 |
+
# Pretrained models
|
| 59 |
+
pretrained_model: "" # Resume from checkpoint
|
| 60 |
+
pretrained_hybrid_codec: "hybrid_codec_training/epoch_hybrid_codec_00017.pth"
|
Configs/config_predictors_speaker_flow.yml
ADDED
|
@@ -0,0 +1,89 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
# config_predictors_speaker_flow.yml
|
| 2 |
+
# ==============================================================================
|
| 3 |
+
# Configuration for Duration and Token Predictors with Speaker ID
|
| 4 |
+
# Token Predictor uses Flow Matching (CFM) instead of classification
|
| 5 |
+
#
|
| 6 |
+
# ARCHITECTURE:
|
| 7 |
+
# - Duration Predictor: Text + Speaker ID -> Durations (Flow-based SDP)
|
| 8 |
+
# - Token Predictor: Text + Durations + Speaker ID -> FSQ Embeddings (CFM)
|
| 9 |
+
#
|
| 10 |
+
# Key Features:
|
| 11 |
+
# - Continuous token prediction via Conditional Flow Matching
|
| 12 |
+
# - Predicts FSQ embeddings directly (not discrete token IDs)
|
| 13 |
+
# - At inference, quantizes to nearest FSQ codes
|
| 14 |
+
# - More stable training, smoother outputs
|
| 15 |
+
# ==============================================================================
|
| 16 |
+
|
| 17 |
+
log_dir: "predictors_speaker_flow_training"
|
| 18 |
+
save_freq: 2
|
| 19 |
+
log_interval: 10
|
| 20 |
+
|
| 21 |
+
# Training
|
| 22 |
+
epochs: 100
|
| 23 |
+
batch_size: 32
|
| 24 |
+
lr: 1e-4
|
| 25 |
+
|
| 26 |
+
# Gradient clipping (recommended for flow matching)
|
| 27 |
+
grad_clip: 1.0
|
| 28 |
+
|
| 29 |
+
# Loss weights
|
| 30 |
+
loss_weight_dur: 1.0
|
| 31 |
+
loss_weight_token: 100.0 # CFM loss is typically smaller scale
|
| 32 |
+
|
| 33 |
+
# Pretrained model (optional)
|
| 34 |
+
pretrained_model: ""
|
| 35 |
+
|
| 36 |
+
# Precomputed data
|
| 37 |
+
# Option 1: FSQ embeddings (preferred - continuous targets)
|
| 38 |
+
fsq_embeddings_train: "precomputed_tokens/fsq_embeddings_train.safetensors"
|
| 39 |
+
fsq_embeddings_val: "precomputed_tokens/fsq_embeddings_val.safetensors"
|
| 40 |
+
|
| 41 |
+
# Option 2: Codec tokens (fallback - will convert to embeddings)
|
| 42 |
+
codec_tokens_train: "precomputed_tokens/codec_tokens_train.safetensors"
|
| 43 |
+
codec_tokens_val: "precomputed_tokens/codec_tokens_val.safetensors"
|
| 44 |
+
|
| 45 |
+
# Data
|
| 46 |
+
data_params:
|
| 47 |
+
train_data: "Data/train_3_filtered_dur_fixed_speakers_test.txt"
|
| 48 |
+
val_data: "Data/val_3_filtered_fixed_speakers.txt"
|
| 49 |
+
root_path: "../tts_model"
|
| 50 |
+
min_length: 50
|
| 51 |
+
|
| 52 |
+
preprocess_params:
|
| 53 |
+
sr: 44100
|
| 54 |
+
spect_params:
|
| 55 |
+
n_fft: 4096
|
| 56 |
+
win_length: 2400
|
| 57 |
+
hop_length: 600
|
| 58 |
+
|
| 59 |
+
# Model parameters
|
| 60 |
+
model_params:
|
| 61 |
+
# Vocabulary
|
| 62 |
+
n_token: 178
|
| 63 |
+
|
| 64 |
+
# Speaker settings
|
| 65 |
+
n_speakers: 100
|
| 66 |
+
speaker_emb_dim: 256
|
| 67 |
+
|
| 68 |
+
# Model dimensions
|
| 69 |
+
hidden_dim: 512
|
| 70 |
+
|
| 71 |
+
# Codec settings
|
| 72 |
+
codec_stride: 2
|
| 73 |
+
|
| 74 |
+
# FSQ settings (must match your trained codec)
|
| 75 |
+
fsq_levels: [4, 4, 4, 4, 4] # 4^5 = 1024 codes
|
| 76 |
+
|
| 77 |
+
# CFM (Conditional Flow Matching) parameters
|
| 78 |
+
cfm_params:
|
| 79 |
+
# Hidden dimension for CFM estimator
|
| 80 |
+
hidden_channels: 512
|
| 81 |
+
|
| 82 |
+
# Number of residual blocks in CFM
|
| 83 |
+
n_layers: 6
|
| 84 |
+
|
| 85 |
+
# Dropout rate
|
| 86 |
+
dropout: 0.1
|
| 87 |
+
|
| 88 |
+
# ODE solver steps at inference
|
| 89 |
+
solver_steps: 20
|
Configs/config_predictors_speaker_flow_context.yml
ADDED
|
@@ -0,0 +1,103 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
# config_predictors_speaker_flow_context.yml
|
| 2 |
+
# ==============================================================================
|
| 3 |
+
# Configuration for Duration and Token Predictors with Speaker ID + Context
|
| 4 |
+
# Token Predictor uses Flow Matching (CFM) approach
|
| 5 |
+
#
|
| 6 |
+
# ARCHITECTURE:
|
| 7 |
+
# - Duration Predictor: Text + Context + Speaker ID -> Durations (Flow-based SDP)
|
| 8 |
+
# - Token Predictor: Text + Context + Durations + Speaker ID -> FSQ Embeddings (CFM)
|
| 9 |
+
#
|
| 10 |
+
# Key Features:
|
| 11 |
+
# - Context-aware predictions for smooth sliding window inference
|
| 12 |
+
# - Cross-attention to neighboring sentences (prev/next)
|
| 13 |
+
# - Exclusion mask prevents attending to current sentence in context
|
| 14 |
+
# - This ensures sharp predictions while maintaining context awareness
|
| 15 |
+
# ==============================================================================
|
| 16 |
+
|
| 17 |
+
log_dir: "predictors_context_training"
|
| 18 |
+
save_freq: 2
|
| 19 |
+
log_interval: 10
|
| 20 |
+
|
| 21 |
+
# Training
|
| 22 |
+
epochs: 100
|
| 23 |
+
batch_size: 32
|
| 24 |
+
lr: 1e-4
|
| 25 |
+
|
| 26 |
+
# Gradient clipping (recommended for flow matching)
|
| 27 |
+
grad_clip: 1.0
|
| 28 |
+
|
| 29 |
+
# Loss weights
|
| 30 |
+
loss_weight_dur: 1.0
|
| 31 |
+
loss_weight_token: 100.0 # CFM loss is typically smaller scale
|
| 32 |
+
|
| 33 |
+
# Pretrained model (optional)
|
| 34 |
+
pretrained_model: "predictors_context_training/epoch_00100.pth"
|
| 35 |
+
|
| 36 |
+
# Precomputed data
|
| 37 |
+
# Option 1: FSQ embeddings (preferred - continuous targets)
|
| 38 |
+
fsq_embeddings_train: "precomputed_tokens/fsq_embeddings_train.safetensors"
|
| 39 |
+
fsq_embeddings_val: "precomputed_tokens/fsq_embeddings_val.safetensors"
|
| 40 |
+
|
| 41 |
+
# Option 2: Codec tokens (fallback - will convert to embeddings)
|
| 42 |
+
codec_tokens_train: "precomputed_tokens/codec_tokens_train.safetensors"
|
| 43 |
+
codec_tokens_val: "precomputed_tokens/codec_tokens_val.safetensors"
|
| 44 |
+
|
| 45 |
+
# Pretrained hybrid codec (for validation audio)
|
| 46 |
+
pretrained_hybrid_codec: "hybrid_codec_training/epoch_mel_speaker_codec_00002.pth"
|
| 47 |
+
|
| 48 |
+
# Data
|
| 49 |
+
data_params:
|
| 50 |
+
train_data: "Data/train_3_filtered_dur_fixed_speakers_test.txt"
|
| 51 |
+
val_data: "Data/val_3_filtered_fixed_speakers.txt"
|
| 52 |
+
root_path: "../tts_model"
|
| 53 |
+
min_length: 50
|
| 54 |
+
|
| 55 |
+
preprocess_params:
|
| 56 |
+
sr: 44100
|
| 57 |
+
spect_params:
|
| 58 |
+
n_fft: 4096
|
| 59 |
+
win_length: 2400
|
| 60 |
+
hop_length: 600
|
| 61 |
+
|
| 62 |
+
# Model parameters
|
| 63 |
+
model_params:
|
| 64 |
+
# Vocabulary
|
| 65 |
+
n_token: 178
|
| 66 |
+
|
| 67 |
+
# Speaker settings
|
| 68 |
+
n_speakers: 100
|
| 69 |
+
speaker_emb_dim: 256
|
| 70 |
+
|
| 71 |
+
# Model dimensions
|
| 72 |
+
hidden_dim: 512
|
| 73 |
+
|
| 74 |
+
# Codec settings
|
| 75 |
+
codec_stride: 2
|
| 76 |
+
|
| 77 |
+
# FSQ settings (must match your trained codec)
|
| 78 |
+
fsq_levels: [4, 4, 4, 4, 4] # 4^5 = 1024 codes
|
| 79 |
+
|
| 80 |
+
# Context conditioning parameters
|
| 81 |
+
context_params:
|
| 82 |
+
# Number of transformer layers in context encoder
|
| 83 |
+
n_context_layers: 2
|
| 84 |
+
|
| 85 |
+
# Number of attention heads in context encoder
|
| 86 |
+
n_context_heads: 4
|
| 87 |
+
|
| 88 |
+
# Enable cross-attention from current tokens to context
|
| 89 |
+
use_context_cross_attn: true
|
| 90 |
+
|
| 91 |
+
# CFM (Conditional Flow Matching) parameters
|
| 92 |
+
cfm_params:
|
| 93 |
+
# Hidden dimension for CFM estimator
|
| 94 |
+
hidden_channels: 512
|
| 95 |
+
|
| 96 |
+
# Number of residual blocks in CFM
|
| 97 |
+
n_layers: 6
|
| 98 |
+
|
| 99 |
+
# Dropout rate
|
| 100 |
+
dropout: 0.1
|
| 101 |
+
|
| 102 |
+
# ODE solver steps at inference
|
| 103 |
+
solver_steps: 20
|
Configs/config_predictors_speaker_flow_context_temporal.yml
ADDED
|
@@ -0,0 +1,88 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
# config_predictors_speaker_flow_context_temporal.yml
|
| 2 |
+
# ==============================================================================
|
| 3 |
+
# Configuration for Duration and Token Predictors with Speaker ID + Context + Temporal Codec
|
| 4 |
+
# Token Predictor uses Flow Matching (CFM) approach
|
| 5 |
+
# ==============================================================================
|
| 6 |
+
|
| 7 |
+
log_dir: "predictors_speaker_flow_context_temporal_training"
|
| 8 |
+
save_freq: 2
|
| 9 |
+
log_interval: 10
|
| 10 |
+
|
| 11 |
+
# Training
|
| 12 |
+
epochs: 100
|
| 13 |
+
batch_size: 32
|
| 14 |
+
lr: 1e-4
|
| 15 |
+
|
| 16 |
+
# Gradient clipping (recommended for flow matching)
|
| 17 |
+
grad_clip: 2.0
|
| 18 |
+
|
| 19 |
+
# Loss weights
|
| 20 |
+
loss_weight_dur: 1.0
|
| 21 |
+
loss_weight_token: 100.0 # CFM loss is typically smaller scale
|
| 22 |
+
|
| 23 |
+
# Pretrained model (optional)
|
| 24 |
+
pretrained_model: ""
|
| 25 |
+
|
| 26 |
+
# Precomputed data
|
| 27 |
+
codec_tokens_train: "precomputed_tokens_temporal/codec_tokens_temporal_train.safetensors"
|
| 28 |
+
# codec_tokens_val: "precomputed_tokens_temporal/codec_tokens_temporal_val.safetensors" # Optional
|
| 29 |
+
|
| 30 |
+
# Pretrained hybrid temporal codec (for validation audio generation)
|
| 31 |
+
pretrained_hybrid_temporal_codec: "hybrid_temporal_codec_training/epoch_hybrid_temporal_codec_00031.pth"
|
| 32 |
+
|
| 33 |
+
# Data
|
| 34 |
+
data_params:
|
| 35 |
+
train_data: "Data/train_3_filtered_dur_fixed_speakers_test.txt"
|
| 36 |
+
val_data: "Data/val_3_filtered_fixed_speakers.txt"
|
| 37 |
+
root_path: "../tts_model"
|
| 38 |
+
min_length: 50
|
| 39 |
+
|
| 40 |
+
preprocess_params:
|
| 41 |
+
sr: 44100
|
| 42 |
+
spect_params:
|
| 43 |
+
n_fft: 2048
|
| 44 |
+
win_length: 1764
|
| 45 |
+
hop_length: 441
|
| 46 |
+
|
| 47 |
+
# Model parameters
|
| 48 |
+
model_params:
|
| 49 |
+
# Vocabulary
|
| 50 |
+
n_token: 176
|
| 51 |
+
|
| 52 |
+
# Speaker settings
|
| 53 |
+
n_speakers: 4
|
| 54 |
+
speaker_emb_dim: 256
|
| 55 |
+
|
| 56 |
+
# Model dimensions
|
| 57 |
+
hidden_dim: 512
|
| 58 |
+
|
| 59 |
+
# Codec settings
|
| 60 |
+
codec_stride: 2
|
| 61 |
+
|
| 62 |
+
# FSQ settings (must match your trained codec)
|
| 63 |
+
fsq_levels: [4, 4, 4, 4, 4] # 4^5 = 1024 codes
|
| 64 |
+
|
| 65 |
+
# Context conditioning parameters
|
| 66 |
+
context_params:
|
| 67 |
+
# Number of transformer layers in context encoder
|
| 68 |
+
n_context_layers: 2
|
| 69 |
+
|
| 70 |
+
# Number of attention heads in context encoder
|
| 71 |
+
n_context_heads: 4
|
| 72 |
+
|
| 73 |
+
# Enable cross-attention from current tokens to context
|
| 74 |
+
use_context_cross_attn: true
|
| 75 |
+
|
| 76 |
+
# CFM (Conditional Flow Matching) parameters
|
| 77 |
+
cfm_params:
|
| 78 |
+
# Hidden dimension for CFM estimator
|
| 79 |
+
hidden_channels: 512
|
| 80 |
+
|
| 81 |
+
# Number of residual blocks in CFM
|
| 82 |
+
n_layers: 3
|
| 83 |
+
|
| 84 |
+
# Dropout rate
|
| 85 |
+
dropout: 0.1
|
| 86 |
+
|
| 87 |
+
# Solver steps for inference
|
| 88 |
+
solver_steps: 20
|
Configs/config_predictors_streaming_dit.yml
ADDED
|
@@ -0,0 +1,100 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
# Configuration for Streaming-Native Predictors with DiT
|
| 2 |
+
# ==============================================================================
|
| 3 |
+
# Trains duration and token predictors with:
|
| 4 |
+
# - Block-structured attention: 3 blocks receptive field
|
| 5 |
+
# * Current block (1)
|
| 6 |
+
# * 2-block lookback
|
| 7 |
+
# * 1-block lookahead
|
| 8 |
+
# - Block-based processing during training and inference
|
| 9 |
+
# - DiT backbone instead of flow-based models
|
| 10 |
+
# - Flow Matching for token prediction
|
| 11 |
+
# ==============================================================================
|
| 12 |
+
|
| 13 |
+
log_dir: "logs/predictors_streaming_dit"
|
| 14 |
+
|
| 15 |
+
# Training
|
| 16 |
+
epochs: 100
|
| 17 |
+
batch_size: 16 # Can be smaller than standard due to block processing
|
| 18 |
+
save_freq: 2
|
| 19 |
+
log_interval: 10
|
| 20 |
+
lr: 1.0e-4
|
| 21 |
+
|
| 22 |
+
# Data
|
| 23 |
+
data_params:
|
| 24 |
+
train_data: "Data/train_3_filtered_dur_fixed_speakers_test.txt"
|
| 25 |
+
val_data: "Data/val_3_filtered_fixed_speakers.txt"
|
| 26 |
+
root_path: "../tts_model"
|
| 27 |
+
min_length: 50
|
| 28 |
+
|
| 29 |
+
# Precomputed codec tokens (from extract_codec_tokens_hybrid_temporal.py)
|
| 30 |
+
codec_tokens_train: "precomputed_tokens_temporal/codec_tokens_temporal_train.safetensors"
|
| 31 |
+
|
| 32 |
+
# Pretrained models
|
| 33 |
+
pretrained_model: "" # Resume training from checkpoint
|
| 34 |
+
pretrained_hybrid_temporal_codec: "hybrid_temporal_codec_training/epoch_hybrid_temporal_codec_00031.pth"
|
| 35 |
+
|
| 36 |
+
# Model architecture
|
| 37 |
+
model_params:
|
| 38 |
+
n_token: 178 # Vocabulary size
|
| 39 |
+
n_speakers: 100
|
| 40 |
+
speaker_emb_dim: 256
|
| 41 |
+
d_model: 512 # Hidden dimension for all components
|
| 42 |
+
codec_stride: 2 # Codec compression (50Hz tokens)
|
| 43 |
+
fsq_levels: [4, 4, 4, 4, 4] # FSQ quantization levels
|
| 44 |
+
|
| 45 |
+
# Streaming parameters (block-structured attention)
|
| 46 |
+
streaming_params:
|
| 47 |
+
# Block size: number of tokens per block
|
| 48 |
+
block_size: 50
|
| 49 |
+
|
| 50 |
+
# Receptive field: 3 blocks total
|
| 51 |
+
# - Current block (1)
|
| 52 |
+
# - 2-block lookback
|
| 53 |
+
# - 1-block lookahead
|
| 54 |
+
n_lookback_blocks: 2
|
| 55 |
+
n_lookahead_blocks: 1
|
| 56 |
+
|
| 57 |
+
# Enable block-based training for long sequences
|
| 58 |
+
use_block_training: true
|
| 59 |
+
|
| 60 |
+
# DiT architecture
|
| 61 |
+
dit_params:
|
| 62 |
+
# Text encoder (shared between duration and token predictors)
|
| 63 |
+
encoder_layers: 4
|
| 64 |
+
encoder_heads: 8
|
| 65 |
+
|
| 66 |
+
# Duration predictor DiT
|
| 67 |
+
duration_dit_layers: 6
|
| 68 |
+
duration_dit_heads: 8
|
| 69 |
+
|
| 70 |
+
# Token predictor DiT (for CFM velocity estimation)
|
| 71 |
+
token_dit_layers: 6
|
| 72 |
+
token_dit_heads: 8
|
| 73 |
+
|
| 74 |
+
# Flow Matching (for token predictor)
|
| 75 |
+
cfm_params:
|
| 76 |
+
solver_steps: 20 # Number of ODE solver steps
|
| 77 |
+
sigma_min: 1.0e-4 # Minimum noise level
|
| 78 |
+
|
| 79 |
+
# Optimizer
|
| 80 |
+
optimizer_params:
|
| 81 |
+
lr: 1.0e-4
|
| 82 |
+
betas: [0.9, 0.999]
|
| 83 |
+
eps: 1.0e-8
|
| 84 |
+
|
| 85 |
+
# Notes:
|
| 86 |
+
# - BLOCK-STRUCTURED ATTENTION:
|
| 87 |
+
# * The DiT's receptive field is restricted to 3 blocks
|
| 88 |
+
# * Current block + 2 lookback + 1 lookahead
|
| 89 |
+
# * Example: block_size=50 → total receptive field = 4 blocks × 50 = 200 tokens
|
| 90 |
+
# * Structured as discrete blocks, NOT continuous sliding window
|
| 91 |
+
# * Memory: O(N × 4B) where B is block_size
|
| 92 |
+
#
|
| 93 |
+
# - block_size controls the granularity
|
| 94 |
+
# * 50 = each block contains 50 text tokens
|
| 95 |
+
# * Larger = fewer blocks, more tokens per block
|
| 96 |
+
# * Smaller = more blocks, finer granularity
|
| 97 |
+
#
|
| 98 |
+
# - use_block_training enables automatic block creation during training
|
| 99 |
+
# * true = automatically chunk long sequences into blocks with proper masks
|
| 100 |
+
# * false = process full sequences (may OOM on long texts)
|
Configs/config_stage2_masked.yml
ADDED
|
@@ -0,0 +1,69 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
# config_stage2_masked.yml
|
| 2 |
+
# ==============================================================================
|
| 3 |
+
# Configuration for Stage 2 Training: Duration + Masked Token Predictors
|
| 4 |
+
#
|
| 5 |
+
# This config is for training the predictors that work with the
|
| 6 |
+
# HybridTTSCodecVocoderTemporal codec.
|
| 7 |
+
# ==============================================================================
|
| 8 |
+
|
| 9 |
+
# Output directory
|
| 10 |
+
log_dir: "logs_stage2_masked"
|
| 11 |
+
|
| 12 |
+
# Training parameters
|
| 13 |
+
batch_size: 16
|
| 14 |
+
epochs: 100
|
| 15 |
+
lr: 1e-4
|
| 16 |
+
save_freq: 5
|
| 17 |
+
log_interval: 20
|
| 18 |
+
|
| 19 |
+
# Loss weights
|
| 20 |
+
lambda_dur: 1.0
|
| 21 |
+
lambda_token: 1.0
|
| 22 |
+
|
| 23 |
+
# Data parameters
|
| 24 |
+
data_params:
|
| 25 |
+
train_data: "Data/train_3_filtered_dur_fixed_speakers_test.txt"
|
| 26 |
+
val_data: "Data/val_3_filtered_fixed_speakers.txt"
|
| 27 |
+
root_path: "../tts_model"
|
| 28 |
+
min_length: 50
|
| 29 |
+
|
| 30 |
+
# Model parameters
|
| 31 |
+
model_params:
|
| 32 |
+
n_speakers: 4
|
| 33 |
+
speaker_emb_dim: 256
|
| 34 |
+
hidden_dim: 512
|
| 35 |
+
n_token: 178
|
| 36 |
+
codec_stride: 2
|
| 37 |
+
fsq_levels: [4, 4, 4, 4, 4] # Must match codec training
|
| 38 |
+
|
| 39 |
+
# Context parameters (for sliding window)
|
| 40 |
+
context_params:
|
| 41 |
+
n_context_layers: 2
|
| 42 |
+
n_context_heads: 4
|
| 43 |
+
use_context_cross_attn: true
|
| 44 |
+
|
| 45 |
+
# Masked Transformer parameters (for token prediction)
|
| 46 |
+
mask_params:
|
| 47 |
+
n_layers: 8
|
| 48 |
+
n_heads: 8
|
| 49 |
+
dropout: 0.1
|
| 50 |
+
|
| 51 |
+
# Duration predictor parameters
|
| 52 |
+
duration_params:
|
| 53 |
+
use_deterministic_head: false # false = stochastic flow-based
|
| 54 |
+
n_flows: 4
|
| 55 |
+
|
| 56 |
+
# Precomputed tokens (from extract_codec_tokens_hybrid_temporal.py)
|
| 57 |
+
codec_tokens_train: "precomputed_tokens_temporal/codec_tokens_temporal_train.safetensors"
|
| 58 |
+
|
| 59 |
+
# Pretrained models
|
| 60 |
+
pretrained_model: "" # Stage 2 checkpoint to resume from (optional)
|
| 61 |
+
pretrained_hybrid_temporal_codec: "logs_codec_hybrid_temporal/hybrid_temporal_codec_best.pth"
|
| 62 |
+
|
| 63 |
+
# Preprocessing (should match codec config)
|
| 64 |
+
preprocess_params:
|
| 65 |
+
sr: 44100
|
| 66 |
+
spect_params:
|
| 67 |
+
hop_length: 441
|
| 68 |
+
n_fft: 4096
|
| 69 |
+
win_length: 1764
|
Data/OOD_texts.txt
ADDED
|
@@ -0,0 +1,3 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
version https://git-lfs.github.com/spec/v1
|
| 2 |
+
oid sha256:babec1dc6881a3b10ecb11b5de56fae8a02923f831c5d2e2da819841a86a5ecc
|
| 3 |
+
size 15667506
|
Data/add.py
ADDED
|
@@ -0,0 +1,31 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
#!/usr/bin/env python3
|
| 2 |
+
|
| 3 |
+
INPUT_FILE = "fashion_train.txt"
|
| 4 |
+
OUTPUT_FILE = "fashion.txt"
|
| 5 |
+
|
| 6 |
+
def main():
|
| 7 |
+
out_lines = []
|
| 8 |
+
with open(INPUT_FILE, "r", encoding="utf-8") as f:
|
| 9 |
+
for line in f:
|
| 10 |
+
line = line.rstrip("\n")
|
| 11 |
+
if not line.strip():
|
| 12 |
+
continue
|
| 13 |
+
|
| 14 |
+
parts = line.split("|")
|
| 15 |
+
# Expecting: path | phonemes | speaker_id | text
|
| 16 |
+
if len(parts) == 4:
|
| 17 |
+
path, phonemes, speaker_id, text = parts
|
| 18 |
+
new_line = f"{path}|{phonemes}|{speaker_id}|0|{text}"
|
| 19 |
+
out_lines.append(new_line)
|
| 20 |
+
else:
|
| 21 |
+
# If unexpected format, keep line as-is
|
| 22 |
+
out_lines.append(line)
|
| 23 |
+
|
| 24 |
+
with open(OUTPUT_FILE, "w", encoding="utf-8") as f:
|
| 25 |
+
for l in out_lines:
|
| 26 |
+
f.write(l + "\n")
|
| 27 |
+
|
| 28 |
+
print(f"✅ Added language column successfully → {OUTPUT_FILE}")
|
| 29 |
+
|
| 30 |
+
if __name__ == "__main__":
|
| 31 |
+
main()
|
Data/check_list.py
ADDED
|
@@ -0,0 +1,68 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
import os
|
| 2 |
+
import numpy as np
|
| 3 |
+
from scipy.io import wavfile
|
| 4 |
+
|
| 5 |
+
def is_extreme(wav_path, threshold=95):
|
| 6 |
+
"""
|
| 7 |
+
Return True if any sample in wav_path exceeds ±threshold% of full-scale.
|
| 8 |
+
"""
|
| 9 |
+
try:
|
| 10 |
+
_, data = wavfile.read(wav_path)
|
| 11 |
+
except Exception as e:
|
| 12 |
+
print(f"[SKIP] {wav_path!r}: {e}")
|
| 13 |
+
# Treat unreadable files as "extreme" so they're dropped
|
| 14 |
+
return True
|
| 15 |
+
|
| 16 |
+
samples = data.flatten().astype(np.float32)
|
| 17 |
+
dt = data.dtype
|
| 18 |
+
|
| 19 |
+
if dt == np.int16:
|
| 20 |
+
max_val = 32767.0
|
| 21 |
+
elif dt == np.int32:
|
| 22 |
+
max_val = 2147483647.0
|
| 23 |
+
elif dt == np.uint8:
|
| 24 |
+
samples -= 128.0
|
| 25 |
+
max_val = 127.0
|
| 26 |
+
else:
|
| 27 |
+
# assume float32/64 normalized to [-1,1]
|
| 28 |
+
max_val = 1.0
|
| 29 |
+
|
| 30 |
+
thresh_val = (threshold / 100.0) * max_val
|
| 31 |
+
return np.any(samples > thresh_val) or np.any(samples < -thresh_val)
|
| 32 |
+
|
| 33 |
+
def filter_to_new(input_list,
|
| 34 |
+
output_list,
|
| 35 |
+
prefix="../",
|
| 36 |
+
threshold=95):
|
| 37 |
+
"""
|
| 38 |
+
Read input_list, drop lines whose wavs exceed ±threshold%, and
|
| 39 |
+
write the remaining lines to output_list.
|
| 40 |
+
"""
|
| 41 |
+
with open(input_list, "r", encoding="utf-8") as f:
|
| 42 |
+
lines = [L for L in f if L.strip()]
|
| 43 |
+
|
| 44 |
+
kept = []
|
| 45 |
+
for L in lines:
|
| 46 |
+
rel_path = L.split("|", 1)[0].strip()
|
| 47 |
+
wav_path = os.path.join(prefix, rel_path)
|
| 48 |
+
if not os.path.isfile(wav_path):
|
| 49 |
+
print(f"[MISSING] {wav_path}")
|
| 50 |
+
continue
|
| 51 |
+
if is_extreme(wav_path, threshold):
|
| 52 |
+
print(f"[DROP] {wav_path}")
|
| 53 |
+
else:
|
| 54 |
+
kept.append(L)
|
| 55 |
+
|
| 56 |
+
with open(output_list, "w", encoding="utf-8") as f:
|
| 57 |
+
f.writelines(kept)
|
| 58 |
+
|
| 59 |
+
print(f"\nKept {len(kept)} of {len(lines)} entries.")
|
| 60 |
+
print(f"Written filtered list to: {output_list}")
|
| 61 |
+
|
| 62 |
+
if __name__ == "__main__":
|
| 63 |
+
filter_to_new(
|
| 64 |
+
input_list="train_list_filtered.txt",
|
| 65 |
+
output_list="train_list_no_clipped_90.txt",
|
| 66 |
+
prefix="../",
|
| 67 |
+
threshold=90
|
| 68 |
+
)
|
Data/dd.py
ADDED
|
@@ -0,0 +1,123 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
import os
|
| 2 |
+
from phonemizer import backend
|
| 3 |
+
|
| 4 |
+
# Konfiguracja plików
|
| 5 |
+
INPUT_FILE = 'train_3_filtered_dur.txt' # Plik wejściowy
|
| 6 |
+
OUTPUT_FILE = 'train_3_filtered_dur_fixed.txt' # Plik wynikowy
|
| 7 |
+
|
| 8 |
+
# Zestaw znaków, których obecność w fonemach powoduje usunięcie linii
|
| 9 |
+
FORBIDDEN_CHARS = {'{', '}', '(', ')'}
|
| 10 |
+
|
| 11 |
+
def initialize_phonemizers():
|
| 12 |
+
"""
|
| 13 |
+
Inicjalizuje słownik backendów espeak dla wymaganych języków.
|
| 14 |
+
Zwraca słownik { 'language_id': backend_instance }
|
| 15 |
+
"""
|
| 16 |
+
phonemizers = {}
|
| 17 |
+
print("Inicjalizacja phonemizerów (może to chwilę potrwać)...")
|
| 18 |
+
|
| 19 |
+
try:
|
| 20 |
+
# ID 0: Polski
|
| 21 |
+
phonemizers['0'] = backend.EspeakBackend(
|
| 22 |
+
language='pl',
|
| 23 |
+
preserve_punctuation=True,
|
| 24 |
+
with_stress=True
|
| 25 |
+
)
|
| 26 |
+
|
| 27 |
+
# ID 1: Angielski Brytyjski
|
| 28 |
+
phonemizers['1'] = backend.EspeakBackend(
|
| 29 |
+
language='en-gb',
|
| 30 |
+
preserve_punctuation=True,
|
| 31 |
+
with_stress=True
|
| 32 |
+
)
|
| 33 |
+
|
| 34 |
+
# ID 2: Hindi
|
| 35 |
+
phonemizers['2'] = backend.EspeakBackend(
|
| 36 |
+
language='hi',
|
| 37 |
+
preserve_punctuation=True,
|
| 38 |
+
with_stress=True
|
| 39 |
+
)
|
| 40 |
+
|
| 41 |
+
print("Phonemizery zainicjalizowane pomyślnie.")
|
| 42 |
+
return phonemizers
|
| 43 |
+
|
| 44 |
+
except Exception as e:
|
| 45 |
+
print(f"Krytyczny błąd inicjalizacji phonemizerów: {e}")
|
| 46 |
+
print("Upewnij się, że masz zainstalowany 'espeak-ng'.")
|
| 47 |
+
return None
|
| 48 |
+
|
| 49 |
+
def process_dataset():
|
| 50 |
+
# 1. Przygotuj phonemizery
|
| 51 |
+
phonemizers = initialize_phonemizers()
|
| 52 |
+
if not phonemizers:
|
| 53 |
+
return
|
| 54 |
+
|
| 55 |
+
if not os.path.exists(INPUT_FILE):
|
| 56 |
+
print(f"Nie znaleziono pliku: {INPUT_FILE}")
|
| 57 |
+
return
|
| 58 |
+
|
| 59 |
+
print(f"Rozpoczynam przetwarzanie pliku {INPUT_FILE}...")
|
| 60 |
+
|
| 61 |
+
processed_count = 0
|
| 62 |
+
skipped_count = 0
|
| 63 |
+
|
| 64 |
+
with open(INPUT_FILE, 'r', encoding='utf-8') as f_in, \
|
| 65 |
+
open(OUTPUT_FILE, 'w', encoding='utf-8') as f_out:
|
| 66 |
+
|
| 67 |
+
for line_num, line in enumerate(f_in, 1):
|
| 68 |
+
line = line.strip()
|
| 69 |
+
if not line:
|
| 70 |
+
continue
|
| 71 |
+
|
| 72 |
+
# 2. Split z limitem 4
|
| 73 |
+
parts = line.split('|', 4)
|
| 74 |
+
|
| 75 |
+
# Sprawdzenie poprawności struktury (musi być 5 kolumn)
|
| 76 |
+
if len(parts) < 5:
|
| 77 |
+
print(f"Ostrzeżenie: Linia {line_num} ma nieprawidłowy format (pominięto).")
|
| 78 |
+
continue
|
| 79 |
+
|
| 80 |
+
# Wyciągamy potrzebne dane
|
| 81 |
+
# parts[1] = phonemes (to podmieniamy i sprawdzamy)
|
| 82 |
+
lang_id = parts[3]
|
| 83 |
+
raw_text = parts[4]
|
| 84 |
+
|
| 85 |
+
# Pobieramy odpowiedni phonemizer
|
| 86 |
+
current_backend = phonemizers.get(lang_id)
|
| 87 |
+
|
| 88 |
+
if current_backend:
|
| 89 |
+
try:
|
| 90 |
+
# Generowanie fonemów
|
| 91 |
+
phonemes_list = current_backend.phonemize([raw_text], strip=True)
|
| 92 |
+
if phonemes_list:
|
| 93 |
+
parts[1] = phonemes_list[0] # Aktualizacja fonemów
|
| 94 |
+
except Exception as e:
|
| 95 |
+
print(f"Błąd phonemizera w linii {line_num} (ID jęz: {lang_id}): {e}")
|
| 96 |
+
|
| 97 |
+
# --- NOWA LOGIKA FILTROWANIA ---
|
| 98 |
+
current_phonemes = parts[1]
|
| 99 |
+
|
| 100 |
+
# Sprawdzamy czy w fonemach występuje któryś z zakazanych znaków
|
| 101 |
+
if any(char in current_phonemes for char in FORBIDDEN_CHARS):
|
| 102 |
+
skipped_count += 1
|
| 103 |
+
# Opcjonalnie: odkomentuj linię poniżej, jeśli chcesz widzieć, co jest usuwane
|
| 104 |
+
# print(f"Pominięto linię {line_num}: znaleziono zakazany znak w fonemach: {current_phonemes}")
|
| 105 |
+
continue
|
| 106 |
+
|
| 107 |
+
# 3. Zapis do nowego pliku (tylko jeśli walidacja przeszła pomyślnie)
|
| 108 |
+
processed_count += 1
|
| 109 |
+
new_line = "|".join(parts)
|
| 110 |
+
f_out.write(new_line + '\n')
|
| 111 |
+
|
| 112 |
+
# Logowanie postępu co 100 linii
|
| 113 |
+
if processed_count > 0 and processed_count % 100 == 0:
|
| 114 |
+
print(f"Zapisano {processed_count} poprawnych linii...")
|
| 115 |
+
|
| 116 |
+
print("-" * 30)
|
| 117 |
+
print(f"Zakończono!")
|
| 118 |
+
print(f"Poprawnie przetworzono i zapisano: {processed_count}")
|
| 119 |
+
print(f"Usunięto (zawierały '{{', '}}', '(', ')'): {skipped_count}")
|
| 120 |
+
print(f"Wynik zapisano w: {OUTPUT_FILE}")
|
| 121 |
+
|
| 122 |
+
if __name__ == "__main__":
|
| 123 |
+
process_dataset()
|
Data/del_amp.py
ADDED
|
@@ -0,0 +1,58 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
from pathlib import Path
|
| 2 |
+
import numpy as np
|
| 3 |
+
import soundfile as sf
|
| 4 |
+
|
| 5 |
+
# USTAWIENIA (statycznie)
|
| 6 |
+
ROOT_DIR = Path("Dataset") # <- zmień na swoją ścieżkę
|
| 7 |
+
|
| 8 |
+
# Przedziały (włącznie z granicami)
|
| 9 |
+
MIN_SEC = 1.3
|
| 10 |
+
MAX_SEC = 15.0
|
| 11 |
+
|
| 12 |
+
AMP_MIN = 0.01 # minimalny peak |x|
|
| 13 |
+
AMP_MAX = 1.0 # maksymalny peak |x|
|
| 14 |
+
|
| 15 |
+
def iter_wavs(root: Path):
|
| 16 |
+
for p in root.rglob("*.wav"):
|
| 17 |
+
if p.is_file():
|
| 18 |
+
yield p
|
| 19 |
+
|
| 20 |
+
def should_keep(wav: Path) -> bool:
|
| 21 |
+
try:
|
| 22 |
+
data, sr = sf.read(wav, always_2d=True) # shape: (n_samples, n_channels)
|
| 23 |
+
n, _ = data.shape
|
| 24 |
+
if sr <= 0 or n == 0:
|
| 25 |
+
return False
|
| 26 |
+
|
| 27 |
+
# Długość
|
| 28 |
+
dur = n / float(sr)
|
| 29 |
+
if not (MIN_SEC <= dur <= MAX_SEC):
|
| 30 |
+
return False
|
| 31 |
+
|
| 32 |
+
# Peak amplitudy w mono
|
| 33 |
+
mono = data.mean(axis=1).astype(np.float32, copy=False)
|
| 34 |
+
peak = float(np.max(np.abs(mono)))
|
| 35 |
+
|
| 36 |
+
return (AMP_MIN <= peak <= AMP_MAX)
|
| 37 |
+
except Exception:
|
| 38 |
+
return False
|
| 39 |
+
|
| 40 |
+
def main():
|
| 41 |
+
kept = 0
|
| 42 |
+
deleted = 0
|
| 43 |
+
errors = 0
|
| 44 |
+
|
| 45 |
+
for wav in iter_wavs(ROOT_DIR):
|
| 46 |
+
if should_keep(wav):
|
| 47 |
+
kept += 1
|
| 48 |
+
else:
|
| 49 |
+
try:
|
| 50 |
+
wav.unlink() # USUŃ plik niespełniający warunków
|
| 51 |
+
deleted += 1
|
| 52 |
+
except Exception:
|
| 53 |
+
errors += 1
|
| 54 |
+
|
| 55 |
+
print(f"Zachowane: {kept} | Usunięte: {deleted} | Błędy: {errors}")
|
| 56 |
+
|
| 57 |
+
if __name__ == "__main__":
|
| 58 |
+
main()
|
Data/delete_silence.py
ADDED
|
@@ -0,0 +1,22 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
#!/usr/bin/env python3
|
| 2 |
+
import os
|
| 3 |
+
import numpy as np
|
| 4 |
+
import soundfile as sf
|
| 5 |
+
|
| 6 |
+
# Ścieżka do katalogu wavs
|
| 7 |
+
base_dir = 'Dataset/wavs'
|
| 8 |
+
# Próg amplitudy – pliki, które nie mają próbki > threshold, zostaną usunięte
|
| 9 |
+
threshold = 0.07
|
| 10 |
+
|
| 11 |
+
# Iteruj przez wszystkie podfoldery i pliki
|
| 12 |
+
for root, dirs, files in os.walk(base_dir):
|
| 13 |
+
for file in files:
|
| 14 |
+
if not file.lower().endswith('.wav'):
|
| 15 |
+
continue
|
| 16 |
+
full_path = os.path.join(root, file).replace('\\', '/')
|
| 17 |
+
# Wczytaj dane audio (może być wielokanałowe)
|
| 18 |
+
data, sr = sf.read(full_path)
|
| 19 |
+
# Jeśli nie ma próbki przekraczającej threshold → usuń
|
| 20 |
+
if not np.any(np.abs(data) > threshold):
|
| 21 |
+
print(f"Usuwam: {full_path}")
|
| 22 |
+
os.remove(full_path)
|
Data/fashion.txt
ADDED
|
The diff for this file is too large to render.
See raw diff
|
|
|
Data/fashion_train.txt
ADDED
|
The diff for this file is too large to render.
See raw diff
|
|
|
Data/filet_train.py
ADDED
|
@@ -0,0 +1,332 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
import os
|
| 2 |
+
import wave
|
| 3 |
+
import numpy as np
|
| 4 |
+
import subprocess
|
| 5 |
+
import tempfile
|
| 6 |
+
|
| 7 |
+
|
| 8 |
+
def filter_audio_list(
|
| 9 |
+
input_path="train_list.txt",
|
| 10 |
+
output_path="train_list_filtered.txt",
|
| 11 |
+
min_duration_sec=1.25,
|
| 12 |
+
max_duration_sec=10.0,
|
| 13 |
+
min_amplitude_threshold=0.02,
|
| 14 |
+
max_amplitude_threshold=0.94,
|
| 15 |
+
ffmpeg_path="ffmpeg",
|
| 16 |
+
):
|
| 17 |
+
"""
|
| 18 |
+
Filter lines in input_path according to duration and amplitude checks.
|
| 19 |
+
Removes duplicate paths: if a given .wav path appears more than once in the
|
| 20 |
+
input file, ALL occurrences are removed from the output.
|
| 21 |
+
"""
|
| 22 |
+
if not os.path.exists(input_path):
|
| 23 |
+
print(f"Error: Input file not found at '{input_path}'")
|
| 24 |
+
return
|
| 25 |
+
|
| 26 |
+
kept_lines = []
|
| 27 |
+
removed_count = 0
|
| 28 |
+
total_count = 0
|
| 29 |
+
|
| 30 |
+
print(f"Starting to process '{input_path}'...")
|
| 31 |
+
print(f" - Minimum duration: {min_duration_sec}s")
|
| 32 |
+
print(f" - Maximum duration: {max_duration_sec}s")
|
| 33 |
+
print(f" - Minimum amplitude: {min_amplitude_threshold}")
|
| 34 |
+
print(f" - Maximum amplitude: {max_amplitude_threshold}")
|
| 35 |
+
print(
|
| 36 |
+
f" - Target format: 44.1kHz, 16-bit PCM, mono "
|
| 37 |
+
f"(will convert using {ffmpeg_path})"
|
| 38 |
+
)
|
| 39 |
+
|
| 40 |
+
# Read input lines (preserve full line content for output)
|
| 41 |
+
with open(input_path, "r", encoding="utf-8") as f:
|
| 42 |
+
raw_lines = f.readlines()
|
| 43 |
+
|
| 44 |
+
# Build canonical path for each non-empty line so we can detect duplicates
|
| 45 |
+
base_dir = os.path.dirname(os.path.abspath(input_path)) or os.getcwd()
|
| 46 |
+
canon_for_line = [None] * len(raw_lines)
|
| 47 |
+
canon_to_indices = {}
|
| 48 |
+
|
| 49 |
+
for idx, raw in enumerate(raw_lines):
|
| 50 |
+
ln = raw.strip()
|
| 51 |
+
if not ln:
|
| 52 |
+
continue
|
| 53 |
+
audio_rel = ln.split("|")[0].strip()
|
| 54 |
+
# Match original behavior of prefixing "../" relative to the input file
|
| 55 |
+
candidate = os.path.join(base_dir, "..", audio_rel)
|
| 56 |
+
canonical = os.path.realpath(os.path.abspath(candidate))
|
| 57 |
+
canon_for_line[idx] = canonical
|
| 58 |
+
canon_to_indices.setdefault(canonical, []).append(idx)
|
| 59 |
+
|
| 60 |
+
# Identify duplicate canonical paths (appear more than once)
|
| 61 |
+
duplicates_canonical = {p for p, idxs in canon_to_indices.items() if len(idxs) > 1}
|
| 62 |
+
if duplicates_canonical:
|
| 63 |
+
print(
|
| 64 |
+
f" [Deduplication] Found {len(duplicates_canonical)} duplicate "
|
| 65 |
+
"path(s). All occurrences will be removed."
|
| 66 |
+
)
|
| 67 |
+
for p in sorted(duplicates_canonical):
|
| 68 |
+
print(f" - {p} (occurrences={len(canon_to_indices[p])})")
|
| 69 |
+
|
| 70 |
+
# Process lines, skipping duplicates early
|
| 71 |
+
for idx, raw in enumerate(raw_lines):
|
| 72 |
+
total_count += 1
|
| 73 |
+
line = raw.strip()
|
| 74 |
+
if not line:
|
| 75 |
+
continue
|
| 76 |
+
|
| 77 |
+
canonical = canon_for_line[idx]
|
| 78 |
+
if canonical in duplicates_canonical:
|
| 79 |
+
# remove duplicate occurrences (do not keep any of them)
|
| 80 |
+
print(f" [Removing] Duplicate entry: {line.split('|')[0].strip()}")
|
| 81 |
+
removed_count += 1
|
| 82 |
+
continue
|
| 83 |
+
|
| 84 |
+
# Use the canonical absolute path for filesystem operations
|
| 85 |
+
audio_path = canonical
|
| 86 |
+
|
| 87 |
+
try:
|
| 88 |
+
if not os.path.exists(audio_path):
|
| 89 |
+
print(f" [Warning] File not found, skipping: {audio_path}")
|
| 90 |
+
removed_count += 1
|
| 91 |
+
continue
|
| 92 |
+
|
| 93 |
+
# Try to open as WAV; if not readable, convert with ffmpeg
|
| 94 |
+
try:
|
| 95 |
+
wav_file = wave.open(audio_path, "rb")
|
| 96 |
+
except wave.Error:
|
| 97 |
+
print(
|
| 98 |
+
f" [Converting] Not a readable WAV: converting {audio_path} -> "
|
| 99 |
+
"44.1kHz 16-bit mono WAV"
|
| 100 |
+
)
|
| 101 |
+
tmp = tempfile.NamedTemporaryFile(delete=False, suffix=".wav")
|
| 102 |
+
tmp.close()
|
| 103 |
+
cmd = [
|
| 104 |
+
ffmpeg_path,
|
| 105 |
+
"-y",
|
| 106 |
+
"-i",
|
| 107 |
+
audio_path,
|
| 108 |
+
"-ar",
|
| 109 |
+
"44100",
|
| 110 |
+
"-ac",
|
| 111 |
+
"1",
|
| 112 |
+
"-acodec",
|
| 113 |
+
"pcm_s16le",
|
| 114 |
+
tmp.name,
|
| 115 |
+
]
|
| 116 |
+
proc = subprocess.run(
|
| 117 |
+
cmd, stdout=subprocess.PIPE, stderr=subprocess.PIPE
|
| 118 |
+
)
|
| 119 |
+
if proc.returncode != 0:
|
| 120 |
+
stderr = proc.stderr.decode("utf-8", errors="replace")
|
| 121 |
+
print(
|
| 122 |
+
f" [Error] ffmpeg conversion failed for {audio_path}: "
|
| 123 |
+
f"{stderr}"
|
| 124 |
+
)
|
| 125 |
+
removed_count += 1
|
| 126 |
+
try:
|
| 127 |
+
os.unlink(tmp.name)
|
| 128 |
+
except Exception:
|
| 129 |
+
pass
|
| 130 |
+
continue
|
| 131 |
+
|
| 132 |
+
try:
|
| 133 |
+
os.replace(tmp.name, audio_path)
|
| 134 |
+
except Exception as e:
|
| 135 |
+
print(
|
| 136 |
+
f" [Error] Could not replace original with converted file: "
|
| 137 |
+
f"{e}"
|
| 138 |
+
)
|
| 139 |
+
removed_count += 1
|
| 140 |
+
try:
|
| 141 |
+
os.unlink(tmp.name)
|
| 142 |
+
except Exception:
|
| 143 |
+
pass
|
| 144 |
+
continue
|
| 145 |
+
|
| 146 |
+
try:
|
| 147 |
+
wav_file = wave.open(audio_path, "rb")
|
| 148 |
+
except wave.Error as e:
|
| 149 |
+
print(
|
| 150 |
+
f" [Warning] Still cannot open after conversion: "
|
| 151 |
+
f"{audio_path} ({e})"
|
| 152 |
+
)
|
| 153 |
+
removed_count += 1
|
| 154 |
+
continue
|
| 155 |
+
|
| 156 |
+
# Read header info then close
|
| 157 |
+
try:
|
| 158 |
+
num_frames = wav_file.getnframes()
|
| 159 |
+
framerate = wav_file.getframerate()
|
| 160 |
+
sampwidth = wav_file.getsampwidth()
|
| 161 |
+
n_channels = wav_file.getnchannels()
|
| 162 |
+
finally:
|
| 163 |
+
try:
|
| 164 |
+
wav_file.close()
|
| 165 |
+
except Exception:
|
| 166 |
+
pass
|
| 167 |
+
|
| 168 |
+
# Convert to target format if needed
|
| 169 |
+
needs_conversion = (
|
| 170 |
+
framerate != 44100 or sampwidth != 2 or n_channels != 1
|
| 171 |
+
)
|
| 172 |
+
if needs_conversion:
|
| 173 |
+
print(
|
| 174 |
+
f" [Converting] {audio_path} (sr={framerate}, sw={sampwidth}, "
|
| 175 |
+
f"ch={n_channels}) -> 44.1kHz 16-bit mono"
|
| 176 |
+
)
|
| 177 |
+
tmp = tempfile.NamedTemporaryFile(delete=False, suffix=".wav")
|
| 178 |
+
tmp.close()
|
| 179 |
+
cmd = [
|
| 180 |
+
ffmpeg_path,
|
| 181 |
+
"-y",
|
| 182 |
+
"-i",
|
| 183 |
+
audio_path,
|
| 184 |
+
"-ar",
|
| 185 |
+
"44100",
|
| 186 |
+
"-ac",
|
| 187 |
+
"1",
|
| 188 |
+
"-acodec",
|
| 189 |
+
"pcm_s16le",
|
| 190 |
+
tmp.name,
|
| 191 |
+
]
|
| 192 |
+
proc = subprocess.run(
|
| 193 |
+
cmd, stdout=subprocess.PIPE, stderr=subprocess.PIPE
|
| 194 |
+
)
|
| 195 |
+
if proc.returncode != 0:
|
| 196 |
+
stderr = proc.stderr.decode("utf-8", errors="replace")
|
| 197 |
+
print(
|
| 198 |
+
f" [Error] ffmpeg conversion failed for {audio_path}: "
|
| 199 |
+
f"{stderr}"
|
| 200 |
+
)
|
| 201 |
+
removed_count += 1
|
| 202 |
+
try:
|
| 203 |
+
os.unlink(tmp.name)
|
| 204 |
+
except Exception:
|
| 205 |
+
pass
|
| 206 |
+
continue
|
| 207 |
+
|
| 208 |
+
try:
|
| 209 |
+
os.replace(tmp.name, audio_path)
|
| 210 |
+
except Exception as e:
|
| 211 |
+
print(
|
| 212 |
+
f" [Error] Could not replace original with converted file: "
|
| 213 |
+
f"{e}"
|
| 214 |
+
)
|
| 215 |
+
removed_count += 1
|
| 216 |
+
try:
|
| 217 |
+
os.unlink(tmp.name)
|
| 218 |
+
except Exception:
|
| 219 |
+
pass
|
| 220 |
+
continue
|
| 221 |
+
|
| 222 |
+
# Open the (possibly converted) WAV and perform checks
|
| 223 |
+
try:
|
| 224 |
+
with wave.open(audio_path, "rb") as wf:
|
| 225 |
+
num_frames = wf.getnframes()
|
| 226 |
+
framerate = wf.getframerate()
|
| 227 |
+
sampwidth = wf.getsampwidth()
|
| 228 |
+
n_channels = wf.getnchannels()
|
| 229 |
+
|
| 230 |
+
# Duration checks
|
| 231 |
+
duration = num_frames / float(framerate)
|
| 232 |
+
if duration < min_duration_sec:
|
| 233 |
+
print(
|
| 234 |
+
f" [Removing] Short duration: {audio_path} "
|
| 235 |
+
f"({duration:.2f}s)"
|
| 236 |
+
)
|
| 237 |
+
removed_count += 1
|
| 238 |
+
continue
|
| 239 |
+
|
| 240 |
+
if duration > max_duration_sec:
|
| 241 |
+
print(
|
| 242 |
+
f" [Removing] Too long: {audio_path} "
|
| 243 |
+
f"({duration:.2f}s > {max_duration_sec}s)"
|
| 244 |
+
)
|
| 245 |
+
removed_count += 1
|
| 246 |
+
continue
|
| 247 |
+
|
| 248 |
+
# Amplitude check (16-bit PCM)
|
| 249 |
+
if sampwidth == 2:
|
| 250 |
+
frames = wf.readframes(num_frames)
|
| 251 |
+
if not frames:
|
| 252 |
+
print(f" [Removing] Empty audio: {audio_path}")
|
| 253 |
+
removed_count += 1
|
| 254 |
+
continue
|
| 255 |
+
|
| 256 |
+
samples = np.frombuffer(frames, dtype=np.int16)
|
| 257 |
+
if samples.size == 0:
|
| 258 |
+
print(f" [Removing] Empty samples: {audio_path}")
|
| 259 |
+
removed_count += 1
|
| 260 |
+
continue
|
| 261 |
+
|
| 262 |
+
normalized_samples = samples.astype(np.float32) / 32768.0
|
| 263 |
+
max_abs_amplitude = float(
|
| 264 |
+
np.max(np.abs(normalized_samples))
|
| 265 |
+
)
|
| 266 |
+
|
| 267 |
+
if max_abs_amplitude > max_amplitude_threshold:
|
| 268 |
+
print(
|
| 269 |
+
f" [Removing] High amplitude: {audio_path} "
|
| 270 |
+
f"(Peak: {max_abs_amplitude:.2f})"
|
| 271 |
+
)
|
| 272 |
+
removed_count += 1
|
| 273 |
+
continue
|
| 274 |
+
|
| 275 |
+
if max_abs_amplitude < min_amplitude_threshold:
|
| 276 |
+
print(
|
| 277 |
+
f" [Removing] Low amplitude: {audio_path} "
|
| 278 |
+
f"(Peak: {max_abs_amplitude:.2f})"
|
| 279 |
+
)
|
| 280 |
+
removed_count += 1
|
| 281 |
+
continue
|
| 282 |
+
else:
|
| 283 |
+
print(
|
| 284 |
+
f" [Info] Skipping amplitude check for {audio_path} "
|
| 285 |
+
f"(sample width: {sampwidth})"
|
| 286 |
+
)
|
| 287 |
+
|
| 288 |
+
except wave.Error as e:
|
| 289 |
+
print(
|
| 290 |
+
f" [Warning] Could not read WAV after conversion/open: "
|
| 291 |
+
f"{audio_path} ({e})"
|
| 292 |
+
)
|
| 293 |
+
removed_count += 1
|
| 294 |
+
continue
|
| 295 |
+
|
| 296 |
+
# Passed all checks
|
| 297 |
+
kept_lines.append(line + "\n")
|
| 298 |
+
|
| 299 |
+
except wave.Error as e:
|
| 300 |
+
print(
|
| 301 |
+
f" [Warning] Could not read WAV file, skipping: {audio_path} ({e})"
|
| 302 |
+
)
|
| 303 |
+
removed_count += 1
|
| 304 |
+
except FileNotFoundError as e:
|
| 305 |
+
print(f" [Warning] File disappeared, skipping: {audio_path} ({e})")
|
| 306 |
+
removed_count += 1
|
| 307 |
+
except Exception as e:
|
| 308 |
+
print(f" [Error] An unexpected error occurred on line: {line}")
|
| 309 |
+
print(f" {e}")
|
| 310 |
+
removed_count += 1
|
| 311 |
+
|
| 312 |
+
with open(output_path, "w", encoding="utf-8") as f:
|
| 313 |
+
f.writelines(kept_lines)
|
| 314 |
+
|
| 315 |
+
print("\n--- Processing Complete ---")
|
| 316 |
+
print(f"Total entries processed: {total_count}")
|
| 317 |
+
print(f"Entries kept: {len(kept_lines)}")
|
| 318 |
+
print(f"Entries removed (duration/amplitude/errors/dupes): {removed_count}")
|
| 319 |
+
print(f"Filtered list saved to: '{output_path}'")
|
| 320 |
+
|
| 321 |
+
|
| 322 |
+
if __name__ == "__main__":
|
| 323 |
+
# Ensure numpy and ffmpeg are available.
|
| 324 |
+
filter_audio_list(
|
| 325 |
+
input_path="train_3_filtered.txt",
|
| 326 |
+
output_path="train_3_filtered_1.txt",
|
| 327 |
+
min_duration_sec=1.25,
|
| 328 |
+
max_duration_sec=10.0,
|
| 329 |
+
min_amplitude_threshold=0.02,
|
| 330 |
+
max_amplitude_threshold=0.93,
|
| 331 |
+
ffmpeg_path="ffmpeg",
|
| 332 |
+
)
|
Data/finalfinal.txt
ADDED
|
@@ -0,0 +1,3 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
version https://git-lfs.github.com/spec/v1
|
| 2 |
+
oid sha256:8461bf253498a394a29ab7a017345f8d6ea09b57f7cd96e2705db5efd4740773
|
| 3 |
+
size 47296629
|
Data/harry.txt
ADDED
|
@@ -0,0 +1,3 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
version https://git-lfs.github.com/spec/v1
|
| 2 |
+
oid sha256:ebc9b1e699756f324fda10aad71573d4a4b026cf3fcaa29f42b55578b77f8937
|
| 3 |
+
size 16283722
|
Data/luf_norm.py
ADDED
|
@@ -0,0 +1,429 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
#!/usr/bin/env python3
|
| 2 |
+
"""
|
| 3 |
+
Batch LUFS normalization using ffmpeg (two-pass loudnorm), enforcing a peak
|
| 4 |
+
limit (default linear 0.93) and converting to 44.1 kHz, mono, PCM 16-bit.
|
| 5 |
+
Recursively processes all .wav files under a directory, atomically overwrites
|
| 6 |
+
originals, and deletes any files that fail processing. Logs results to CSV.
|
| 7 |
+
|
| 8 |
+
Important:
|
| 9 |
+
- Requires ffmpeg in PATH (ffmpeg loudnorm). Recommended ffmpeg >= 4.x.
|
| 10 |
+
- Requires Python packages: soundfile, numpy
|
| 11 |
+
Install with: pip install soundfile numpy
|
| 12 |
+
|
| 13 |
+
Usage examples:
|
| 14 |
+
python luf_norm_ffmpeg_no_quarantine.py --input ../Dataset
|
| 15 |
+
python luf_norm_ffmpeg_no_quarantine.py --input ../Dataset --target -18.0 --peak 0.93
|
| 16 |
+
python luf_norm_ffmpeg_no_quarantine.py --input ../Dataset --workers 4
|
| 17 |
+
"""
|
| 18 |
+
from __future__ import annotations
|
| 19 |
+
|
| 20 |
+
import argparse
|
| 21 |
+
import csv
|
| 22 |
+
import json
|
| 23 |
+
import os
|
| 24 |
+
import re
|
| 25 |
+
import shutil
|
| 26 |
+
import subprocess
|
| 27 |
+
import tempfile
|
| 28 |
+
import uuid
|
| 29 |
+
from functools import partial
|
| 30 |
+
from multiprocessing import Pool
|
| 31 |
+
from pathlib import Path
|
| 32 |
+
from typing import Dict, Optional
|
| 33 |
+
|
| 34 |
+
import numpy as np
|
| 35 |
+
import soundfile as sf
|
| 36 |
+
|
| 37 |
+
# Regex used to extract JSON printed by ffmpeg loudnorm (it prints a JSON block to stderr)
|
| 38 |
+
_JSON_RE = re.compile(r"\{[\s\S]*?\}", re.MULTILINE)
|
| 39 |
+
|
| 40 |
+
|
| 41 |
+
def find_wav_files(root: Path):
|
| 42 |
+
return sorted(root.rglob("*.wav"))
|
| 43 |
+
|
| 44 |
+
|
| 45 |
+
def _extract_loudnorm_json(stderr_text: str) -> Dict:
|
| 46 |
+
matches = list(_JSON_RE.finditer(stderr_text))
|
| 47 |
+
if not matches:
|
| 48 |
+
raise RuntimeError("ffmpeg loudnorm did not produce JSON measurement in stderr")
|
| 49 |
+
# Use last JSON block
|
| 50 |
+
js = matches[-1].group(0)
|
| 51 |
+
return json.loads(js)
|
| 52 |
+
|
| 53 |
+
|
| 54 |
+
def ffmpeg_measure(in_path: Path, target_lufs: float, tp_db: float) -> Dict:
|
| 55 |
+
"""
|
| 56 |
+
First-pass: run ffmpeg loudnorm with print_format=json to get measurement.
|
| 57 |
+
Returns parsed measurement dict.
|
| 58 |
+
"""
|
| 59 |
+
cmd = [
|
| 60 |
+
"ffmpeg",
|
| 61 |
+
"-hide_banner",
|
| 62 |
+
"-nostats",
|
| 63 |
+
"-y",
|
| 64 |
+
"-i",
|
| 65 |
+
str(in_path),
|
| 66 |
+
"-af",
|
| 67 |
+
f"loudnorm=I={target_lufs}:TP={tp_db}:LRA=7:print_format=json",
|
| 68 |
+
"-ar",
|
| 69 |
+
"44100",
|
| 70 |
+
"-ac",
|
| 71 |
+
"1",
|
| 72 |
+
"-f",
|
| 73 |
+
"null",
|
| 74 |
+
"-",
|
| 75 |
+
]
|
| 76 |
+
proc = subprocess.run(cmd, stdout=subprocess.PIPE, stderr=subprocess.PIPE, text=True)
|
| 77 |
+
if proc.returncode != 0:
|
| 78 |
+
raise RuntimeError(f"ffmpeg measure failed (rc={proc.returncode}): {proc.stderr.splitlines()[-20:]}")
|
| 79 |
+
return _extract_loudnorm_json(proc.stderr)
|
| 80 |
+
|
| 81 |
+
|
| 82 |
+
def ffmpeg_apply_second_pass(in_path: Path, out_path: Path, target_lufs: float, tp_db: float, measured: Dict, use_limiter: bool = False, limiter_db: Optional[float] = None):
|
| 83 |
+
"""
|
| 84 |
+
Second pass: apply loudnorm with measured_* values to produce normalized output.
|
| 85 |
+
If use_limiter True, append an alimiter with limit=limiter_db (dB) after loudnorm.
|
| 86 |
+
Writes to out_path (wav).
|
| 87 |
+
"""
|
| 88 |
+
# Required measured fields for the second pass
|
| 89 |
+
measured_I = measured.get("input_i")
|
| 90 |
+
measured_TP = measured.get("input_tp")
|
| 91 |
+
measured_LRA = measured.get("input_lra")
|
| 92 |
+
measured_thresh = measured.get("input_thresh")
|
| 93 |
+
target_offset = measured.get("target_offset", 0.0)
|
| 94 |
+
|
| 95 |
+
if None in (measured_I, measured_TP, measured_LRA, measured_thresh):
|
| 96 |
+
raise RuntimeError(f"Missing measured fields for second pass: {measured}")
|
| 97 |
+
|
| 98 |
+
# Build audio filter string
|
| 99 |
+
af = (
|
| 100 |
+
f"loudnorm=I={target_lufs}:TP={tp_db}:LRA=7:"
|
| 101 |
+
f"measured_I={measured_I}:measured_TP={measured_TP}:measured_LRA={measured_LRA}:"
|
| 102 |
+
f"measured_thresh={measured_thresh}:offset={target_offset}"
|
| 103 |
+
)
|
| 104 |
+
if use_limiter:
|
| 105 |
+
if limiter_db is None:
|
| 106 |
+
raise RuntimeError("Limiter requested but limiter_db is None")
|
| 107 |
+
# alimiter.limit expects a linear amplitude in [0.0625, 1], not dB.
|
| 108 |
+
linear_limit = float(10 ** (limiter_db / 20.0))
|
| 109 |
+
# Clamp to valid range to avoid ffmpeg errors
|
| 110 |
+
linear_limit = max(0.0625, min(1.0, linear_limit))
|
| 111 |
+
af = f"{af},alimiter=limit={linear_limit}"
|
| 112 |
+
cmd = [
|
| 113 |
+
"ffmpeg",
|
| 114 |
+
"-hide_banner",
|
| 115 |
+
"-nostats",
|
| 116 |
+
"-y",
|
| 117 |
+
"-i",
|
| 118 |
+
str(in_path),
|
| 119 |
+
"-af",
|
| 120 |
+
af,
|
| 121 |
+
"-ar",
|
| 122 |
+
"44100",
|
| 123 |
+
"-ac",
|
| 124 |
+
"1",
|
| 125 |
+
"-c:a",
|
| 126 |
+
"pcm_s16le",
|
| 127 |
+
str(out_path),
|
| 128 |
+
]
|
| 129 |
+
proc = subprocess.run(cmd, stdout=subprocess.PIPE, stderr=subprocess.PIPE, text=True)
|
| 130 |
+
if proc.returncode != 0:
|
| 131 |
+
# include some stderr context for debugging
|
| 132 |
+
raise RuntimeError(f"ffmpeg apply failed (rc={proc.returncode}). stderr excerpt: {proc.stderr.splitlines()[-40:]}")
|
| 133 |
+
|
| 134 |
+
|
| 135 |
+
def _unique_dest(dest: Path) -> Path:
|
| 136 |
+
"""Return a unique path by appending a short uuid if dest exists."""
|
| 137 |
+
if not dest.exists():
|
| 138 |
+
return dest
|
| 139 |
+
stem = dest.stem
|
| 140 |
+
suffix = dest.suffix
|
| 141 |
+
parent = dest.parent
|
| 142 |
+
while True:
|
| 143 |
+
new_name = f"{stem}_{uuid.uuid4().hex[:8]}{suffix}"
|
| 144 |
+
candidate = parent / new_name
|
| 145 |
+
if not candidate.exists():
|
| 146 |
+
return candidate
|
| 147 |
+
|
| 148 |
+
|
| 149 |
+
def atomic_replace(tmp_path: Path, dest: Path):
|
| 150 |
+
"""
|
| 151 |
+
Atomically replace dest with tmp_path. tmp_path should exist.
|
| 152 |
+
"""
|
| 153 |
+
try:
|
| 154 |
+
os.replace(str(tmp_path), str(dest))
|
| 155 |
+
except Exception:
|
| 156 |
+
# fallback to move
|
| 157 |
+
shutil.move(str(tmp_path), str(dest))
|
| 158 |
+
|
| 159 |
+
|
| 160 |
+
def validate_audio_and_get_peak(path: Path) -> Dict:
|
| 161 |
+
"""
|
| 162 |
+
Read audio file and return dict with sr, channels, peak, and whether samples are finite.
|
| 163 |
+
"""
|
| 164 |
+
data, sr = sf.read(str(path), dtype="float32", always_2d=False)
|
| 165 |
+
channels = 1 if data.ndim == 1 else int(data.shape[1])
|
| 166 |
+
mono = data if data.ndim == 1 else np.mean(data, axis=1)
|
| 167 |
+
finite = bool(np.all(np.isfinite(mono)))
|
| 168 |
+
peak = float(np.max(np.abs(mono))) if mono.size else 0.0
|
| 169 |
+
return {"sr": int(sr), "channels": channels, "finite": finite, "peak": peak}
|
| 170 |
+
|
| 171 |
+
|
| 172 |
+
def process_one(in_path: Path, target_lufs: float, peak_linear: float, workers_idx: int = 0) -> Dict:
|
| 173 |
+
"""
|
| 174 |
+
Process a single file:
|
| 175 |
+
- 1st pass measure (ffmpeg loudnorm print json)
|
| 176 |
+
- 2nd pass apply loudnorm using measured values -> tmp out
|
| 177 |
+
- validate tmp out; if peak > peak_linear then re-run second pass with limiter
|
| 178 |
+
- if still invalid or non-finite, delete original and record error
|
| 179 |
+
- otherwise atomically overwrite original with tmp out
|
| 180 |
+
Returns a record dict for CSV logging.
|
| 181 |
+
"""
|
| 182 |
+
rec = {
|
| 183 |
+
"path": str(in_path),
|
| 184 |
+
"input_i": None,
|
| 185 |
+
"input_tp": None,
|
| 186 |
+
"input_lra": None,
|
| 187 |
+
"input_thresh": None,
|
| 188 |
+
"target_offset": None,
|
| 189 |
+
"final_lufs": None, # may be filled from measured output_i if present
|
| 190 |
+
"final_peak": None,
|
| 191 |
+
"sr": None,
|
| 192 |
+
"channels": None,
|
| 193 |
+
"deleted": False,
|
| 194 |
+
"error": None,
|
| 195 |
+
}
|
| 196 |
+
|
| 197 |
+
try:
|
| 198 |
+
# compute dBTP from linear peak
|
| 199 |
+
tp_db = 20.0 * np.log10(peak_linear) if peak_linear > 0 else -999.0
|
| 200 |
+
limiter_db = tp_db # limiter in dB to use if reprocessing needed
|
| 201 |
+
|
| 202 |
+
# 1) Measure
|
| 203 |
+
measured = ffmpeg_measure(in_path, target_lufs, tp_db)
|
| 204 |
+
|
| 205 |
+
# record measured fields if available
|
| 206 |
+
rec["input_i"] = measured.get("input_i")
|
| 207 |
+
rec["input_tp"] = measured.get("input_tp")
|
| 208 |
+
rec["input_lra"] = measured.get("input_lra")
|
| 209 |
+
rec["input_thresh"] = measured.get("input_thresh")
|
| 210 |
+
rec["target_offset"] = measured.get("target_offset")
|
| 211 |
+
|
| 212 |
+
# Use a temp file in same directory to write output, then atomic replace
|
| 213 |
+
out_tmp = Path(in_path.parent) / (in_path.stem + f".tmp_{uuid.uuid4().hex[:8]}.wav")
|
| 214 |
+
|
| 215 |
+
# 2) Second pass: apply loudnorm (no limiter first)
|
| 216 |
+
try:
|
| 217 |
+
ffmpeg_apply_second_pass(in_path, out_tmp, target_lufs, tp_db, measured, use_limiter=False)
|
| 218 |
+
except Exception as e:
|
| 219 |
+
# second pass failed -> delete the original and record error
|
| 220 |
+
rec["error"] = f"ffmpeg second pass failed: {e}"
|
| 221 |
+
try:
|
| 222 |
+
in_path.unlink()
|
| 223 |
+
rec["deleted"] = True
|
| 224 |
+
except Exception as e2:
|
| 225 |
+
rec["error"] += f"; failed deleting original: {e2}"
|
| 226 |
+
# cleanup tmp if present
|
| 227 |
+
if out_tmp.exists():
|
| 228 |
+
try:
|
| 229 |
+
out_tmp.unlink()
|
| 230 |
+
except Exception:
|
| 231 |
+
pass
|
| 232 |
+
return rec
|
| 233 |
+
|
| 234 |
+
# 3) validate output
|
| 235 |
+
try:
|
| 236 |
+
info = validate_audio_and_get_peak(out_tmp)
|
| 237 |
+
rec["sr"] = info["sr"]
|
| 238 |
+
rec["channels"] = info["channels"]
|
| 239 |
+
rec["final_peak"] = float(info["peak"])
|
| 240 |
+
if not info["finite"]:
|
| 241 |
+
raise RuntimeError("Non-finite samples in ffmpeg output")
|
| 242 |
+
except Exception as e:
|
| 243 |
+
rec["error"] = (rec["error"] + "; " if rec["error"] else "") + f"Validation failed after second pass: {e}"
|
| 244 |
+
try:
|
| 245 |
+
in_path.unlink()
|
| 246 |
+
rec["deleted"] = True
|
| 247 |
+
except Exception as e2:
|
| 248 |
+
rec["error"] += f"; failed deleting original: {e2}"
|
| 249 |
+
if out_tmp.exists():
|
| 250 |
+
try:
|
| 251 |
+
out_tmp.unlink()
|
| 252 |
+
except Exception:
|
| 253 |
+
pass
|
| 254 |
+
return rec
|
| 255 |
+
|
| 256 |
+
# 4) If peak > peak_linear (allow tiny epsilon), re-run with limiter
|
| 257 |
+
eps = 1e-6
|
| 258 |
+
if rec["final_peak"] > peak_linear + eps:
|
| 259 |
+
# Run second pass again but append alimiter to ensure peaks are clamped
|
| 260 |
+
# write to a new temporary file
|
| 261 |
+
out_tmp2 = Path(in_path.parent) / (in_path.stem + f".tmp_lim_{uuid.uuid4().hex[:8]}.wav")
|
| 262 |
+
try:
|
| 263 |
+
ffmpeg_apply_second_pass(in_path, out_tmp2, target_lufs, tp_db, measured, use_limiter=True, limiter_db=limiter_db)
|
| 264 |
+
except Exception as e:
|
| 265 |
+
rec["error"] = (rec["error"] + "; " if rec["error"] else "") + f"ffmpeg limiter pass failed: {e}"
|
| 266 |
+
# delete original and cleanup
|
| 267 |
+
try:
|
| 268 |
+
in_path.unlink()
|
| 269 |
+
rec["deleted"] = True
|
| 270 |
+
except Exception as e2:
|
| 271 |
+
rec["error"] += f"; failed deleting original: {e2}"
|
| 272 |
+
# cleanup temp files
|
| 273 |
+
for t in (out_tmp, out_tmp2):
|
| 274 |
+
if t.exists():
|
| 275 |
+
try:
|
| 276 |
+
t.unlink()
|
| 277 |
+
except Exception:
|
| 278 |
+
pass
|
| 279 |
+
return rec
|
| 280 |
+
|
| 281 |
+
# validate out_tmp2
|
| 282 |
+
try:
|
| 283 |
+
info2 = validate_audio_and_get_peak(out_tmp2)
|
| 284 |
+
rec["sr"] = info2["sr"]
|
| 285 |
+
rec["channels"] = info2["channels"]
|
| 286 |
+
rec["final_peak"] = float(info2["peak"])
|
| 287 |
+
if not info2["finite"]:
|
| 288 |
+
raise RuntimeError("Non-finite samples in limiter output")
|
| 289 |
+
# if still above limit, treat as error
|
| 290 |
+
if rec["final_peak"] > peak_linear + eps:
|
| 291 |
+
raise RuntimeError(f"Peak still above limit after limiter: {rec['final_peak']:.6f} > {peak_linear:.6f}")
|
| 292 |
+
except Exception as e:
|
| 293 |
+
rec["error"] = (rec["error"] + "; " if rec["error"] else "") + f"Validation failed after limiter: {e}"
|
| 294 |
+
try:
|
| 295 |
+
in_path.unlink()
|
| 296 |
+
rec["deleted"] = True
|
| 297 |
+
except Exception as e2:
|
| 298 |
+
rec["error"] += f"; failed deleting original: {e2}"
|
| 299 |
+
# cleanup temps
|
| 300 |
+
for t in (out_tmp, out_tmp2):
|
| 301 |
+
if t.exists():
|
| 302 |
+
try:
|
| 303 |
+
t.unlink()
|
| 304 |
+
except Exception:
|
| 305 |
+
pass
|
| 306 |
+
return rec
|
| 307 |
+
|
| 308 |
+
# limiter output is good — replace the tmp pointer to limiter output for final replace
|
| 309 |
+
# remove the first tmp (if exists)
|
| 310 |
+
if out_tmp.exists():
|
| 311 |
+
try:
|
| 312 |
+
out_tmp.unlink()
|
| 313 |
+
except Exception:
|
| 314 |
+
pass
|
| 315 |
+
out_tmp = out_tmp2
|
| 316 |
+
|
| 317 |
+
# 5) All good: atomically overwrite original with out_tmp
|
| 318 |
+
try:
|
| 319 |
+
atomic_replace(out_tmp, in_path)
|
| 320 |
+
except Exception as e:
|
| 321 |
+
rec["error"] = (rec["error"] + "; " if rec["error"] else "") + f"Atomic replace failed: {e}"
|
| 322 |
+
# in case of a failure, try to delete original to avoid leaving inconsistent data (as requested)
|
| 323 |
+
try:
|
| 324 |
+
in_path.unlink()
|
| 325 |
+
rec["deleted"] = True
|
| 326 |
+
except Exception as e2:
|
| 327 |
+
rec["error"] += f"; failed deleting original after replace failure: {e2}"
|
| 328 |
+
if out_tmp.exists():
|
| 329 |
+
try:
|
| 330 |
+
out_tmp.unlink()
|
| 331 |
+
except Exception:
|
| 332 |
+
pass
|
| 333 |
+
return rec
|
| 334 |
+
|
| 335 |
+
# Optionally, ffmpeg's JSON sometimes includes output_i (final loudness).
|
| 336 |
+
# We didn't capture the apply-pass stderr here. If you want exact final LUFS, we could
|
| 337 |
+
# measure it using pyloudnorm or another ffmpeg measurement pass. For now, leave final_lufs empty.
|
| 338 |
+
rec["final_lufs"] = None
|
| 339 |
+
|
| 340 |
+
return rec
|
| 341 |
+
|
| 342 |
+
except Exception as e:
|
| 343 |
+
rec["error"] = str(e)
|
| 344 |
+
# On unexpected error, delete the original as user requested no quarantine
|
| 345 |
+
try:
|
| 346 |
+
in_path.unlink()
|
| 347 |
+
rec["deleted"] = True
|
| 348 |
+
except Exception as e2:
|
| 349 |
+
rec["error"] += f"; failed deleting original during error cleanup: {e2}"
|
| 350 |
+
return rec
|
| 351 |
+
|
| 352 |
+
|
| 353 |
+
def write_csv(logfile: Path, records, fieldnames):
|
| 354 |
+
with open(logfile, "w", newline="", encoding="utf-8") as f:
|
| 355 |
+
writer = csv.DictWriter(f, fieldnames=fieldnames)
|
| 356 |
+
writer.writeheader()
|
| 357 |
+
for r in records:
|
| 358 |
+
writer.writerow({k: r.get(k) for k in fieldnames})
|
| 359 |
+
|
| 360 |
+
|
| 361 |
+
def main():
|
| 362 |
+
p = argparse.ArgumentParser(description="Batch LUFS normalization using ffmpeg loudnorm (two-pass), delete bad files.")
|
| 363 |
+
p.add_argument("--input", "-i", default="../Dataset", help="Input root directory (recursive). Default ../Dataset")
|
| 364 |
+
p.add_argument("--target", "-t", type=float, default=-16.0, help="Target integrated LUFS (default -16.0)")
|
| 365 |
+
p.add_argument("--peak", type=float, default=0.93, help="Maximum linear peak allowed after processing (default 0.93)")
|
| 366 |
+
p.add_argument("--log", default="normalize_log.csv", help="CSV log filename")
|
| 367 |
+
p.add_argument("--workers", "-w", type=int, default=1, help="Number of parallel workers (default 1)")
|
| 368 |
+
args = p.parse_args()
|
| 369 |
+
|
| 370 |
+
input_root = Path(args.input).expanduser().resolve()
|
| 371 |
+
if not input_root.exists():
|
| 372 |
+
print(f"Input directory does not exist: {input_root}")
|
| 373 |
+
return
|
| 374 |
+
|
| 375 |
+
wav_files = find_wav_files(input_root)
|
| 376 |
+
if not wav_files:
|
| 377 |
+
print(f"No WAV files found under {input_root}")
|
| 378 |
+
return
|
| 379 |
+
|
| 380 |
+
print(f"Found {len(wav_files)} WAV files.")
|
| 381 |
+
print(f"Target LUFS = {args.target} dB. Peak limit (linear) = {args.peak} (TP ≈ {20.0 * np.log10(args.peak):.3f} dB).")
|
| 382 |
+
print("Converting to 44.1 kHz, mono, PCM_16. Bad files will be deleted (no quarantine).")
|
| 383 |
+
print(f"Workers: {args.workers}")
|
| 384 |
+
|
| 385 |
+
worker = partial(process_one, target_lufs=args.target, peak_linear=args.peak)
|
| 386 |
+
|
| 387 |
+
records = []
|
| 388 |
+
if args.workers == 1:
|
| 389 |
+
for pth in wav_files:
|
| 390 |
+
rec = worker(pth)
|
| 391 |
+
records.append(rec)
|
| 392 |
+
status = "OK" if not rec.get("error") else "ERR"
|
| 393 |
+
print(f"{pth}: {status} {'(deleted)' if rec.get('deleted') else ''} {rec.get('error') or ''}")
|
| 394 |
+
else:
|
| 395 |
+
with Pool(processes=args.workers) as pool:
|
| 396 |
+
for rec in pool.imap_unordered(worker, wav_files):
|
| 397 |
+
records.append(rec)
|
| 398 |
+
status = "OK" if not rec.get("error") else "ERR"
|
| 399 |
+
print(f"{rec.get('path')}: {status} {'(deleted)' if rec.get('deleted') else ''} {rec.get('error') or ''}")
|
| 400 |
+
|
| 401 |
+
# Write CSV
|
| 402 |
+
fieldnames = [
|
| 403 |
+
"path",
|
| 404 |
+
"input_i",
|
| 405 |
+
"input_tp",
|
| 406 |
+
"input_lra",
|
| 407 |
+
"input_thresh",
|
| 408 |
+
"target_offset",
|
| 409 |
+
"final_lufs",
|
| 410 |
+
"final_peak",
|
| 411 |
+
"sr",
|
| 412 |
+
"channels",
|
| 413 |
+
"deleted",
|
| 414 |
+
"error",
|
| 415 |
+
]
|
| 416 |
+
write_csv(Path(args.log), records, fieldnames)
|
| 417 |
+
|
| 418 |
+
total = len(records)
|
| 419 |
+
errors = sum(1 for r in records if r.get("error"))
|
| 420 |
+
deleted = sum(1 for r in records if r.get("deleted"))
|
| 421 |
+
print("\nSummary:")
|
| 422 |
+
print(f"Total files processed: {total}")
|
| 423 |
+
print(f"Files with error: {errors}")
|
| 424 |
+
print(f"Files deleted: {deleted}")
|
| 425 |
+
print(f"CSV log written to: {args.log}")
|
| 426 |
+
|
| 427 |
+
|
| 428 |
+
if __name__ == "__main__":
|
| 429 |
+
main()
|
Data/merged_train.txt
ADDED
|
The diff for this file is too large to render.
See raw diff
|
|
|
Data/merged_train_sorted.txt
ADDED
|
The diff for this file is too large to render.
See raw diff
|
|
|
Data/merged_train_test.txt
ADDED
|
@@ -0,0 +1,23 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
Dataset/wavs/czytadlo_ferenc/9788367950787_005_Konwicki_Czytadlo_segment_218.wav|patʃˈɨwa na krˈavɛɲdʑ zbˈɔtʃa ujˈɛntɔ̃ w ɡˈɛ̃stfɛ pˈustɨx kʃˈakuf.|0|Patrzyła na krawędź zbocza ujętą w gęstwę pustych krzaków.
|
| 2 |
+
Dataset/wavs/lew_ferenc/12_segment_391.wav|tɔ znˈatʃɲʲɛ pʃɨspʲˈɛʃa pˌɔtpisˈaɲʲɛ uɡˈɔdɨ mʲˌɛndʑɨ vwˌaɕtɕitɕˈɛlɛm zˌapadˌajɔntsˈɛɡɔ ɕɛ dˈɔmu a kɔpˈalɲʲɔ̃.|0|To znacznie przyspiesza podpisanie ugody między właścicielem zapadającego się domu a kopalnią.
|
| 3 |
+
Dataset/wavs/ryz_ferenc/9788367950190_15_Hlasko_Palcie-ryz-kazdego-dnia_segment_149.wav|pʃˌɨpɔmˈinaw mu ɔ tʃˈɨmɕ, tsˈɔ ɕɛ ɲʲɛ stˈawɔ.|0|Przypominał mu o czymś, co się nie stało.
|
| 4 |
+
Dataset/wavs/czytadlo_ferenc/9788367950787_006_Konwicki_Czytadlo_segment_153.wav|pɔtʃˈɛdwɛm dɔ naʃˈɛɡɔ bufˈɛtu dˈɔɕtɕ sfˌatɨɡˌɔvanˈɛɡɔ pʃˈɛstɛ fʃˈɨstkʲɛ lˈata.|0|Podszedłem do naszego bufetu dość sfatygowanego przez te wszystkie lata.
|
| 5 |
+
Dataset/wavs/czytadlo_ferenc/9788367950787_004_Konwicki_Czytadlo_segment_105.wav|ʒˌɛtʃɨvˈiɕtɕɛ mˈiwɔ. lˈubjɛ tɛn vˈus.|0|Rzeczywiście miło. Lubię ten wóz.
|
| 6 |
+
Dataset/wavs/czytadlo_ferenc/9788367950787_007_Konwicki_Czytadlo_segment_197.wav|a jɛj sˈɛn tɔ zɡˈɔda i pʃˌɨzvɔlˈɛɲʲɛ.|0|a jej sen to zgoda i przyzwolenie.
|
| 7 |
+
Dataset/wavs/czytadlo_ferenc/9788367950787_008_Konwicki_Czytadlo_segment_401.wav|ʒˈɛ jˈa, lˈɛkkɔː ˌarxaˈitʃnɨ i mˈɔtsnɔ naˈivnɨ,|0|Że ja, lekko archaiczny i mocno naiwny,
|
| 8 |
+
Dataset/wavs/lew_ferenc/05_segment_296.wav|kʲˈɛdɨɕ na bˈɔbrɛk jɛxˈawɔ ɕɛ pɔ lˈɛpʃɛ ʒˈɨtɕɛ.|0|Kiedyś na Bobrek jechało się po lepsze życie.
|
| 9 |
+
Dataset/wavs/urwisko_ferenc/22_segment_14.wav|ɡˈɛstɛm zaprˈɔɕiw ɡˈɔ dɔ vˈɔzu. bɔrˈɛvitʃ ˈuɕad na fɔtˈɛlu pˌasaʒˈɛra i zˈamknɔw dʒvˈi, ktˌurɛ pʃɨlɡnˈɛwɨ ɡwˈuxɔ dɔː uʃtʃˈɛlki.|0|Gestem zaprosił go do wozu. Borewicz usiadł na fotelu pasażera i zamknął drzwi, które przylgnęły głucho do uszczelki.
|
| 10 |
+
Dataset/wavs/czytadlo_ferenc/9788367950787_012_Konwicki_Czytadlo_segment_97.wav|zatʃˈɨnam ˌɔdʑɨskˈivatɕ pˈamjɛɲtɕ. pʃɨpˈɔmnɛ sˈɔbjɛ fʃˈɨstkɔ.|0|Zaczynam odzyskiwać pamięć. Przypomnę sobie wszystko.
|
| 11 |
+
Dataset/wavs/czytadlo_ferenc/9788367950787_001_Konwicki_Czytadlo_segment_593.wav|pˈadaw dˈɛʃtʃ.|0|Padał deszcz.
|
| 12 |
+
Dataset/wavs/czytadlo_ferenc/9788367950787_009_Konwicki_Czytadlo_segment_206.wav|pɔdɲʲˈɔswɛm ɕɛ tɕˈɛ̃ʃkɔ z wˈuʃka.|0|Podniosłem się ciężko z łóżka.
|
| 13 |
+
Dataset/wavs/ryz_ferenc/9788367950190_16_Hlasko_Palcie-ryz-kazdego-dnia_segment_131.wav|tʃɨ ɲʲɛ jɛst tˈak? zapˈɨtaw.|0|Czy nie jest tak? zapytał.
|
| 14 |
+
Dataset/wavs/lew_ferenc/07_segment_247.wav|pɔwˈɔvɛ mʲɛʃkˈaɲtsuf stanˈɔvi lˈudnɔɕtɕ nˌapwɨvˈɔva, tɔ jɛst rˌɛpatrjˈaɲtɕi i ˌɔɕɛdlˈɛɲtsɨ.|0|Połowę mieszkańców stanowi ludność napływowa, to jest repatrianci i osiedleńcy.
|
| 15 |
+
Dataset/wavs/czytadlo_ferenc/9788367950787_003_Konwicki_Czytadlo_segment_259.wav|w nˈaɡwɛj pʃˌɨtɔmnˈɔɕtɕi pˌɔdʑivʲˈawɛm fspaɲʲˈawɛ prɔpˈɔrtsjɛ i zdˌumjɛvajˈɔntsɔ̃ ɡˌɛɔmɛtrˈɨtʃnɔɕtɕ pʲˈɛrɕi ˌaɲi za dˈuʒɨx, ˌaɲi za mˈawɨx.|0|W nagłej przytomności podziwiałem wspaniałe proporcje i zdumiewającą geometryczność piersi ani za dużych, ani za małych.
|
| 16 |
+
Dataset/wavs/lew_ferenc/05_segment_360.wav|ˌɔtʃɨvˈiɕtɕɛ, mˈɨɕmɨ ix ʃkɔlˈili, bˈɔ nˈatɔ dɔstˈaliɕmˌɨ pʲɛɲʲˈɔndʑɛ.|0|Oczywiście, myśmy ich szkolili, bo na to dostaliśmy pieniądze.
|
| 17 |
+
Dataset/wavs/urwisko_ferenc/15_segment_100.wav|miltʃˈawa. dˈam tɕi nˈamjar na jˈɛɡɔ bˈɨwɔ̃ ʒˈɔnɛ.|0|Milczała. Dam ci namiar na jego byłą żonę.
|
| 18 |
+
Dataset/wavs/urwisko_ferenc/49_segment_65.wav|pˌɔbwɔɲdʑˈiwa, ˌalɛ tɔ ɕɛ zdaʒˈawɔ najlˈɛpʃɨm.|0|Pobłądziła, ale to się zdarzało najlepszym.
|
| 19 |
+
Dataset/wavs/czytadlo_ferenc/9788367950787_008_Konwicki_Czytadlo_segment_293.wav|ɔpˈɔvʲɛts mi tsˈɔɕ ɔ sˈɔbjɛ, ʃɛpnˈɛwa.|0|Opowiedz mi coś o sobie, szepnęła.
|
| 20 |
+
Dataset/wavs/czytadlo_ferenc/9788367950787_007_Konwicki_Czytadlo_segment_118.wav|naxˈɔdʑi mɲʲɛ pɔlˈitsja.|0|Nachodzi mnie policja.
|
| 21 |
+
Dataset/wavs/urwisko_ferenc/63_segment_128.wav|tʃɨ ɕɲˈi mu ɕɛ zuzˈanna?|0|Czy śni mu się Zuzanna?
|
| 22 |
+
Dataset/wavs/czytadlo_ferenc/9788367950787_005_Konwicki_Czytadlo_segment_502.wav|a mɨ ftˈɛdɨ vidʑˈimɨ pʃɛkwˈutɔ̃ tɕˈɛmnɔɕtɕ.|0|A my wtedy widzimy przekłutą ciemność.
|
| 23 |
+
Dataset/wavs/urwisko_ferenc/43_segment_78.wav|ˈɔlɡʲɛrd vˈɨjɔw tɛlˈɛfɔn i vˈɨbraw pˌɔwɔntʃˈɛɲʲɛ. pʃɨwˈɔʒɨw apˈarad dɔː ˈuxa.|0|Olgierd wyjął telefon i wybrał połączenie. Przyłożył aparat do ucha.
|
Data/merged_val.txt
ADDED
|
@@ -0,0 +1,106 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
Dataset/wavs/urwisko_ferenc/58_segment_27.wav|ɲʲɛ bˈardʑɔ vʲˈɛdʑaw, tsˈɔ ɕɛ dʑˈɛjɛ nˈatɨm parkˈiŋɡu i tʃɨ pɔvˈiɲʲɛn tsˈɔɕ s tɨm zrˈɔbʲitɕ.|0|Nie bardzo wiedział, co się dzieje na tym parkingu i czy powinien coś z tym zrobić.
|
| 2 |
+
Dataset/wavs/ryz_ferenc/9788367950190_09_Hlasko_Palcie-ryz-kazdego-dnia_segment_293.wav|ˈandɛrsɔn i sˈusan patʃˈɨli za ɲˈimi.|0|Anderson i Susan patrzyli za nimi.
|
| 3 |
+
Dataset/wavs/ryz_ferenc/9788367950190_06_Hlasko_Palcie-ryz-kazdego-dnia_segment_50.wav|ʑlˈɛ. mˈɔi kljˈɛɲtɕi tɔ vwˈaɕɲʲɛ tˈatsɨ jˈak tˈɨ.|0|Źle. Moi klienci to właśnie tacy jak ty.
|
| 4 |
+
Dataset/wavs/urwisko_ferenc/65_segment_129.wav|ˌalɛ najɡˈɔrʃɛ bˌɨwɨ ɔstˈatɲʲɛ swˈɔva rˌɛpɔrtˈaʒu.|0|Ale najgorsze były ostatnie słowa reportażu.
|
| 5 |
+
Dataset/wavs/czytadlo_ferenc/9788367950787_010_Konwicki_Czytadlo_segment_107.wav|pɔʃˈɛdwɛm f strˈɔnɛ skˈarpɨ.|0|Poszedłem w stronę skarpy.
|
| 6 |
+
Dataset/wavs/lew_ferenc/09_segment_238.wav|ɲʲˌɛvɨbrˈanɨ vˈɛŋɡʲɛl, ktˌurɨ mˈɔʒna bˌɨwɔ vˈɨbratɕ, tɔː ɔɡrˈɔmna strˈata dla pʃɛmˈɨswu, dla ˌɔbɨvatˈɛli.|0|Niewybrany węgiel, który można było wybrać, to ogromna strata dla przemysłu, dla obywateli.
|
| 7 |
+
Dataset/wavs/urwisko_ferenc/23_segment_34.wav|pˈaxɲʲaw dˈɔbrɔ̃ vˈɔdɔ̃ kɔlˈɔɲskɔ̃.|0|Pachniał dobrą wodą kolońską.
|
| 8 |
+
Dataset/wavs/czytadlo_ferenc/9788367950787_010_Konwicki_Czytadlo_segment_422.wav|a dˈɔkɔnt jɛdʑˈɛmɨ? a, zɔbˈatʃɨ pˈan na mʲˈɛjstsu.|0|A dokąd jedziemy? A, zobaczy pan na miejscu.
|
| 9 |
+
Dataset/wavs/czytadlo_ferenc/9788367950787_009_Konwicki_Czytadlo_segment_208.wav|xˈalɔ, pˌɔvʲɛdʑˈawɛm sˈɛnnɨm ɡwˈɔsɛm.|0|Halo, powiedziałem sennym głosem.
|
| 10 |
+
Dataset/wavs/lew_ferenc/11_segment_292.wav|uwˈamɛk sɛkˈundɨ.|0|Ułamek sekundy.
|
| 11 |
+
Dataset/wavs/czytadlo_ferenc/9788367950787_006_Konwicki_Czytadlo_segment_293.wav|xˈɔtɕ ˈinɲi zmʲɛɲʲˈali ɕɛ tsˈɔ pˈuw kˌilɔmˈɛtra.|0|Choć inni zmieniali się co pół kilometra.
|
| 12 |
+
Dataset/wavs/urwisko_ferenc/21_segment_45.wav|tˈɨlɛ tˈɨlkɔ, ʒˈɛ xwˈɔp ɲʲˈɛma mɔtˈɨvu. jˈɛɕli dˈɔbʒɛ zrˌɔzumjˈawɛm, rɔzvˈɔdʑiw ɕɛ z ʒˈɔnɔ̃, ktˌura mʲˈawa tfˈardɛ dɔvˈɔdɨ zdrˈadɨ.|0|Tyle tylko, że chłop nie ma motywu. Jeśli dobrze zrozumiałem, rozwodził się z żoną, która miała twarde dowody zdrady.
|
| 13 |
+
Dataset/wavs/ryz_ferenc/9788367950190_07_Hlasko_Palcie-ryz-kazdego-dnia_segment_199.wav|tʃɨ ɲʲɛ bˌɨwɔ tˈak?|0|Czy nie było tak?
|
| 14 |
+
Dataset/wavs/ryz_ferenc/9788367950190_13_Hlasko_Palcie-ryz-kazdego-dnia_segment_46.wav|ʃˈɛfjɛ, ˌɔɲi ɕɛ ˌɔbraʒˈajɔ̃, kʲˈɛdɨ ix ɕɛ bjˈɛʒɛ jˈɛdnɨɣ za drˈuɡʲix. tˈak? ˌɔbraʒˈajɔ̃ ɕɛ?|0|Szefie, oni się obrażają, kiedy ich się bierze jednych za drugich. Tak? Obrażają się?
|
| 15 |
+
Dataset/wavs/lew_ferenc/04_segment_213.wav|tsudˈɔvnɛ zdaʒˈɛɲʲa tɔ mˈɔɡwɨbˌɨ mʲˈɛtɕ mʲˈɛjstsɛ w bˈajtsɛ ɔ ɕlˈɔ̃skim kɔptɕˈuʃku.|0|Cudowne zdarzenia to mogłyby mieć miejsce w bajce o śląskim kopciuszku.
|
| 16 |
+
Dataset/wavs/lew_ferenc/09_segment_391.wav|pɔt stʃˈɛxɛ jˈɛdnɛj z vʲˈɛjskix xˈad zˌaxɔdʑˈiwɨ vˈɨʃʃɛ sfˈɛrɨ pɔ ɕfʲɛʒˈutkɔ̃ ɕmʲɛtˈaŋkɛ, pɔ mlˈɛkɔ.|0|Pod strzechę jednej z wiejskich chat zachodziły wyższe sfery po świeżutką śmietankę, po mleko.
|
| 17 |
+
Dataset/wavs/urwisko_ferenc/28_segment_42.wav|ilˈɛkrɔtɕ spˌɔtɨkˈawam ɕɛ s kˈaɕkɔ̃, vidʑˈawam, ʒˈɛ ɲʲɛ ukwˈada jɛj ɕɛ w mawʒˈɛɲstfʲɛ.|0|Ilekroć spotykałam się z Kaśką, widziałam, że nie układa jej się w małżeństwie.
|
| 18 |
+
Dataset/wavs/czytadlo_ferenc/9788367950787_009_Konwicki_Czytadlo_segment_159.wav|tɛn vʲˈɛlki vˈir mɲʲɛ vˈɛssaw.|0|Ten wielki wir mnie wessał.
|
| 19 |
+
Dataset/wavs/lew_ferenc/13_segment_137.wav|pˌɔtstavˈili ˈawta, vɨɡnˈali lˈudʑi s xawˈupɨ, wˌadɔvˈali i vˌɨvɔzˈili na xɔtˈɛlɛ, jˈak ktˈɔɕ ɲʲˈɛmʲaw rɔdʑˈinɨ w ˌɔkɔlˈitsɨ.|0|Podstawili auta, wygnali ludzi z chałupy, ładowali i wywozili na hotele, jak ktoś nie miał rodziny w okolicy.
|
| 20 |
+
Dataset/wavs/urwisko_ferenc/32_segment_27.wav|ftˈɛdɨ stˈara nˈɔkja xˈɛrman...|0|Wtedy stara Nokia Herman...
|
| 21 |
+
Dataset/wavs/ryz_ferenc/9788367950190_13_Hlasko_Palcie-ryz-kazdego-dnia_segment_206.wav|ɲʲˈɛpij za dˈuʒɔ.|0|Nie pij za dużo.
|
| 22 |
+
Dataset/wavs/czytadlo_ferenc/9788367950787_009_Konwicki_Czytadlo_segment_544.wav|ja bˌɛndɛ tfˈɔim ʒˈɨtɕɛm, pˌɔvʲɛdʑˈawa pʃɛt ɕˈɛbjɛ i tfˈɔjɔ̃ ɕmʲˈɛrtɕɔ̃.|0|Ja będę Twoim życiem, powiedziała przed siebie i Twoją śmiercią.
|
| 23 |
+
Dataset/wavs/ryz_ferenc/9788367950190_01_Hlasko_Palcie-ryz-kazdego-dnia_segment_179.wav|tˈak tʃɨ ˈɔvak papʲˈɛrɨ sɔ̃ sfˌawʃɔvˈanɛ, a tˈu jɛzd vˈɔlnɨ krˈaj.|0|Tak czy owak papiery są sfałszowane, a tu jest wolny kraj.
|
| 24 |
+
Dataset/wavs/ryz_ferenc/9788367950190_07_Hlasko_Palcie-ryz-kazdego-dnia_segment_194.wav|tˌɨlkɔ ta dʑɛftʃˈɨna ɲʲɛ pˈɔʃwa za tˈɔbɔ̃, tˈak jˈak tɨ sˈɔbjɛ tɔ vˌɨɔbraʒˈawɛɕ.|0|Tylko ta dziewczyna nie poszła za tobą, tak jak ty sobie to wyobrażałeś.
|
| 25 |
+
Dataset/wavs/ryz_ferenc/9788367950190_10_Hlasko_Palcie-ryz-kazdego-dnia_segment_28.wav|w jˈakimɕ sˈɛnɕɛ.|0|W jakimś sensie.
|
| 26 |
+
Dataset/wavs/czytadlo_ferenc/9788367950787_006_Konwicki_Czytadlo_segment_81.wav|ˌalɛ pʃˌɛtɕɛʃ miljˈardɨ lˈudʑi ɔ tsˈɔɕ ɕɛ mˈɔdlɔ̃ f tɛj xfˈili. ktˈɔ mˈa spˈɛwɲitɕ tɛ nˈaʃɛ ʒɨtʃˈɛɲʲa?|0|Ale przecież miliardy ludzi o coś się modlą w tej chwili. Kto ma spełnić te nasze życzenia?
|
| 27 |
+
Dataset/wavs/lew_ferenc/12_segment_275.wav|xtɕˈawbɨm vʲˈɛdʑɛtɕ, tʃɨ pɔt nˈaʃɔ̃ ulˈitsɔ̃ ftɕˈɔ̃ʃ kˈɔpjɔ̃ vˈɛŋɡʲɛl.|0|Chciałbym wiedzieć, czy pod naszą ulicą wciąż kopią węgiel.
|
| 28 |
+
Dataset/wavs/ryz_ferenc/9788367950190_10_Hlasko_Palcie-ryz-kazdego-dnia_segment_202.wav|ɲʲˈɛbuj ɕɛ, zɔstˈavjɛ tɕi jˈɔ̃.|0|Nie bój się, zostawię ci ją.
|
| 29 |
+
Dataset/wavs/ryz_ferenc/9788367950190_09_Hlasko_Palcie-ryz-kazdego-dnia_segment_68.wav|tɔ zˈafʃɛ dˈɔbʒɛ zrˈɔbʲitɕ pɔvʲˈɛdʑaw ˈandɛrsɔn. pɔwˈɔʒɨw ɕɛ na plˈɛtsax i zawˈɔʒɨw ramjˈɔna pɔd ɡwˈɔvɔ̃.|0|– To zawsze dobrze zrobić – powiedział Anderson. Położył się na plecach i założył ramiona pod głową.
|
| 30 |
+
Dataset/wavs/czytadlo_ferenc/9788367950787_009_Konwicki_Czytadlo_segment_542.wav|tʃˈɛba ɕɛ tɕˈɛʃɨtɕ kˈaʒdɨm dɲʲˈɛm. ɲʲɛ vʲˈɛmɨ, ˈilɛ nˈam iɣ zɔstˈawɔ.|0|Trzeba się cieszyć każdym dniem. Nie wiemy, ile nam ich zostało.
|
| 31 |
+
Dataset/wavs/lew_ferenc/05_segment_212.wav|na ulˈitsɛ vˌɨjɛʒdʒˈajɔ̃ nˈɔvɛ sˌamɔxˈɔdɨ, ktˌurɛ za xfˈilɛ stˈanɔ̃ w ɡarˈaʒax s pustˈɨmi bakˈami.|0|Na ulicę wyjeżdżają nowe samochody, które za chwilę staną w garażach z pustymi bakami.
|
| 32 |
+
Dataset/wavs/czytadlo_ferenc/9788367950787_007_Konwicki_Czytadlo_segment_268.wav|jˈak trafjˈawam i dlatʃˈɛɡɔ f tɔ nˈɔvɛ mʲˈɛjstsɛ?|0|Jak trafiałam i dlaczego w to nowe miejsce?
|
| 33 |
+
Dataset/wavs/urwisko_ferenc/29_segment_4.wav|ɕˈɛŋɡnɔw pɔ kɔmˈurkɛ.|0|Sięgnął po komórkę.
|
| 34 |
+
Dataset/wavs/urwisko_ferenc/43_segment_8.wav|xˈɛrman ɕɛ ˌutɕɛʃˈɨwa, ʒˈɛ trafˈili na ɡadˈuwɛ, ˌalɛ z dˌɔɕfʲattʃˈɛɲʲa vʲɛdʑˈawa, ʒˈɛ pɔvˈinna pʃˈɛjɔɲtɕ kɔntrˈɔlɛ nat jˈɛɡɔ swˌɔvɔtˈɔkʲɛm.|0|Herman się ucieszyła, że trafili na gadułę, ale z doświadczenia wiedziała, że powinna przejąć kontrolę nad jego słowotokiem.
|
| 35 |
+
Dataset/wavs/czytadlo_ferenc/9788367950787_001_Konwicki_Czytadlo_segment_173.wav|a ja tˈak strˈaʃɲʲɛ ɲʲɛ lˈubjɛ rˌɔspɔtʃɨnˈaɲʲa mˈɨɕli ɔt tˌɛɡɔ nˈɔ tsˈuʃ.|0|A ja tak strasznie nie lubię rozpoczynania myśli od tego no cóż.
|
| 36 |
+
Dataset/wavs/ryz_ferenc/9788367950190_05_Hlasko_Palcie-ryz-kazdego-dnia_segment_361.wav|tʃwˈɔvʲɛk, kturˌɛɡɔ mi brˌakɔvˈawɔ dɔ kɔmplˈɛtu.|0|Człowiek, którego mi brakowało do kompletu.
|
| 37 |
+
Dataset/wavs/czytadlo_ferenc/9788367950787_008_Konwicki_Czytadlo_segment_239.wav|pˌɔwɔʒˈɨwɛm ɕɛ, ɔkrˈɨwɛm jˈɔ̃ ramjˈɛɲʲɛm.|0|Położyłem się, okryłem ją ramieniem.
|
| 38 |
+
Dataset/wavs/ryz_ferenc/9788367950190_14_Hlasko_Palcie-ryz-kazdego-dnia_segment_106.wav|ɔ ɕmʲˈɛrtɕi tfɔjˈɛɡɔ brˈata vʲˈɛʃ tˌɨlkɔ dlatˈɛɡɔ, ʒˈɛ zɡʲˈinɔw f sˌamɔlˈɔtɕɛ i ɲʲɛ mˈɔʒɛʃ mu pʃɛbˈatʃɨtɕ, ʒˈɛ rɔzvˈaliw dˈɔbrɨ samˈɔlɔt.|0|O śmierci twojego brata wiesz tylko dlatego, że zginął w samolocie i nie możesz mu przebaczyć, że rozwalił dobry samolot.
|
| 39 |
+
Dataset/wavs/czytadlo_ferenc/9788367950787_011_Konwicki_Czytadlo_segment_291.wav|zˌabwɔŋkˈawa ɕɛ dɔ tɛj ɡalˈaktɨkˌi i ɲʲɛ mˈɔʒɛ ɕɛ z ɲʲˈɛj vˈɨrvatɕ.|0|Zabłąkała się do tej galaktyki i nie może się z niej wyrwać.
|
| 40 |
+
Dataset/wavs/ryz_ferenc/9788367950190_16_Hlasko_Palcie-ryz-kazdego-dnia_segment_145.wav|a jˈɛɕli ja tɕi ɲʲɛ pɔzvˈɔlɛ?|0|A jeśli ja ci nie pozwolę?
|
| 41 |
+
Dataset/wavs/czytadlo_ferenc/9788367950787_004_Konwicki_Czytadlo_segment_59.wav|bˈɔ pʃˌɨpɔmɲʲˈawɛm sˈɔbjɛ sfˈuj dˈɔm, ktˌurɨ bˈɨw vʲˈɛlkɔ̃ kˌamjɛɲˈitsɔ̃ jˈak mˈɔnd blˈants.|0|Bo przypomniałem sobie swój dom, który był wielką kamienicą jak Mont Blanc.
|
| 42 |
+
Dataset/wavs/ryz_ferenc/9788367950190_12_Hlasko_Palcie-ryz-kazdego-dnia_segment_56.wav|i ʒˈɛ ɲʲɛ stˈartʃɨ tɕi ʒˈɨtɕa, ˈabɨ ɕɛ ɲʲˈɔ̃ natɕˈɛʃɨtɕ.|0|I że nie starczy ci życia, aby się nią nacieszyć.
|
| 43 |
+
Dataset/wavs/lew_ferenc/11_segment_270.wav|pɔvˈɔli zɲikˈamɨ s pɔvʲˈɛʃxɲi ʑˈɛmi. zɔstˈajɔ̃ zˌarɔɕɲʲˈɛntɛ kʃɛvˈami bɔtʃɲˈitsɛ.|0|Powoli znikamy z powierzchni ziemi. Zostają zarośnięte krzewami bocznice.
|
| 44 |
+
Dataset/wavs/czytadlo_ferenc/9788367950787_005_Konwicki_Czytadlo_segment_207.wav|jˈakaɕ pʃˈɨkrɔʑdʑ zvʲɔ̃zˈana s tˈamtɔ̃ nˈɔtsɔ̃.|0|Jakaś przykrość związana z tamtą nocą.
|
| 45 |
+
Dataset/wavs/ryz_ferenc/9788367950190_03_Hlasko_Palcie-ryz-kazdego-dnia_segment_297.wav|f pɔʒˈɔntku, pɔvʲˈɛdʑaw ɡˈɛrs fˈirst lˈɔvɛ.|0|W porządku, powiedział Gers First Love.
|
| 46 |
+
Dataset/wavs/czytadlo_ferenc/9788367950787_001_Konwicki_Czytadlo_segment_500.wav|tsˈɔ mɲʲɛ ˌɔddʑɛlˈiwɔː ɔt mˈɛɡɔ ɡˌasnɔntsˈɛɡɔ ʒɨvˈɔta?|0|Co mnie oddzieliło od mego gasnącego żywota?
|
| 47 |
+
Dataset/wavs/czytadlo_ferenc/9788367950787_007_Konwicki_Czytadlo_segment_345.wav|xˈɔdʑ znˈuf ɲʲɛ tˈaka mwˈɔda, jˈaɡbɨ ta mˈɔja kɔbjˈɛta tʃɨmˈawa tsˈɔɕ swɔtkʲˈɛɡɔ na jɛ̃zˈɨku ˈalbɔ pˌɔdɲʲɛbjˈɛɲʲu.|0|Choć znów nie taka młoda, jakby ta moja kobieta trzymała coś słodkiego na języku albo podniebieniu.
|
| 48 |
+
Dataset/wavs/lew_ferenc/13_segment_215.wav|mˈɔʒna bˈɨ mu nˈadatɕ pˌɔvaʒɲʲˈɛjʃɔ̃ rˈaŋɡɛ, fprɔvˈadʑidʑ dɔ ɕtɕiswˈɛɡɔ tsˈɛntrum.|0|Można by mu nadać poważniejszą rangę, wprowadzić do ścisłego centrum.
|
| 49 |
+
Dataset/wavs/urwisko_ferenc/36_segment_107.wav|pʃˈɛʃli pʃˈɛs pˈɔkuj na tˈaras. rɔzɡʒˈanɛ pwˈɨtki zɡʒɨtˈawɨ pɔt ix stɔpˈami.|0|Przeszli przez pokój na taras. Rozgrzane płytki zgrzytały pod ich stopami.
|
| 50 |
+
Dataset/wavs/czytadlo_ferenc/9788367950787_004_Konwicki_Czytadlo_segment_197.wav|uɕmʲˈɛxatɕ ɕɛ dɔ mˌitskʲɛvˈitʃa.|0|Uśmiechać się do Mickiewicza.
|
| 51 |
+
Dataset/wavs/czytadlo_ferenc/9788367950787_001_Konwicki_Czytadlo_segment_476.wav|ja ɲʲɛ jˌɛstɛm ˌɛrɔtɔmˈanɛm. ɲʲɛ lˈɛtsɛ jˈak pʲˈɛz za kˈaʒdɔ̃ sˈukɔ̃.|0|Ja nie jestem erotomanem. Nie lecę jak pies za każdą suką.
|
| 52 |
+
Dataset/wavs/urwisko_ferenc/51_segment_17.wav|ftʃˈɛɕɲʲɛj pʃˌɨɡlɔndˈawa ɕɛ mˈapʲɛ ɡɔˈɔɡlɛ i zdjˈɛɲtɕɔm sˌatɛlitˈarnɨm kaʃtʃˈɔrka.|0|Wcześniej przyglądała się mapie Google i zdjęciom satelitarnym kaszczorka.
|
| 53 |
+
Dataset/wavs/ryz_ferenc/9788367950190_15_Hlasko_Palcie-ryz-kazdego-dnia_segment_75.wav|— jˌɛstɛɕ jˈasna, a mɲʲɛ zˈafʃɛ muvʲˈɔnɔ, ʒˈɛ irlˈantki sɔ̃ tɕˌɛmnɔvwˈɔsɨ.|0|— Jesteś jasna, a mnie zawsze mówiono, że Irlandki są ciemnowłosy.
|
| 54 |
+
Dataset/wavs/ryz_ferenc/9788367950190_02_Hlasko_Palcie-ryz-kazdego-dnia_segment_392.wav|— pˌɔvʲɛdʑˈawɛm jˈuʃ, pˈanu, pˈaɲi i ja jɛstˌɛɕmɨ tɨm sˈamɨm tʃwɔvʲˈɛkʲɛm.|0|— Powiedziałem już, panu, pani i ja jesteśmy tym samym człowiekiem.
|
| 55 |
+
Dataset/wavs/ryz_ferenc/9788367950190_07_Hlasko_Palcie-ryz-kazdego-dnia_segment_39.wav|ˌalɛ pʃˈɛttɛm xtɕˈawbɨm fstˈɔmpidʑ dɔ sklˈɛpu z brˈɔɲʲɔ̃. tɔ pɔ drˈɔdʑɛ. xtsˈɛ kˈupitɕ karˈabʲin.|0|Ale przedtem chciałbym wstąpić do sklepu z bronią. To po drodze. Chcę kupić karabin.
|
| 56 |
+
Dataset/wavs/ryz_ferenc/9788367950190_02_Hlasko_Palcie-ryz-kazdego-dnia_segment_9.wav|i pɔwˈɔʒɨw ɕɛ, pˌɔdwɔʒˈɨfʃɨ vʲatrˈufkɛ pɔd ɡwˈɔvɛ i ˌɔdvrutɕˈifʃɨ tfˈaʒ dɔ ɕtɕˈanɨ.|0|I położył się, podłożywszy wiatrówkę pod głowę i odwróciwszy twarz do ściany.
|
| 57 |
+
Dataset/wavs/czytadlo_ferenc/9788367950787_008_Konwicki_Czytadlo_segment_431.wav|ɔbjˈɔwɛm jˈɔ̃ za ʃˈɨjɛ tˈak ˌɛnɛrɡʲˈitʃɲʲɛ, ʒˈɛ ˈaʒ zˌawaskɔtˈawa mˈuj bˈɔk kˌɔlɛbjɔntsˈɨmi ɕɛ sutkˈami. — tʃɨ tɨ ɕɛ mɲʲɛ ɲʲɛ bˈɔiʃ? — ʃɛpnˈɔwɛm.|0|Objąłem ją za szyję tak energicznie, że aż załaskotała mój bok kolebiącymi się sutkami. — Czy ty się mnie nie boisz? — szepnąłem.
|
| 58 |
+
Dataset/wavs/urwisko_ferenc/38_segment_31.wav|zˌavaxˈawa ɕɛ, lˈɛtʃ ˌɔstatˈɛtʃɲʲɛ uɕˈadwa ˈɔbɔk.|0|Zawahała się, lecz ostatecznie usiadła obok.
|
| 59 |
+
Dataset/wavs/urwisko_ferenc/24_segment_15.wav|pˈan sprˈavdʑi i zadʑvˈɔɲi.|0|Pan sprawdzi i zadzwoni.
|
| 60 |
+
Dataset/wavs/ryz_ferenc/9788367950190_10_Hlasko_Palcie-ryz-kazdego-dnia_segment_66.wav|tɨ ˈɔtɨm vʲˈɛʃ rˈuvɲʲɛ dˈɔbʒɛ jˈak i jˈa. lˈataʃ i dwˈuʒɛj i lˈɛpʲɛj ˈɔdɛ mɲʲɛ. pʃˈɨkrɔ mi, ʒˈɛ mˈuʃɛ pɔvʲˈɛdʑɛtɕ tɕi kɔmplˈɛmɛnt.|0|Ty o tym wiesz równie dobrze jak i ja. Latasz i dłużej i lepiej ode mnie. Przykro mi, że muszę powiedzieć ci komplement.
|
| 61 |
+
Dataset/wavs/urwisko_ferenc/49_segment_78.wav|pˈɔza tɨm jˌɛstɛm xɔlˈɛrɲʲɛ tɕˈɛkaf, tsˈɔ kˌɔmbʲinˈujɛʃ.|0|Poza tym jestem cholernie ciekaw, co kombinujesz.
|
| 62 |
+
Dataset/wavs/urwisko_ferenc/59_segment_77.wav|pˌɔpatʃˈɨwa na bjɛɡwˈɛɡɔː i tʃɛkˈawa.|0|Popatrzyła na biegłego i czekała.
|
| 63 |
+
Dataset/wavs/ryz_ferenc/9788367950190_15_Hlasko_Palcie-ryz-kazdego-dnia_segment_81.wav|tʃɨ bɛɲdʑˌɛmɨ tˈɛras mˈuvitɕ ɔ sˈukɲʲax?|0|Czy będziemy teraz mówić o sukniach?
|
| 64 |
+
Dataset/wavs/ryz_ferenc/9788367950190_03_Hlasko_Palcie-ryz-kazdego-dnia_segment_97.wav|ɔtkwˈadaj sfˈɔjɛ pajˈɔŋki, a ja bˌɛndɛ ɔtkwˈadaw sfˈɔjɛ ɕmʲˈɛtɕɛ w lˈɛvɔ.|0|Odkładaj swoje pająki, a ja będę odkładał swoje śmiecie w lewo.
|
| 65 |
+
Dataset/wavs/czytadlo_ferenc/9788367950787_003_Konwicki_Czytadlo_segment_440.wav|tʃˈas raptˈɔvnɨx navrˈutsɛɲ, pˌɔmɨɕlˈawɛm.|0|Czas raptownych nawróceń, pomyślałem.
|
| 66 |
+
Dataset/wavs/ryz_ferenc/9788367950190_02_Hlasko_Palcie-ryz-kazdego-dnia_segment_55.wav|zˌatʃɨnˈamɨ? dˈɔbʒɛ.|0|Zaczynamy? Dobrze.
|
| 67 |
+
Dataset/wavs/urwisko_ferenc/05_segment_56.wav|ʃtʃɛɡˈulɲʲɛ f tˌaki ˈupaw. pˌɔvʲɛdʑˈawaɕ ɕˌikɔrskʲˈɛmu, na jˈakix pɔtstˈavax pɔnˈɔvɲʲɛ fʃtʃˈɛntɔ ɕlˈɛtstfɔ?|0|Szczególnie w taki upał. Powiedziałaś Sikorskiemu, na jakich podstawach ponownie wszczęto śledztwo?
|
| 68 |
+
Dataset/wavs/czytadlo_ferenc/9788367950787_011_Konwicki_Czytadlo_segment_26.wav|kˈɔrsak stˈanɔw ˈɔstrɔ.|0|Korsak stanął ostro.
|
| 69 |
+
Dataset/wavs/czytadlo_ferenc/9788367950787_004_Konwicki_Czytadlo_segment_217.wav|ɲʲˈɛma prɔblˈɛmu, mˈɔɡɛ tɕˈɛ pˈɔdvʲɛɕtɕ. dʑɛŋkˈujɛ, tɔ ɲʲˌɛdalˈɛkɔ, mˈuʃɛ zˈɛbratɕ mˈɨɕli.|0|Nie ma problemu, mogę cię podwieźć. Dziękuję, to niedaleko, muszę zebrać myśli.
|
| 70 |
+
Dataset/wavs/urwisko_ferenc/01_segment_78.wav|xˈɛrman ɲʲɛ zˌamjɛʒˈawa ɡˈɔ pɔɡˈaɲʲatɕ. tʃɛkˈawa tɕɛrplˈivʲɛ.|0|Herman nie zamierzała go poganiać. Czekała cierpliwie.
|
| 71 |
+
Dataset/wavs/urwisko_ferenc/14_segment_8.wav|ˌalɛ xˈɛrman pˌɔɡrɔ̃ʒˈɨwa ɕɛ w rˌɔzmɨɕlˈaɲʲax i ɲʲɛ ˌɔtpɔvʲɛdʑˈawa.|0|Ale Herman pogrążyła się w rozmyślaniach i nie odpowiedziała.
|
| 72 |
+
Dataset/wavs/urwisko_ferenc/14_segment_34.wav|tʃɨ s tɔ̃ lˈipskɔ̃, ˈɔprutʃ lˌɛvandˈɔfskʲɛj, mʲˈɛʃkaw ktˈɔɕ jˈɛʃtʃɛ?|0|Czy z tą Lipską, oprócz Lewandowskiej, mieszkał ktoś jeszcze?
|
| 73 |
+
Dataset/wavs/ryz_ferenc/9788367950190_03_Hlasko_Palcie-ryz-kazdego-dnia_segment_122.wav|pˈɔtʃɔw znˈɔɕitɕ pˈatʃki ˌɔbvʲɔ̃zˈanɛ ʃnˈurkʲɛm i ukwˈadatɕ jˈɛ na drɛvɲʲˈanɛj pɔtstˈaftsɛ.|0|Począł znosić paczki obwiązane sznurkiem i układać je na drewnianej podstawce.
|
| 74 |
+
Dataset/wavs/ryz_ferenc/9788367950190_15_Hlasko_Palcie-ryz-kazdego-dnia_segment_113.wav|pʃˌɛtɕɛʃ muɕˈawɛʑ bˈɨtɕ tˈak tʃɨ ˈɔvaɡ zdrˈɔvɔ pˌɔɡruxɔtˈanɨ.|0|Przecież musiałeś być tak czy owak zdrowo pogruchotany.
|
| 75 |
+
Dataset/wavs/urwisko_ferenc/18_segment_88.wav|pɔdˈɔbnɔ vˌɨwɔvʲˈɔnɔ z vˈiswɨ ʃtʃˈɔntki jˈakʲɛjɕ kɔbjˈɛtɨ ɔt pˈaru.|0|Podobno wyłowiono z Wisły szczątki jakiejś kobiety od paru.
|
| 76 |
+
Dataset/wavs/lew_ferenc/06_segment_240.wav|ˌalɛ jˈuʃ nˈavɛt tɕˈi, ktˌuʒɨ ftʃˈɛɕɲʲɛj ˌɔɡlɔndˈali bˌɔmbardɔvˈaɲʲa z dˈaxuf, ɲˈitʃɨm pɔkˈazɨ fˌajɛrvˈɛrkuf, zbjɛɡˈajɔ̃ tˈɛraz dɔ sxrˈɔnuf.|0|Ale już nawet ci, którzy wcześniej oglądali bombardowania z dachów, niczym pokazy fajerwerków, zbiegają teraz do schronów.
|
| 77 |
+
Dataset/wavs/czytadlo_ferenc/9788367950787_010_Konwicki_Czytadlo_segment_397.wav|mɲʲˈɛjʃa s tˈɨm, jˈak mˈavʲaw bˌɨwɨ pˌɔtkɔmˈisaʃ kˈɔrsak.|0|Mniejsza z tym, jak mawiał były podkomisarz Korsak.
|
| 78 |
+
Dataset/wavs/urwisko_ferenc/03_segment_130.wav|i pˈɔvʲɛm pˈaɲi, ʒˈɛ jɛst f tɛj muzˈɨtsɛ tsˈɔɕ, tsˈɔ mɲʲɛ pɔtɕˈɔŋɡa.|0|I powiem pani, że jest w tej muzyce coś, co mnie pociąga.
|
| 79 |
+
Dataset/wavs/czytadlo_ferenc/9788367950787_002_Konwicki_Czytadlo_segment_121.wav|ʒˈɛbɨ ˌuratˈɔvatɕ ɕɛ i pʃˈɛʒɨtɕ, pɔtʃˈɛbna jɛzd dˌɨstsɨplˈina, ˌawtɔrˈɨtɛt.|0|Żeby uratować się i przeżyć, potrzebna jest dyscyplina, autorytet.
|
| 80 |
+
Dataset/wavs/urwisko_ferenc/09_segment_113.wav|jˈarɔɲ ɔdvrˈutɕiw ɕɛ dɔ ɲʲˈɛj i pɔwˈɔʒɨw dwˈɔɲ na klˈamtsɛ.|0|Jaroń odwrócił się do niej i położył dłoń na klamce.
|
| 81 |
+
Dataset/wavs/ryz_ferenc/9788367950190_10_Hlasko_Palcie-ryz-kazdego-dnia_segment_30.wav|pʃˌɛtɕɛʃ swˈɨʃɨ pˈaɲi, ʒˈɛ ja mˈuvjɛ z aktsˈɛntɛm.|0|Przecież słyszy pani, że ja mówię z akcentem.
|
| 82 |
+
Dataset/wavs/urwisko_ferenc/36_segment_160.wav|— muvˈiwam jˈuʃ. xtɕˈawa, ʒˈɛbɨ pˈaɲi mʲˈawa ɡdʑˈɛ mʲˈɛʃkatɕ.|0|— Mówiłam już. Chciała, żeby pani miała gdzie mieszkać.
|
| 83 |
+
Dataset/wavs/urwisko_ferenc/62_segment_25.wav|a xaŋɡʲˈɛrski zdˈawa na dʑˌɛvʲɛɲdʑˈɛɕɔnt kˈilka.|0|a hangierski zdała na dziewięćdziesiąt kilka.
|
| 84 |
+
Dataset/wavs/czytadlo_ferenc/9788367950787_009_Konwicki_Czytadlo_segment_148.wav|pˌɔwɔʒˈɨwɛm ɕɛ na sfˈɔim tɕˈɔŋɡlɛ ɲʲˌɛzaswˈanɨm wˈuʃku.|0|Położyłem się na swoim ciągle niezasłanym łóżku.
|
| 85 |
+
Dataset/wavs/urwisko_ferenc/46_segment_114.wav|ˌalɛ tˌɨlkɔ s kˌɔŋkrɛtˈami, ftˈɛdɨ pɔmˈɨɕlɛ.|0|Ale tylko z konkretami, wtedy pomyślę.
|
| 86 |
+
Dataset/wavs/czytadlo_ferenc/9788367950787_004_Konwicki_Czytadlo_segment_270.wav|pˈɛwnɨm jˈakixɕ ɲʲɛjˈasnɨx pɔɡrˈuʒɛk.|0|Pełnym jakichś niejasnych pogróżek.
|
| 87 |
+
Dataset/wavs/czytadlo_ferenc/9788367950787_004_Konwicki_Czytadlo_segment_4.wav|ˌɔtsɨkˈawɨ mɲʲɛ vɨbˈuxɨ ɕmʲˈɛxu na kˌɔrɨtˈaʒu.|0|Ocykały mnie wybuchy śmiechu na korytarzu.
|
| 88 |
+
Dataset/wavs/czytadlo_ferenc/9788367950787_006_Konwicki_Czytadlo_segment_376.wav|vˌɨmɨɕlˈiliɕmˌɨ pˈɛvʲɛn spˈɔsup na zˌaɡwuʃˈaɲʲɛ vʲɛtʃnˈɛɡɔ ɲʲˌɛpɔkˈɔju.|0|Wymyśliliśmy pewien sposób na zagłuszanie wiecznego niepokoju.
|
| 89 |
+
Dataset/wavs/ryz_ferenc/9788367950190_10_Hlasko_Palcie-ryz-kazdego-dnia_segment_73.wav|tɔ jɛst mɔdlˈitfa, tɨ skˌurvɨsˈɨnu, pɔvʲˈɛdʑaw ��andɛrsɔn.|0|To jest modlitwa, ty skurwysynu, powiedział Anderson.
|
| 90 |
+
Dataset/wavs/czytadlo_ferenc/9788367950787_010_Konwicki_Czytadlo_segment_30.wav|i prˌɛzɛntˈɔvaw ɕɛ tˈɛras prˈavʲɛ ˌurɔtʃˈɨɕtɕɛ.|0|I prezentował się teraz prawie uroczyście.
|
| 91 |
+
Dataset/wavs/urwisko_ferenc/43_segment_27.wav|pˈana zdˈaɲʲɛm mˈɔɡwa zapˈɔmɲʲɛtɕ ɔ dʑˈɛtsku i zɔstˈavitɕ jˈɛ f sˌamɔxˈɔdʑɛ?|0|Pana zdaniem mogła zapomnieć o dziecku i zostawić je w samochodzie?
|
| 92 |
+
Dataset/wavs/urwisko_ferenc/18_segment_81.wav|kʲˈɛdɨ xudʑˈiɲski fʃˈɛd dɔ kˌɔrɨtˈaʒa, ɔtstˈaviw tˈɛtʃkɛ i pˌɔtsawˈɔvaw kɔbjˈɛtɛ w ˈusta, a nastˈɛmpɲʲɛ pˈɔdɲʲus xwˈɔptsa.|0|Kiedy Chudziński wszedł do korytarza, odstawił teczkę i pocałował kobietę w usta, a następnie podniósł chłopca.
|
| 93 |
+
Dataset/wavs/ryz_ferenc/9788367950190_06_Hlasko_Palcie-ryz-kazdego-dnia_segment_275.wav|mɛ̃ʃtʃˈɨzna ɔdvrˈutɕiw ɕɛ ɡvawtˈɔvɲʲɛ, pˈatʃɨw pʃˈɛs xfˈilɛ na ɲʲˈɛɡɔ, a pˈɔtɛm ˈɔtʃɛd.|0|Mężczyzna odwrócił się gwałtownie, patrzył przez chwilę na niego, a potem odszedł.
|
| 94 |
+
Dataset/wavs/urwisko_ferenc/08_segment_27.wav|stˈawɨ bɨvˈalɛts ˈimprɛs, kturˌɛɡɔ pˈartja prˌɔpaɡɔvˈawa xʃˌɛɕtɕijˈaɲskʲɛ vartˈɔɕtɕi.|0|Stały bywalec imprez, którego partia propagowała chrześcijańskie wartości.
|
| 95 |
+
Dataset/wavs/urwisko_ferenc/19_segment_22.wav|ˌalɛ skˈɔrɔ vrakˈatɕɛ dɔ ɕlˈɛtstfa, muɕˈitɕɛ mʲˈɛtɕ kɔŋkrˈɛtnɨ pˈɔvut.|0|Ale skoro wracacie do śledztwa, musicie mieć konkretny powód.
|
| 96 |
+
Dataset/wavs/lew_ferenc/08_segment_412.wav|zasˈɔbnɔʑdʑ zwˈuʃ pɔd bɨtˈɔmjɛm mˈa najvˈɨʃʃɛ pˌaramˈɛtrɨ f tsˈawɛj ɲʲˈɛtstsɛ vɛŋɡlˈɔvɛj.|0|Zasobność złóż pod Bytomiem ma najwyższe parametry w całej niecce węglowej.
|
| 97 |
+
Dataset/wavs/ryz_ferenc/9788367950190_09_Hlasko_Palcie-ryz-kazdego-dnia_segment_120.wav|ɕˈɛdʑaw vʲˈɛndʑ w ɡˈurax rˈazɛm zˈɛ sfˈɔim sˈɨnɛm, ktˌurɨ mʲˈaw ɲʲɛvʲˈɛlɛ pˈɔnad dʑˈɛɕɛɲtɕ lˈat.|0|Siedział więc w górach razem ze swoim synem, który miał niewiele ponad dziesięć lat.
|
| 98 |
+
Dataset/wavs/czytadlo_ferenc/9788367950787_010_Konwicki_Czytadlo_segment_108.wav|ˌɔbɛjʒˈawɛm fɔrsˈɨtsjɛ.|0|Obejrzałem forsycję.
|
| 99 |
+
Dataset/wavs/ryz_ferenc/9788367950190_05_Hlasko_Palcie-ryz-kazdego-dnia_segment_238.wav|a ˈɛstɛr ˌɔdvinˈɛwa prˈavɨ rˈɛŋkaf jˈɛɡɔ zrudʑˈawɛj kˌanadˈɨjki.|0|A Ester odwinęła prawy rękaw jego zrudziałej Kanadyjki.
|
| 100 |
+
Dataset/wavs/ryz_ferenc/9788367950190_12_Hlasko_Palcie-ryz-kazdego-dnia_segment_21.wav|tɛn tʃwˈɔvʲɛk ɲʲɛ ˈumjaw ʒˈɨdʑ bˈɛs latˈaɲʲa i bˈɨw jˈuʃ mˈartfɨ. nadwˈuɡɔ pʃˈɛttɛm ɲˈim ɕɛ zˈabʲiw.|0|Ten człowiek nie umiał żyć bez latania i był już martwy. Nadługo przedtem nim się zabił.
|
| 101 |
+
Dataset/wavs/czytadlo_ferenc/9788367950787_006_Konwicki_Czytadlo_segment_312.wav|vʲˈɛm, ʒˈɛ jˈɛdna z nˈaʃɨx wɔntʃɲˈitʃɛk mʲˈɛʃka w ɡdˈaɲsku.|0|Wiem, że jedna z naszych łączniczek mieszka w Gdańsku.
|
| 102 |
+
Dataset/wavs/ryz_ferenc/9788367950190_15_Hlasko_Palcie-ryz-kazdego-dnia_segment_4.wav|lˈɛdʒ dˈɛʒdʒ vrˈutɕiw znˈɔvu.|0|Lecz deszcz wrócił znowu.
|
| 103 |
+
Dataset/wavs/ryz_ferenc/9788367950190_03_Hlasko_Palcie-ryz-kazdego-dnia_segment_306.wav|tʃˌɨtajˈɔntsɨ pʃˈɛrvaw i pɔvʲˈɛdʑaw pɔ xfˈili, f pʃɨʃwˈɔɕtɕi?|0|Czytający przerwał i powiedział po chwili, w przyszłości?
|
| 104 |
+
Dataset/wavs/czytadlo_ferenc/9788367950787_003_Konwicki_Czytadlo_segment_386.wav|pˈan pɔzvˈɔli, ʒˈɛɡw dɔ mɲʲɛ i pɔkˈazaw ˌuvalˈanɔ̃ w ˌatramˈɛɲtɕɛ rˈɛŋkɔ̃ nˈaʃɛ zˌardʑɛvʲˈawɛ dʒvˈi.|0|Pan pozwoli, rzekł do mnie i pokazał uwalaną w atramencie ręką nasze zardzewiałe drzwi.
|
| 105 |
+
Dataset/wavs/czytadlo_ferenc/9788367950787_001_Konwicki_Czytadlo_segment_111.wav|tsɔdʑˈɛnnɨm smˈɔɡʲɛm, rɔzmˈɨtɕɛm ˌɔddalˈɛɲʲa, ʒˈɛ pˌɔmɨɕlˈawɛm...|0|Codziennym smogiem, rozmyciem oddalenia, że pomyślałem...
|
| 106 |
+
Dataset/wavs/ryz_ferenc/9788367950190_03_Hlasko_Palcie-ryz-kazdego-dnia_segment_419.wav|tˈak tɔ vɨɡlˈɔnda.|0|Tak to wygląda.
|
Data/normalize_log.csv
ADDED
|
@@ -0,0 +1,3 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
version https://git-lfs.github.com/spec/v1
|
| 2 |
+
oid sha256:705c026e32b38f0151b35b10b91640f000c529c28ad8f4cc0d8fde960087788e
|
| 3 |
+
size 10694681
|
Data/syspin.txt
ADDED
|
@@ -0,0 +1,3 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
version https://git-lfs.github.com/spec/v1
|
| 2 |
+
oid sha256:63de2cd14152736cf300d73810def2c439f10caed73389448c64479db5920c83
|
| 3 |
+
size 11781738
|
Data/texts/check.py
ADDED
|
@@ -0,0 +1,102 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
#!/usr/bin/env python3
|
| 2 |
+
import glob
|
| 3 |
+
import os
|
| 4 |
+
|
| 5 |
+
# ---------------- CONFIG ----------------
|
| 6 |
+
INPUT_GLOB = "*.txt" # which files to check (e.g. "*.txt", "data_*.txt")
|
| 7 |
+
EXPECT_WAV_EXT = True # set False if path doesn't have to end with .wav
|
| 8 |
+
# ----------------------------------------
|
| 9 |
+
|
| 10 |
+
|
| 11 |
+
def check_line_format(line: str, line_num: int, filename: str):
|
| 12 |
+
"""
|
| 13 |
+
Check if a line matches: path|phonemes|speaker_id|language_id|rawtext
|
| 14 |
+
Returns None if OK, or an error message string if NOT OK.
|
| 15 |
+
"""
|
| 16 |
+
stripped = line.rstrip("\n")
|
| 17 |
+
|
| 18 |
+
# Ignore empty lines
|
| 19 |
+
if not stripped.strip():
|
| 20 |
+
return None
|
| 21 |
+
|
| 22 |
+
# Ignore comment lines (optional)
|
| 23 |
+
if stripped.lstrip().startswith("#"):
|
| 24 |
+
return None
|
| 25 |
+
|
| 26 |
+
parts = stripped.split("|")
|
| 27 |
+
|
| 28 |
+
if len(parts) < 5:
|
| 29 |
+
return f"{filename}:{line_num}: expected >=5 fields, found {len(parts)} → {stripped!r}"
|
| 30 |
+
|
| 31 |
+
path = parts[0].strip()
|
| 32 |
+
phonemes = parts[1].strip()
|
| 33 |
+
speaker_id_str = parts[2].strip()
|
| 34 |
+
lang_id_str = parts[3].strip()
|
| 35 |
+
rawtext = "|".join(parts[4:]).strip() # in case rawtext itself had pipes in future
|
| 36 |
+
|
| 37 |
+
if not path:
|
| 38 |
+
return f"{filename}:{line_num}: empty path field"
|
| 39 |
+
|
| 40 |
+
if EXPECT_WAV_EXT and not path.lower().endswith(".wav"):
|
| 41 |
+
return f"{filename}:{line_num}: path does not end with .wav → {path!r}"
|
| 42 |
+
|
| 43 |
+
# speaker_id must be int
|
| 44 |
+
try:
|
| 45 |
+
int(speaker_id_str)
|
| 46 |
+
except ValueError:
|
| 47 |
+
return f"{filename}:{line_num}: speaker_id not an int → {speaker_id_str!r}"
|
| 48 |
+
|
| 49 |
+
# language_id must be int
|
| 50 |
+
try:
|
| 51 |
+
int(lang_id_str)
|
| 52 |
+
except ValueError:
|
| 53 |
+
return f"{filename}:{line_num}: language_id not an int → {lang_id_str!r}"
|
| 54 |
+
|
| 55 |
+
if not rawtext:
|
| 56 |
+
return f"{filename}:{line_num}: empty rawtext field"
|
| 57 |
+
|
| 58 |
+
# phonemes we just require to exist (can be empty if you allow that)
|
| 59 |
+
# if you *require* non-empty phonemes, uncomment:
|
| 60 |
+
# if not phonemes:
|
| 61 |
+
# return f"{filename}:{line_num}: empty phonemes field"
|
| 62 |
+
|
| 63 |
+
return None # all good
|
| 64 |
+
|
| 65 |
+
|
| 66 |
+
def main():
|
| 67 |
+
files = sorted(glob.glob(INPUT_GLOB))
|
| 68 |
+
if not files:
|
| 69 |
+
print("⚠️ No files matched pattern:", INPUT_GLOB)
|
| 70 |
+
return
|
| 71 |
+
|
| 72 |
+
print(f"📂 Checking {len(files)} file(s): {files}")
|
| 73 |
+
|
| 74 |
+
total_errors = 0
|
| 75 |
+
for fname in files:
|
| 76 |
+
errors_for_file = []
|
| 77 |
+
with open(fname, "r", encoding="utf-8") as f:
|
| 78 |
+
for i, line in enumerate(f, start=1):
|
| 79 |
+
err = check_line_format(line, i, fname)
|
| 80 |
+
if err:
|
| 81 |
+
errors_for_file.append(err)
|
| 82 |
+
|
| 83 |
+
if errors_for_file:
|
| 84 |
+
total_errors += len(errors_for_file)
|
| 85 |
+
print(f"\n❌ {fname}: {len(errors_for_file)} line(s) with format issues")
|
| 86 |
+
# Show first few errors to avoid spam
|
| 87 |
+
for msg in errors_for_file[:10]:
|
| 88 |
+
print(" ", msg)
|
| 89 |
+
if len(errors_for_file) > 10:
|
| 90 |
+
print(f" ... and {len(errors_for_file) - 10} more")
|
| 91 |
+
else:
|
| 92 |
+
print(f"✅ {fname}: all lines OK")
|
| 93 |
+
|
| 94 |
+
if total_errors == 0:
|
| 95 |
+
print("\n🎉 All checked files are in correct format.")
|
| 96 |
+
else:
|
| 97 |
+
print(f"\n⚠️ Done. Total problematic lines across all files: {total_errors}")
|
| 98 |
+
|
| 99 |
+
|
| 100 |
+
if __name__ == "__main__":
|
| 101 |
+
main()
|
| 102 |
+
|
Data/texts/cor.py
ADDED
|
@@ -0,0 +1,139 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
#!/usr/bin/env python3
|
| 2 |
+
import os
|
| 3 |
+
|
| 4 |
+
INPUT_FILE = "syspin.txt"
|
| 5 |
+
OUTPUT_FILE = "syspin_fixed.txt"
|
| 6 |
+
DEFAULT_LANG_ID = 2 # Hindi language id
|
| 7 |
+
PATH_PREFIX = "syspin/" # what a “real” record line starts with
|
| 8 |
+
|
| 9 |
+
|
| 10 |
+
def join_logical_lines(path_prefix=PATH_PREFIX):
|
| 11 |
+
"""
|
| 12 |
+
Join wrapped lines so each logical record becomes a single string.
|
| 13 |
+
|
| 14 |
+
Any line starting with `path_prefix` (e.g. 'syspin/') starts a new record.
|
| 15 |
+
Any following non-empty line that does NOT start with that prefix is
|
| 16 |
+
treated as continuation of the previous record's raw text.
|
| 17 |
+
"""
|
| 18 |
+
logical = []
|
| 19 |
+
current = None
|
| 20 |
+
|
| 21 |
+
with open(INPUT_FILE, "r", encoding="utf-8") as f:
|
| 22 |
+
for raw in f:
|
| 23 |
+
stripped = raw.rstrip("\n")
|
| 24 |
+
if not stripped.strip():
|
| 25 |
+
continue # skip empty lines
|
| 26 |
+
|
| 27 |
+
if stripped.startswith(path_prefix):
|
| 28 |
+
# Start of a new record
|
| 29 |
+
if current is not None:
|
| 30 |
+
logical.append(current)
|
| 31 |
+
current = stripped
|
| 32 |
+
else:
|
| 33 |
+
# Continuation of previous record's text
|
| 34 |
+
if current is None:
|
| 35 |
+
# stray line, ignore or keep separately if you want
|
| 36 |
+
continue
|
| 37 |
+
current += " " + stripped.strip()
|
| 38 |
+
|
| 39 |
+
if current is not None:
|
| 40 |
+
logical.append(current)
|
| 41 |
+
|
| 42 |
+
return logical
|
| 43 |
+
|
| 44 |
+
|
| 45 |
+
def fix_record(line: str) -> str:
|
| 46 |
+
"""
|
| 47 |
+
Parse a single logical record and ensure it has:
|
| 48 |
+
path|phonemes|speaker|lang|rawtext...
|
| 49 |
+
|
| 50 |
+
Handles:
|
| 51 |
+
- old 4-field format: path|phonemes|speaker|rawtext...
|
| 52 |
+
- new 5-field format: path|phonemes|speaker|lang|rawtext...
|
| 53 |
+
|
| 54 |
+
Rawtext can contain '|' and spaces.
|
| 55 |
+
"""
|
| 56 |
+
line = line.strip()
|
| 57 |
+
if not line:
|
| 58 |
+
return line
|
| 59 |
+
|
| 60 |
+
# 1) Split off path
|
| 61 |
+
try:
|
| 62 |
+
path, rest = line.split("|", 1)
|
| 63 |
+
except ValueError:
|
| 64 |
+
# No '|' at all, just return as-is
|
| 65 |
+
return line
|
| 66 |
+
|
| 67 |
+
path = path.strip()
|
| 68 |
+
|
| 69 |
+
# 2) Split off phonemes
|
| 70 |
+
try:
|
| 71 |
+
phonemes, rest2 = rest.split("|", 1)
|
| 72 |
+
except ValueError:
|
| 73 |
+
return line # malformed, leave as-is
|
| 74 |
+
|
| 75 |
+
# 3) Try to parse speaker, lang, rawtext with controlled splits
|
| 76 |
+
# rest2 is "speaker|lang|rawtext..." or "speaker|rawtext..."
|
| 77 |
+
parts = rest2.split("|", 2)
|
| 78 |
+
|
| 79 |
+
# Case A: we have at least speaker, lang, rawtext
|
| 80 |
+
if len(parts) == 3:
|
| 81 |
+
speaker_str = parts[0].strip()
|
| 82 |
+
lang_or_raw = parts[1].strip()
|
| 83 |
+
raw_rest = parts[2] # may contain more '|'
|
| 84 |
+
|
| 85 |
+
# speaker must be int
|
| 86 |
+
try:
|
| 87 |
+
int(speaker_str)
|
| 88 |
+
except ValueError:
|
| 89 |
+
return line # not our expected format
|
| 90 |
+
|
| 91 |
+
# If lang_or_raw is int, this is already 5-field format
|
| 92 |
+
try:
|
| 93 |
+
int(lang_or_raw)
|
| 94 |
+
lang_str = lang_or_raw
|
| 95 |
+
rawtext = raw_rest
|
| 96 |
+
return f"{path}|{phonemes}|{speaker_str}|{lang_str}|{rawtext}"
|
| 97 |
+
except ValueError:
|
| 98 |
+
# This is actually 4-field, but rawtext itself had '|'
|
| 99 |
+
# Original shape: speaker|raw_part1|raw_rest
|
| 100 |
+
# So we reassemble rawtext:
|
| 101 |
+
rawtext = lang_or_raw + "|" + raw_rest
|
| 102 |
+
lang_str = str(DEFAULT_LANG_ID)
|
| 103 |
+
return f"{path}|{phonemes}|{speaker_str}|{lang_str}|{rawtext}"
|
| 104 |
+
|
| 105 |
+
# Case B: we only have "speaker|rawtext..."
|
| 106 |
+
elif len(parts) == 2:
|
| 107 |
+
speaker_str = parts[0].strip()
|
| 108 |
+
rawtext = parts[1]
|
| 109 |
+
|
| 110 |
+
try:
|
| 111 |
+
int(speaker_str)
|
| 112 |
+
except ValueError:
|
| 113 |
+
return line
|
| 114 |
+
|
| 115 |
+
lang_str = str(DEFAULT_LANG_ID)
|
| 116 |
+
return f"{path}|{phonemes}|{speaker_str}|{lang_str}|{rawtext}"
|
| 117 |
+
|
| 118 |
+
# Anything else: leave unchanged
|
| 119 |
+
return line
|
| 120 |
+
|
| 121 |
+
|
| 122 |
+
def main():
|
| 123 |
+
print(f"🔍 Joining logical lines from {INPUT_FILE}...")
|
| 124 |
+
logical_lines = join_logical_lines()
|
| 125 |
+
|
| 126 |
+
print(f"📦 Found {len(logical_lines)} logical records. Fixing format...")
|
| 127 |
+
fixed = [fix_record(l) for l in logical_lines]
|
| 128 |
+
|
| 129 |
+
with open(OUTPUT_FILE, "w", encoding="utf-8") as f:
|
| 130 |
+
for l in fixed:
|
| 131 |
+
f.write(l + "\n")
|
| 132 |
+
|
| 133 |
+
print(f"✅ Wrote fixed file to {OUTPUT_FILE}")
|
| 134 |
+
print("👉 Now run your check script on syspin_fixed.txt instead of syspin.txt")
|
| 135 |
+
|
| 136 |
+
|
| 137 |
+
if __name__ == "__main__":
|
| 138 |
+
main()
|
| 139 |
+
|
Data/texts/dataset.txt
ADDED
|
The diff for this file is too large to render.
See raw diff
|
|
|
Data/texts/fin.txt
ADDED
|
@@ -0,0 +1,3 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
version https://git-lfs.github.com/spec/v1
|
| 2 |
+
oid sha256:2b6553b3035a803ba52283e8c1b1e02df58c08906b1f530b37a7f0741861c470
|
| 3 |
+
size 36893682
|
Data/texts/merge.py
ADDED
|
@@ -0,0 +1,46 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
#!/usr/bin/env python3
|
| 2 |
+
import os
|
| 3 |
+
import glob
|
| 4 |
+
|
| 5 |
+
# ---------------- CONFIG ----------------
|
| 6 |
+
INPUT_GLOB = "*.txt" # all text files in current directory
|
| 7 |
+
OUTPUT_FILE = "merged_sorted.txt" # output filename
|
| 8 |
+
LANGUAGE_COL_INDEX = 3 # 0-based index (4th column = language id)
|
| 9 |
+
# ----------------------------------------
|
| 10 |
+
|
| 11 |
+
def parse_line(line):
|
| 12 |
+
"""Split and return (lang_id, line) if valid."""
|
| 13 |
+
parts = line.strip().split("|")
|
| 14 |
+
if len(parts) > LANGUAGE_COL_INDEX:
|
| 15 |
+
try:
|
| 16 |
+
lang_id = int(parts[LANGUAGE_COL_INDEX])
|
| 17 |
+
return lang_id, line.strip()
|
| 18 |
+
except ValueError:
|
| 19 |
+
pass
|
| 20 |
+
return None, line.strip()
|
| 21 |
+
|
| 22 |
+
def main():
|
| 23 |
+
# Gather all .txt files
|
| 24 |
+
files = sorted(glob.glob(INPUT_GLOB))
|
| 25 |
+
print(f"📂 Found {len(files)} text files: {files}")
|
| 26 |
+
|
| 27 |
+
all_lines = []
|
| 28 |
+
for file in files:
|
| 29 |
+
with open(file, "r", encoding="utf-8") as f:
|
| 30 |
+
for line in f:
|
| 31 |
+
if line.strip():
|
| 32 |
+
lang_id, full_line = parse_line(line)
|
| 33 |
+
all_lines.append((lang_id, full_line))
|
| 34 |
+
|
| 35 |
+
# Sort by language ID (then by filename order for consistency)
|
| 36 |
+
all_lines.sort(key=lambda x: (x[0], x[1]))
|
| 37 |
+
|
| 38 |
+
with open(OUTPUT_FILE, "w", encoding="utf-8") as f:
|
| 39 |
+
for _, line in all_lines:
|
| 40 |
+
f.write(line + "\n")
|
| 41 |
+
|
| 42 |
+
print(f"✅ Merged and sorted {len(all_lines)} lines into {OUTPUT_FILE}")
|
| 43 |
+
|
| 44 |
+
if __name__ == "__main__":
|
| 45 |
+
main()
|
| 46 |
+
|
Data/train_3.txt
ADDED
|
@@ -0,0 +1,3 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
version https://git-lfs.github.com/spec/v1
|
| 2 |
+
oid sha256:8a91f40aa64b12431823c2046ff835e8a5bb7e624c47b5915547b6a2558cf6bc
|
| 3 |
+
size 47346672
|
Data/train_3_filtered.txt
ADDED
|
@@ -0,0 +1,3 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
version https://git-lfs.github.com/spec/v1
|
| 2 |
+
oid sha256:bd29f1d22ef76f02d7843fd6ffbe46ee12c38e52e4f6f0614a6f989c8029452d
|
| 3 |
+
size 35290704
|
Data/train_3_filtered_1.txt
ADDED
|
@@ -0,0 +1,3 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
version https://git-lfs.github.com/spec/v1
|
| 2 |
+
oid sha256:e204501375a046beda88812643e222be5c49346ea690a5215db73a9838d3c188
|
| 3 |
+
size 35253822
|
Data/train_3_filtered_dur.txt
ADDED
|
@@ -0,0 +1,3 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
version https://git-lfs.github.com/spec/v1
|
| 2 |
+
oid sha256:2930e002060edbac2eea683909074d4270a02e66e759ccd7830e73c256efecca
|
| 3 |
+
size 32913633
|
Data/train_3_filtered_dur_fixed.txt
ADDED
|
@@ -0,0 +1,3 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
version https://git-lfs.github.com/spec/v1
|
| 2 |
+
oid sha256:f1f1c6cd7d04573ea56fbbd24792e28c9716ace5bc4b7ec2b991d8a4ac7ac57f
|
| 3 |
+
size 33069989
|
Data/train_3_filtered_dur_fixed_copy.txt
ADDED
|
@@ -0,0 +1,3 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
version https://git-lfs.github.com/spec/v1
|
| 2 |
+
oid sha256:fad71ba31150e12bb27836601326157ac6791b227ef7104a0d26d6a5cb3e9a2c
|
| 3 |
+
size 30886753
|
Data/train_3_filtered_dur_fixed_speakers.txt
ADDED
|
@@ -0,0 +1,3 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
version https://git-lfs.github.com/spec/v1
|
| 2 |
+
oid sha256:4f3fb1ccb7717292f5f226a0747f211e24bcb435bfbe9798066aa853dfcb203e
|
| 3 |
+
size 33069989
|