{"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":"# <h><center><b>🐧BIRDCIEF 🐤 2023🐧</b></center></h>\n\n<img src = 'https://external-content.duckduckgo.com/iu/?u=https%3A%2F%2Fimages.deepai.org%2Fconverted-papers%2F2001.04758%2Fx7.png&f=1&nofb=1&ipt=4267ee8c2ec710ca49a6ecc695bffcb07c6031f771cf313186a358e3cd3977b4&ipo=images' class=\"center\">\n\n## ***This time I am trying to generate the audio to particular part of image generation using pytorch lighting***","metadata":{}},{"cell_type":"markdown","source":"# **Import necessary library**","metadata":{}},{"cell_type":"code","source":"!pip install -q noisereduce\n!pip wheel -q https://github.com/Borda/kaggle_image-classify/archive/refs/heads/main.zip --wheel-dir frozen_packages\n!pip wheel -q https://github.com/PyTorchLightning/lightning-flash/archive/refs/heads/feature/soft_targets.zip --wheel-dir frozen_packages\n!rm frozen_packages/torch*\n!ls -l frozen_packages | grep -e kaggle -e flash","metadata":{"execution":{"iopub.status.busy":"2023-03-20T17:01:34.425833Z","iopub.execute_input":"2023-03-20T17:01:34.426640Z","iopub.status.idle":"2023-03-20T17:02:25.371136Z","shell.execute_reply.started":"2023-03-20T17:01:34.426605Z","shell.execute_reply":"2023-03-20T17:02:25.369912Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"import os\nimport pandas as pd\n\nimport torchaudio\nfrom tqdm.auto import tqdm\nfrom joblib import Parallel,delayed\nimport matplotlib.pyplot as plt\n\nfrom PIL import Image\nfrom tqdm.auto import tqdm\nfrom functools import partial\nfrom joblib import Parallel, delayed\nimport glob\nfrom pprint import pprint\n\n\n\nimport torch\nimport torchaudio\nimport noisereduce\nimport matplotlib.pyplot as plt\nimport numpy as np\nimport librosa\nfrom math import ceil\nfrom pprint import pprint\nfrom torch import Tensor\nfrom torch.utils.data import DataLoader\n","metadata":{"execution":{"iopub.status.busy":"2023-03-20T17:02:25.374937Z","iopub.execute_input":"2023-03-20T17:02:25.375249Z","iopub.status.idle":"2023-03-20T17:02:25.381798Z","shell.execute_reply.started":"2023-03-20T17:02:25.375217Z","shell.execute_reply":"2023-03-20T17:02:25.380796Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"# **Load the data**","metadata":{}},{"cell_type":"code","source":"Path = \"/kaggle/input/birdclef-2023\"\npath_csv = os.path.join(Path, \"train_metadata.csv\")\ntrain_meta = pd.read_csv(path_csv).sample(frac=1)\ndisplay(train_meta.head())","metadata":{"execution":{"iopub.status.busy":"2023-03-20T17:02:25.383260Z","iopub.execute_input":"2023-03-20T17:02:25.383904Z","iopub.status.idle":"2023-03-20T17:02:25.737081Z","shell.execute_reply.started":"2023-03-20T17:02:25.383864Z","shell.execute_reply":"2023-03-20T17:02:25.735863Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"# **Let check length of particular recording**","metadata":{}},{"cell_type":"code","source":"#explore audio data lengths\n\ndef get_length(fn):\n    fp = os.path.join(Path,\"train_audio\",fn)\n    waveform,sample_rate = torchaudio.load(fp)\n    return waveform.size()[-1]\n\nsizes = Parallel(n_jobs = os.cpu_count())(delayed(get_length)(fn) for fn in tqdm(train_meta[\"filename\"]))","metadata":{"execution":{"iopub.status.busy":"2023-03-20T17:02:25.739999Z","iopub.execute_input":"2023-03-20T17:02:25.740342Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"plt.hist(sizes, bins=150,color='red')\nplt.gca().set_xscale('log')\nplt.gca().set_yscale('log')\nplt.grid()","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"# **Convert audio to set of spectrogram**","metadata":{}},{"cell_type":"code","source":"SPECTROGRAM_PARAMS = dict(\n    sample_rate=32_000,\n    hop_length=640,\n    n_fft=800,\n    n_mels=128,\n    fmin=20,\n    fmax=16_000,\n    win_length=512\n)\nPCEN_PARAS = dict(\n    time_constant=0.06,\n    eps=1e-6,\n    gain=0.8,\n    power=0.25,\n    bias=10,\n)\n\n\n@torch.no_grad()\ndef create_spectrogram(\n    fname: str,\n    reduce_noise: bool = False,\n    frame_size: int = 5,\n    frame_step: int = 2,\n    spec_params: dict = SPECTROGRAM_PARAMS,\n) -> list:\n    waveform, sample_rate = librosa.core.load(fname, sr=spec_params[\"sample_rate\"], mono=True)\n    if reduce_noise:\n        waveform = noisereduce.reduce_noise(\n            y=waveform,\n            sr=sample_rate,\n            time_constant_s=float(frame_size),\n            time_mask_smooth_ms=250,\n            n_fft=spec_params[\"n_fft\"],\n            use_tqdm=False,\n            n_jobs=2,\n        )\n\n    step = int(frame_step * sample_rate)\n    size = int(frame_size * sample_rate)\n    count = ceil((len(waveform) - size) / float(step))\n    frames = []\n    for i in range(max(1, count)):\n        begin = i * step\n        frame = waveform[begin:begin + size]\n        if len(frame) < size:\n            if i == 0:\n                rep = round(float(size) / len(frame))\n                frame = frame.repeat(int(rep))\n            elif len(frame) < (size * 0.33):\n                continue\n            else:\n                frame = waveform[-size:]\n        frames.append(frame)\n\n    spectrograms = []\n    for frm in frames:\n        sg = librosa.feature.melspectrogram(\n            y=frm,\n            sr=sample_rate,\n            n_fft=spec_params[\"n_fft\"],\n            win_length=spec_params[\"win_length\"],\n            hop_length=spec_params[\"hop_length\"],\n            n_mels=spec_params[\"n_mels\"],\n            fmin=spec_params[\"fmin\"],\n            fmax=spec_params[\"fmax\"],\n            power=1,\n        )\n#         sg = librosa.pcen(sg, sr=sample_rate, hop_length=spec_params[\"hop_length\"], **PCEN_PARAS)\n        sg = librosa.amplitude_to_db(sg, ref=np.max)\n        spectrograms.append(np.nan_to_num(sg))\n    return spectrograms","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"path_audio = os.path.join(Path, \"train_audio\", \"abethr1/XC128013.ogg\")\n# path_audio = os.path.join(PATH_DATASET, \"train_audio\", \"elepai/XC27344.ogg\")\n# path_audio = os.path.join(PATH_DATASET, \"train_audio\", \"hawgoo/XC210217.ogg\")\nprint(path_audio)\nsgs = create_spectrogram(path_audio, reduce_noise=False)\n\n\nfig, axarr = plt.subplots(nrows=len(sgs), figsize=(8, 3 * len(sgs)))\nfor i, sg in enumerate(sgs):\n    print(np.min(sg), np.max(sg))\n    im = axarr[i].imshow(sg)  # librosa\n    plt.colorbar(im, ax=axarr[i])\n","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"# **Export only frames form the recording beginning and ending**","metadata":{}},{"cell_type":"code","source":"def convert_and_export(\n    fn: str, path_in: str, path_out: str,\n    reduce_noise: bool = False,\n    frame_size: int = 5, frame_step: int = 2,\n    img_extension=\".png\",\n) -> None:\n    path_audio = os.path.join(path_in, fn)\n    try:\n        sgs = create_spectrogram(\n            path_audio,\n            reduce_noise=reduce_noise,\n            frame_size=frame_size,\n            frame_step=frame_step,\n        )\n    except Exception as ex:\n        print(f\"Failed conversion for audio: {path_audio}\")\n        return\n    if not sgs:\n        print(f\"Too short audio for: {path_audio}\")\n        return\n    # see: https://www.kaggle.com/c/birdclef-2022/discussion/308861\n    # this is adjustment for window 5s and step 2s\n    nb = ceil((10 - frame_size) / frame_step) + 1\n    if len(sgs) > 2 * nb:\n        sgs = sgs[:nb] + sgs[-nb:]\n    path_npz = os.path.join(path_out, fn + '.npz')\n    os.makedirs(os.path.dirname(path_npz), exist_ok=True)\n    # np.savez_compressed(path_npz, np.array(sgs, dtype=np.float16))\n    for i, sg in enumerate(sgs):\n        path_img = os.path.join(path_out, fn + f\".{i:03}\" + img_extension)\n        try:\n            # plt.imsave(path_img, sg, vmin=-70, vmax=20)\n            sg = (sg + 80) / 80.0\n            sg = np.clip(sg, a_min=0, a_max=1) * 255\n            img = Image.fromarray(sg.astype(np.uint8))\n            img.resize((256,256)).save(path_img)\n        except Exception as ex:\n            print(f\"Failed exporting for image: {path_img}\")\n            continue\n\n","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"# **Conversion of full dataset**","metadata":{}},{"cell_type":"code","source":"_convert_and_export = partial(\n    convert_and_export,\n    path_in=os.path.join(Path, \"train_audio\"),\n    path_out=\"train_images\",\n)\n\n_= Parallel(n_jobs=3)(delayed(_convert_and_export)(fn) for fn in tqdm(train_meta[\"filename\"]))\n# _= list(map(_convert_and_export, tqdm(train_meta[\"filename\"])))\n\n","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"print(train_meta[\"filename\"][1])\nimgs = glob.glob(os.path.join(\"train_images\", train_meta[\"filename\"][1] + \".*.png\"))\npprint(sorted(imgs))\n\npath_img = imgs[0]\nprint(path_img)\nimg = plt.imread(path_img)\nprint(img.shape)\nplt.imshow(img)\n\n","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"# **Color normalization**","metadata":{}},{"cell_type":"code","source":"def _color_means(img_path):\n    img = plt.imread(img_path)\n    if np.max(img) > 1.5:\n        img = img / 255.0\n    clr_mean = np.mean(img) if img.ndim == 2 else {i: np.mean(img[..., i]) for i in range(3)}\n    clr_std = np.std(img) if img.ndim == 2 else {i: np.std(img[..., i]) for i in range(3)}\n    return clr_mean, clr_std\n\nimages = glob.glob(os.path.join(\"train_images\", \"*\", \"*.png\"))\nclr_mean_std = Parallel(n_jobs=os.cpu_count())(delayed(_color_means)(fn) for fn in tqdm(images))","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"img_color_mean = pd.DataFrame([c[0] for c in clr_mean_std]).describe()\ndisplay(img_color_mean.T)","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"img_color_std = pd.DataFrame([c[1] for c in clr_mean_std]).describe()\ndisplay(img_color_std.T)","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"img_color_mean = list(img_color_mean.T[\"mean\"])\nimg_color_std = list(img_color_std.T[\"mean\"])\nprint(img_color_mean, img_color_std)","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"# **Thanks for visiting guys**\n\n## ***Full credit: https://www.kaggle.com/code/jirkaborovec/birdclef-convert-spectrograms-noise-reduce***","metadata":{}},{"cell_type":"code","source":"","metadata":{},"execution_count":null,"outputs":[]}]}