{"metadata":{"kernelspec":{"language":"python","display_name":"Python 3","name":"python3"},"language_info":{"name":"python","version":"3.10.12","mimetype":"text/x-python","codemirror_mode":{"name":"ipython","version":3},"pygments_lexer":"ipython3","nbconvert_exporter":"python","file_extension":".py"},"kaggle":{"accelerator":"none","dataSources":[{"sourceId":91844,"databundleVersionId":11361821,"isSourceIdPinned":false,"sourceType":"competition"}],"dockerImageVersionId":30918,"isInternetEnabled":true,"language":"python","sourceType":"notebook","isGpuEnabled":false}},"nbformat_minor":4,"nbformat":4,"cells":[{"cell_type":"code","source":"import os\nimport shutil\nimport librosa\nimport torch\nimport torchaudio\nimport soundfile as sf\nimport numpy as np\nfrom pydub import AudioSegment\nfrom tqdm import tqdm\nimport sys\nimport pandas as pd\n\nsource_folder = \"/kaggle/input/birdclef-2025\"\ndestination_folder = \"/kaggle/working/\"\nidx = 0\n\n# Đảm bảo thư mục đích tồn tại\nos.makedirs(destination_folder, exist_ok=True)\n\nmodel, (get_speech_timestamps, _, read_audio, _, _) = torch.hub.load(repo_or_dir='snakers4/silero-vad', model='silero_vad')\n\ntorchaudio.set_audio_backend(\"ffmpeg\")\n\ndef process_ogg_file(src_path, dest_path, human_path):\n    # Load file OGG bằng torchaudio\n    wav_tensor, sr = torchaudio.load(src_path)  # wav_tensor: (channels, time)\n\n    # Nếu stereo → chuyển sang mono\n    if wav_tensor.shape[0] > 1:\n        wav_tensor = torch.mean(wav_tensor, dim=0, keepdim=True)\n\n    # Phát hiện vùng có tiếng người\n    speech_timestamps = get_speech_timestamps(wav_tensor.squeeze(0), model)\n\n    if len(speech_timestamps) > 0:\n        nonhuman_wav = []\n        human_wav = []\n        start_point = 0\n\n        for st in speech_timestamps:\n            # Lưu vùng không có tiếng người\n            if st['start'] > start_point:\n                nonhuman_wav.append(wav_tensor[:, start_point:st['start']])\n            # Lưu vùng có tiếng người\n            human_wav.append(wav_tensor[:, st['start']:st['end']])\n            start_point = st['end']\n\n        # Phần còn lại sau đoạn cuối\n        if start_point < wav_tensor.shape[1]:\n            nonhuman_wav.append(wav_tensor[:, start_point:])\n\n        # Nối lại\n        if len(nonhuman_wav) > 0:\n            nonhuman_tensor = torch.cat(nonhuman_wav, dim=1)\n            torchaudio.save(dest_path, nonhuman_tensor, sr, format=\"mp3\")\n        if len(human_wav) > 0:\n            human_tensor = torch.cat(human_wav, dim=1)\n            torchaudio.save(human_path, human_tensor, sr, format=\"mp3\")\n\nlist_src_files = []\nlist_dest_files = []\n\n# Duyệt toàn bộ file và thư mục con\nfor root, _, files in os.walk(source_folder):\n    relative_path = os.path.relpath(root, source_folder)\n    dest_dir = os.path.join(destination_folder, relative_path)\n    os.makedirs(dest_dir, exist_ok=True)\n    \n    for file in files:\n        src_file_path = os.path.join(root, file)\n        dest_file_path = os.path.join(dest_dir, file)\n\n        list_src_files.append(src_file_path)\n        list_dest_files.append(dest_file_path)\n\ntotal_files = len(list_src_files) // 5\n\nfor src_file, dest_file in tqdm(zip(list_src_files[idx*total_files:(idx+1)*total_files], list_dest_files[idx*total_files:(idx+1)*total_files]), total=total_files):\n    if src_file.endswith(\".ogg\") and 'train_soundscapes' not in src_file:\n        name, ext = os.path.splitext(dest_file)\n        dest_file = f\"{name}.mp3\"\n        human_file = f\"{name}-human.mp3\"\n        process_ogg_file(src_file, dest_file, human_file)\n    else:\n        shutil.copy2(src_file, dest_file)\n\ntrain = pd.read_csv('/kaggle/input/birdclef-2025/train.csv')\ntrain['filename'] = train['filename'].str.replace('.ogg', '.mp3')\ntrain.to_csv('train.csv', index=False)","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-05-19T08:31:32.852288Z","iopub.execute_input":"2025-05-19T08:31:32.852663Z","iopub.status.idle":"2025-05-19T08:32:00.394833Z","shell.execute_reply.started":"2025-05-19T08:31:32.852627Z","shell.execute_reply":"2025-05-19T08:32:00.393914Z"}},"outputs":[],"execution_count":null}]}