|
|
import pandas as pd |
|
|
import os |
|
|
import librosa |
|
|
import soundfile as sf |
|
|
from tqdm import tqdm |
|
|
|
|
|
|
|
|
TARGET_SR = 16000 |
|
|
|
|
|
|
|
|
BASE_DATA_PATH = '../data/common_voice/cv-corpus-22.0-2025-06-20/pt/' |
|
|
METADATA_FILE = os.path.join(BASE_DATA_PATH, 'validated.tsv') |
|
|
AUDIO_CLIPS_PATH = os.path.join(BASE_DATA_PATH, 'clips') |
|
|
|
|
|
|
|
|
OUTPUT_PATH = '../dataset_preparado/' |
|
|
OUTPUT_BR_PATH = os.path.join(OUTPUT_PATH, 'pt_br') |
|
|
OUTPUT_PT_PATH = os.path.join(OUTPUT_PATH, 'pt_pt') |
|
|
|
|
|
|
|
|
VARIANT_MAP = { |
|
|
'Portuguese (Brasil)': 'pt_br', |
|
|
'Portuguese (Portugal)': 'pt_pt' |
|
|
} |
|
|
PATH_MAP = { |
|
|
'pt_br': OUTPUT_BR_PATH, |
|
|
'pt_pt': OUTPUT_PT_PATH |
|
|
} |
|
|
|
|
|
def preprocess_common_voice(): |
|
|
print("Iniciando o pré-processamento do Common Voice...") |
|
|
|
|
|
os.makedirs(OUTPUT_BR_PATH, exist_ok=True) |
|
|
os.makedirs(OUTPUT_PT_PATH, exist_ok=True) |
|
|
|
|
|
try: |
|
|
df = pd.read_csv(METADATA_FILE, sep='\t') |
|
|
except FileNotFoundError: |
|
|
print(f"Erro: Arquivo de metadados não encontrado em {METADATA_FILE}") |
|
|
return |
|
|
|
|
|
df = df[['path', 'variant']].dropna() |
|
|
df = df[df['variant'].isin(VARIANT_MAP.keys())] |
|
|
df['label'] = df['variant'].map(VARIANT_MAP) |
|
|
|
|
|
print(f"Amostras encontradas por sotaque (antes do balanceamento):\n{df['label'].value_counts()}") |
|
|
|
|
|
|
|
|
class_counts = df['label'].value_counts().to_dict() |
|
|
if not class_counts or len(class_counts) < 2: |
|
|
print("Erro: Não foram encontradas amostras suficientes de ambas as classes para balancear.") |
|
|
return |
|
|
|
|
|
min_samples = min(class_counts.values()) |
|
|
print(f"Classe minoritária tem {min_samples} amostras. Usando este valor para o balanceamento.") |
|
|
|
|
|
|
|
|
df = df.sample(frac=1).reset_index(drop=True) |
|
|
|
|
|
|
|
|
max_samples_per_class = min_samples |
|
|
counters = {'pt_br': 0, 'pt_pt': 0} |
|
|
|
|
|
for _, row in tqdm(df.iterrows(), total=df.shape[0], desc="Processando áudios"): |
|
|
label = row['label'] |
|
|
|
|
|
if counters[label] >= max_samples_per_class: |
|
|
continue |
|
|
|
|
|
source_audio_path = os.path.join(AUDIO_CLIPS_PATH, row['path']) |
|
|
filename = os.path.splitext(row['path'])[0] + '.wav' |
|
|
dest_path = os.path.join(PATH_MAP[label], f"cv_{filename}") |
|
|
|
|
|
try: |
|
|
audio, sr = librosa.load(source_audio_path, sr=TARGET_SR, mono=True) |
|
|
sf.write(dest_path, audio, TARGET_SR) |
|
|
counters[label] += 1 |
|
|
except Exception as e: |
|
|
print(f"Aviso: Não foi possível processar {source_audio_path}. Erro: {e}") |
|
|
|
|
|
print("\nPré-processamento do Common Voice concluído!") |
|
|
print(f"Amostras salvas (balanceado): {counters}") |
|
|
|
|
|
if __name__ == '__main__': |
|
|
preprocess_common_voice() |