{"metadata":{"kernelspec":{"language":"python","display_name":"Python 3","name":"python3"},"language_info":{"pygments_lexer":"ipython3","nbconvert_exporter":"python","version":"3.6.4","file_extension":".py","codemirror_mode":{"name":"ipython","version":3},"name":"python","mimetype":"text/x-python"}},"nbformat_minor":4,"nbformat":4,"cells":[{"cell_type":"markdown","source":"# Audios Split\n\nThere are differents audio sizes in the dataset. One approach that I have seen is take a random 5 seconds duration sample from each audio. \nMaybe another approach could be splitting all audios in `CFG.duration` seconds and label them with the same `primary_label`\n\nIn this notebook I take the birdclef 2023 dataset and split it in a bunch of different audios of `CFG.duration` seconds. So we can have a large dataset.","metadata":{"_uuid":"8f2839f25d086af736a60e9eeb907d3b93b6e0e5","_cell_guid":"b1076dfc-b9ad-4769-8c92-a6c4dae69d19"}},{"cell_type":"markdown","source":"## Libraries","metadata":{}},{"cell_type":"code","source":"import os\nimport re\nimport soundfile as sf\nimport librosa\nimport pandas as pd\nimport numpy as np\nfrom tqdm import tqdm\nimport torch\ntqdm.pandas()\n","metadata":{"execution":{"iopub.status.busy":"2023-04-23T20:26:06.952377Z","iopub.execute_input":"2023-04-23T20:26:06.952797Z","iopub.status.idle":"2023-04-23T20:26:09.425401Z","shell.execute_reply.started":"2023-04-23T20:26:06.952761Z","shell.execute_reply":"2023-04-23T20:26:09.424152Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"## Configuration","metadata":{}},{"cell_type":"code","source":"class CFG:\n    DURATION = 5 \n    AUDIOS_PATH = \"/kaggle/input/birdclef-2023/train_audio\"","metadata":{"execution":{"iopub.status.busy":"2023-04-23T20:25:32.909465Z","iopub.execute_input":"2023-04-23T20:25:32.909937Z","iopub.status.idle":"2023-04-23T20:25:32.916360Z","shell.execute_reply.started":"2023-04-23T20:25:32.909892Z","shell.execute_reply":"2023-04-23T20:25:32.915010Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"## Split Audios Function","metadata":{}},{"cell_type":"code","source":"# We need to pad those audios that are shorter than CFG.duration seconds\ndef pad(signal, num_samples):\n        length_signal = len(signal)\n        if length_signal < num_samples:\n            num_missing_samples = num_samples - length_signal\n            last_dim_padding = (0, num_missing_samples)\n            signal = torch.nn.functional.pad(torch.from_numpy(signal), last_dim_padding)\n        return signal","metadata":{"execution":{"iopub.status.busy":"2023-04-23T20:14:17.936124Z","iopub.execute_input":"2023-04-23T20:14:17.936552Z","iopub.status.idle":"2023-04-23T20:14:17.943042Z","shell.execute_reply.started":"2023-04-23T20:14:17.936510Z","shell.execute_reply":"2023-04-23T20:14:17.941567Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"def split_audio(row, duration=CFG.DURATION):\n    # Path and filename from metadata\n    path = row.filename\n    audio_name = re.search(r\"/(.*?)\\.\", path).group(1)\n    label = path.split(\"/\")[0]\n    \n    # create class folder\n    class_folder = os.path.join(new_path,label) \n    if not os.path.exists(class_folder):\n        os.mkdir(class_folder)\n    \n    # load audio\n    samples, sr = librosa.load(os.path.join(CFG.AUDIOS_PATH, path))\n    n_duration_samples = sr*duration # frame size\n    samples = pad(samples, n_duration_samples) # pad if signal lower than duration\n    \n    # split\n    splits = librosa.util.frame(samples, frame_length = n_duration_samples, hop_length = n_duration_samples)\n    \n    # save\n    new_rows = []\n    for i in range(splits.shape[1]):\n        new_row = row.copy()\n        new_filename = f\"{audio_name}_{i}.ogg\"\n        new_row.filename = f\"{label}/{new_filename}\"\n        audio = splits[:,i]\n        file_path = os.path.join(class_folder,new_filename)\n        sf.write(file_path, audio, sr)\n        new_rows.append(new_row)\n    return new_rows\n    \n    \n        \n    \n        \n    ","metadata":{"execution":{"iopub.status.busy":"2023-04-23T20:17:09.652501Z","iopub.execute_input":"2023-04-23T20:17:09.653642Z","iopub.status.idle":"2023-04-23T20:17:09.663934Z","shell.execute_reply.started":"2023-04-23T20:17:09.653590Z","shell.execute_reply":"2023-04-23T20:17:09.662505Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"## Split Audios","metadata":{}},{"cell_type":"code","source":"metadata = pd.read_csv('/kaggle/input/birdclef-2023/train_metadata.csv')\nmetadata.head()","metadata":{"execution":{"iopub.status.busy":"2023-04-23T20:23:05.192687Z","iopub.execute_input":"2023-04-23T20:23:05.193411Z","iopub.status.idle":"2023-04-23T20:23:05.378746Z","shell.execute_reply.started":"2023-04-23T20:23:05.193365Z","shell.execute_reply":"2023-04-23T20:23:05.377413Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"### 5 seconds split","metadata":{}},{"cell_type":"code","source":"class CFG:\n    DURATION = 5 \n    AUDIOS_PATH = \"/kaggle/input/birdclef-2023/train_audio\"","metadata":{"execution":{"iopub.status.busy":"2023-04-23T22:34:43.455685Z","iopub.execute_input":"2023-04-23T22:34:43.456540Z","iopub.status.idle":"2023-04-23T22:34:43.465260Z","shell.execute_reply.started":"2023-04-23T22:34:43.456478Z","shell.execute_reply":"2023-04-23T22:34:43.461916Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# We create the new dataset path\nnew_path = f\"split_train_{CFG.DURATION}s\"\nif not os.path.exists(new_path):\n    os.mkdir(new_path)","metadata":{},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"split_df = pd.DataFrame(columns = metadata.columns)\nlist_dfs = []   \nfor i, row in tqdm(metadata.iterrows(), total=metadata.shape[0]):\n    new_rows = split_audio(row, duration=CFG.DURATION)\n    list_dfs.append(pd.DataFrame(data = new_rows, columns = split_df.columns))\n    \nsplit_df = pd.concat([split_df] + list_dfs, axis = 0)\n    ","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"import shutil\nshutil.make_archive(f\"split_train{CFG.DURATION}_s\", 'zip', f\"/kaggle/working/split_train_{CFG.DURATION}s\")","metadata":{"execution":{"iopub.status.busy":"2023-04-23T22:20:57.423801Z","iopub.execute_input":"2023-04-23T22:20:57.424284Z","iopub.status.idle":"2023-04-23T22:25:59.149259Z","shell.execute_reply.started":"2023-04-23T22:20:57.424240Z","shell.execute_reply":"2023-04-23T22:25:59.146151Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"### 10 seconds split","metadata":{}},{"cell_type":"code","source":"class CFG:\n    DURATION = 10\n    AUDIOS_PATH = \"/kaggle/input/birdclef-2023/train_audio\"","metadata":{},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# We create the new dataset path\nnew_path = f\"split_train_{CFG.DURATION}s\"\nif not os.path.exists(new_path):\n    os.mkdir(new_path)","metadata":{},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"split_df = pd.DataFrame(columns = metadata.columns)\nlist_dfs = []   \nfor i, row in tqdm(metadata.iterrows(), total=metadata.shape[0]):\n    new_rows = split_audio(row, duration=CFG.DURATION)\n    list_dfs.append(pd.DataFrame(data = new_rows, columns = split_df.columns))\n    \nsplit_df = pd.concat([split_df] + list_dfs, axis = 0)\n    ","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"import shutil\nshutil.make_archive(f\"split_train{CFG.DURATION}_s\", 'zip', f\"/kaggle/working/split_train_{CFG.DURATION}s\")","metadata":{"execution":{"iopub.status.busy":"2023-04-23T22:20:57.423801Z","iopub.execute_input":"2023-04-23T22:20:57.424284Z","iopub.status.idle":"2023-04-23T22:25:59.149259Z","shell.execute_reply.started":"2023-04-23T22:20:57.424240Z","shell.execute_reply":"2023-04-23T22:25:59.146151Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"","metadata":{},"execution_count":null,"outputs":[]}]}