{"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":"## This notebook can be used to generate training image dataset for the audio files. You can use your favorite image classifier model to classify the audio files.\n## You may find this notebook helpful, if you are using Mac M1/M2 to train the model. ","metadata":{}},{"cell_type":"code","source":"# This Python 3 environment comes with many helpful analytics libraries installed\n# It is defined by the kaggle/python Docker image: https://github.com/kaggle/docker-python\n# For example, here's several helpful packages to load\n\nimport numpy as np # linear algebra\nimport pandas as pd # data processing, CSV file I/O (e.g. pd.read_csv)\n\n# Input data files are available in the read-only \"../input/\" directory\n# For example, running this (by clicking run or pressing Shift+Enter) will list all files under the input directory\n\n","metadata":{"execution":{"iopub.status.busy":"2023-04-27T01:43:49.670339Z","iopub.execute_input":"2023-04-27T01:43:49.670800Z","iopub.status.idle":"2023-04-27T01:43:49.683602Z","shell.execute_reply.started":"2023-04-27T01:43:49.670763Z","shell.execute_reply":"2023-04-27T01:43:49.682220Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"import os\nimport pathlib\nimport librosa\nimport matplotlib.pyplot as plt\nimport numpy as np\nimport tensorflow as tf\nimport glob\nfrom PIL import Image\nimport tqdm","metadata":{"execution":{"iopub.status.busy":"2023-04-27T01:43:49.685246Z","iopub.execute_input":"2023-04-27T01:43:49.685750Z","iopub.status.idle":"2023-04-27T01:43:53.212532Z","shell.execute_reply.started":"2023-04-27T01:43:49.685700Z","shell.execute_reply":"2023-04-27T01:43:53.211058Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"SAMPLE_RATE = 32000\nSIGNAL_LENGTH = 5 # seconds \nN_MELS = 300\nFRAME_STEP=128\nROOT_DIR = '/kaggle/input/birdclef-2023'\nINPUT_DIR= f'{ROOT_DIR}/train_audio'\nOUTPUT_DIR = f'/kaggle/working/audio_images_gray' \nHOP_LENGTH=5*32000\nSPEC_SHAPE = (313, 300)","metadata":{"execution":{"iopub.status.busy":"2023-04-27T01:43:53.216504Z","iopub.execute_input":"2023-04-27T01:43:53.218460Z","iopub.status.idle":"2023-04-27T01:43:53.226001Z","shell.execute_reply.started":"2023-04-27T01:43:53.218369Z","shell.execute_reply":"2023-04-27T01:43:53.224658Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"def ensure_sample_rate(waveform, original_sample_rate,\n                       desired_sample_rate=SAMPLE_RATE):\n    \"\"\"Resample waveform if required.\"\"\"\n    if original_sample_rate != desired_sample_rate:\n        waveform = librosa.resample(waveform, \n                                    orig_sr=original_sample_rate, \n                                    target_sr=desired_sample_rate)\n    return waveform, desired_sample_rate\ndef get_melspec_spectrogram(waveform):\n\n    mel_spec = librosa.feature.melspectrogram(y=np.array(waveform), \n                                            sr = SAMPLE_RATE,\n                                            n_fft=2048,\n                                            fmin=0,\n                                            fmax=None,\n                                            n_mels = N_MELS)\n    mel_spec = mel_spec[..., tf.newaxis]\n    #print(mel_spec.shape)\n    return mel_spec\n\ndef get_waveform(filepath):\n    waveform, sample_rate = librosa.load(filepath)\n    waveform, sample_rate = ensure_sample_rate(waveform, sample_rate)\n    waveform_clips = tf.signal.frame(waveform, \n                                    SIGNAL_LENGTH*SAMPLE_RATE, \n                                    HOP_LENGTH, pad_end=True)\n    #print(waveform_clips.shape)\n    return waveform_clips","metadata":{"execution":{"iopub.status.busy":"2023-04-27T01:43:53.229754Z","iopub.execute_input":"2023-04-27T01:43:53.230173Z","iopub.status.idle":"2023-04-27T01:43:53.242150Z","shell.execute_reply.started":"2023-04-27T01:43:53.230126Z","shell.execute_reply":"2023-04-27T01:43:53.240368Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"def scale_minmax(X, min=0.0, max=1.0):\n    X_std = (X - X.min()) / (X.max() - X.min())\n    X_scaled = X_std * (max - min) + min\n    return X_scaled\n\ndef save_mel_spectrogram(spectrogram, fname):\n    spectrogram = np.abs(np.squeeze(librosa.power_to_db(spectrogram), axis=-1))\n    spectrogram = np.log(spectrogram + 1e-9) # add small number to avoid log(0)\n\n    # min-max scale to fit inside 8-bit range\n    img = scale_minmax(spectrogram, 0, 255).astype(np.uint8)\n    img = np.flip(img, axis=0) # put low frequencies at the bottom in image\n    img = 255-img # invert. make black==more energy\n    image = Image.fromarray(img)\n    image.save(fname)\n","metadata":{"execution":{"iopub.status.busy":"2023-04-27T01:43:53.243751Z","iopub.execute_input":"2023-04-27T01:43:53.244268Z","iopub.status.idle":"2023-04-27T01:43:53.259984Z","shell.execute_reply.started":"2023-04-27T01:43:53.244208Z","shell.execute_reply":"2023-04-27T01:43:53.258265Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"def convert_ogg_to_png(inp_file=f'{INPUT_DIR}/abethr1/XC363504.ogg'):\n    waveforms = get_waveform(inp_file)\n    segs = inp_file.split('/')\n    birdcat = segs[5]\n    fname = segs[6].split('.')[0]\n    if not os.path.isdir(f'{OUTPUT_DIR}/'):\n        os.mkdir(f'{OUTPUT_DIR}/')\n    if not os.path.isdir(f'{OUTPUT_DIR}/{birdcat}/'):\n        os.mkdir(f'{OUTPUT_DIR}/{birdcat}/')\n\n    for i in range(len(waveforms)):\n        spectrogram = get_melspec_spectrogram(waveforms[i])\n        output_fname = f'{OUTPUT_DIR}/{birdcat}/{fname}_{i}.png'\n        save_mel_spectrogram(spectrogram, fname=output_fname)","metadata":{"execution":{"iopub.status.busy":"2023-04-27T01:43:53.265339Z","iopub.execute_input":"2023-04-27T01:43:53.265885Z","iopub.status.idle":"2023-04-27T01:43:53.277284Z","shell.execute_reply.started":"2023-04-27T01:43:53.265838Z","shell.execute_reply":"2023-04-27T01:43:53.275818Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"def prep_train_images():\n    files = glob.glob(f'{INPUT_DIR}/*/*.ogg')\n    for inp_file in tqdm.tqdm(files):\n        convert_ogg_to_png(inp_file=inp_file)","metadata":{"execution":{"iopub.status.busy":"2023-04-27T01:43:53.278521Z","iopub.execute_input":"2023-04-27T01:43:53.279439Z","iopub.status.idle":"2023-04-27T01:43:53.295486Z","shell.execute_reply.started":"2023-04-27T01:43:53.279360Z","shell.execute_reply":"2023-04-27T01:43:53.293733Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"convert_ogg_to_png(inp_file=f'{INPUT_DIR}/abethr1/XC363504.ogg')\n# uncomment following line to create your training dataset \n# prep_train_images()","metadata":{"execution":{"iopub.status.busy":"2023-04-27T01:43:53.297665Z","iopub.execute_input":"2023-04-27T01:43:53.298338Z","iopub.status.idle":"2023-04-27T01:43:57.476677Z","shell.execute_reply.started":"2023-04-27T01:43:53.298292Z","shell.execute_reply":"2023-04-27T01:43:57.472959Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"## Your audio clips has been converted into grayscale images (png) format of (313,300) size.","metadata":{}},{"cell_type":"markdown","source":"### Please vote if you found this notebook helpful ### ","metadata":{}},{"cell_type":"markdown","source":"### Package List from my conda env.###","metadata":{}},{"cell_type":"markdown","source":"```\nPackage details of my env on Mac M1 machine\n> #\n# Name                    Version                   Build  Channel\nabsl-py                   1.4.0                    pypi_0    pypi\nappdirs                   1.4.4                    pypi_0    pypi\nastunparse                1.6.3                    pypi_0    pypi\naudioread                 3.0.0                    pypi_0    pypi\nbzip2                     1.0.8                h3422bc3_4    conda-forge\nc-ares                    1.18.1               h3422bc3_0    conda-forge\nca-certificates           2022.12.7            h4653dfc_0    conda-forge\ncached-property           1.5.2                hd8ed1ab_1    conda-forge\ncached_property           1.5.2              pyha770c72_1    conda-forge\ncachetools                5.3.0                    pypi_0    pypi\ncertifi                   2022.12.7                pypi_0    pypi\ncffi                      1.15.1                   pypi_0    pypi\ncharset-normalizer        3.1.0                    pypi_0    pypi\ncontourpy                 1.0.7                    pypi_0    pypi\ncycler                    0.11.0                   pypi_0    pypi\ndecorator                 5.1.1                    pypi_0    pypi\nffmpeg                    1.4                      pypi_0    pypi\nffprobe                   0.5                      pypi_0    pypi\nflatbuffers               23.3.3                   pypi_0    pypi\nfonttools                 4.39.3                   pypi_0    pypi\ngast                      0.4.0                    pypi_0    pypi\ngoogle-auth               2.17.0                   pypi_0    pypi\ngoogle-auth-oauthlib      0.4.6                    pypi_0    pypi\ngoogle-pasta              0.2.0                    pypi_0    pypi\ngrpcio                    1.46.3          py310ha26ec5d_0    conda-forge\nh5py                      3.6.0           nompi_py310hb8bbf05_100    conda-forge\nhdf5                      1.12.1          nompi_hd9dbc9e_104    conda-forge\nidna                      3.4                      pypi_0    pypi\njoblib                    1.2.0                    pypi_0    pypi\nkeras                     2.11.0                   pypi_0    pypi\nkiwisolver                1.4.4                    pypi_0    pypi\nkrb5                      1.20.1               h69eda48_0    conda-forge\nlazy-loader               0.2                      pypi_0    pypi\nlibblas                   3.9.0           16_osxarm64_openblas    conda-forge\nlibcblas                  3.9.0           16_osxarm64_openblas    conda-forge\nlibclang                  16.0.0                   pypi_0    pypi\nlibcurl                   7.88.1               h9049daf_1    conda-forge\nlibcxx                    16.0.0               h75e25f2_0    conda-forge\nlibedit                   3.1.20191231         hc8eb9b7_2    conda-forge\nlibev                     4.33                 h642e427_1    conda-forge\nlibffi                    3.4.2                h3422bc3_5    conda-forge\nlibgfortran               5.0.0           12_2_0_hd922786_31    conda-forge\nlibgfortran5              12.2.0              h0eea778_31    conda-forge\nliblapack                 3.9.0           16_osxarm64_openblas    conda-forge\nlibnghttp2                1.52.0               hae82a92_0    conda-forge\nlibopenblas               0.3.21          openmp_hc731615_3    conda-forge\nlibprotobuf               3.19.4               hccf11d3_0    conda-forge\nlibrosa                   0.10.0.post2             pypi_0    pypi\nlibsqlite                 3.40.0               h76d750c_0    conda-forge\nlibssh2                   1.10.0               h7a5bd25_3    conda-forge\nlibzlib                   1.2.13               h03a7124_4    conda-forge\nllvm-openmp               16.0.0               h7cfbb63_0    conda-forge\nllvmlite                  0.39.1                   pypi_0    pypi\nmarkdown                  3.4.3                    pypi_0    pypi\nmarkupsafe                2.1.2                    pypi_0    pypi\nmatplotlib                3.7.1                    pypi_0    pypi\nmsgpack                   1.0.5                    pypi_0    pypi\nncurses                   6.3                  h07bb92c_1    conda-forge\nnoisereduce               2.0.1                    pypi_0    pypi\nnumba                     0.56.4                   pypi_0    pypi\nnumpy                     1.23.2          py310h127c7cf_0    conda-forge\noauthlib                  3.2.2                    pypi_0    pypi\nopenssl                   3.1.0                h03a7124_0    conda-forge\nopt-einsum                3.3.0                    pypi_0    pypi\npackaging                 23.0                     pypi_0    pypi\npanda                     0.3.1                    pypi_0    pypi\npandas                    1.5.3                    pypi_0    pypi\npillow                    9.4.0                    pypi_0    pypi\npip                       23.0.1             pyhd8ed1ab_0    conda-forge\npooch                     1.6.0                    pypi_0    pypi\nprotobuf                  3.19.6                   pypi_0    pypi\npyasn1                    0.4.8                    pypi_0    pypi\npyasn1-modules            0.2.8                    pypi_0    pypi\npycparser                 2.21                     pypi_0    pypi\npyparsing                 3.0.9                    pypi_0    pypi\npython                    3.10.10         h3ba56d0_0_cpython    conda-forge\npython-dateutil           2.8.2                    pypi_0    pypi\npython_abi                3.10                    3_cp310    conda-forge\npytz                      2023.3                   pypi_0    pypi\nreadline                  8.2                  h92ec313_1    conda-forge\nrequests                  2.28.2                   pypi_0    pypi\nrequests-oauthlib         1.3.1                    pypi_0    pypi\nrsa                       4.9                      pypi_0    pypi\nscikit-learn              1.2.2                    pypi_0    pypi\nscipy                     1.10.1                   pypi_0    pypi\nsetuptools                67.6.1             pyhd8ed1ab_0    conda-forge\nsix                       1.16.0             pyh6c4a22f_0    conda-forge\nsoundfile                 0.12.1                   pypi_0    pypi\nsoxr                      0.3.4                    pypi_0    pypi\ntensorboard               2.11.2                   pypi_0    pypi\ntensorboard-data-server   0.6.1                    pypi_0    pypi\ntensorboard-plugin-wit    1.8.1                    pypi_0    pypi\ntensorflow-addons         0.19.0                   pypi_0    pypi\ntensorflow-deps           2.10.0                        0    apple\ntensorflow-estimator      2.11.0                   pypi_0    pypi\ntensorflow-hub            0.13.0                   pypi_0    pypi\ntensorflow-macos          2.11.0                   pypi_0    pypi\ntensorflow-metal          0.7.1                    pypi_0    pypi\ntermcolor                 2.2.0                    pypi_0    pypi\nthreadpoolctl             3.1.0                    pypi_0    pypi\ntk                        8.6.12               he1e0b03_0    conda-forge\ntqdm                      4.65.0                   pypi_0    pypi\ntypeguard                 3.0.2                    pypi_0    pypi\ntyping-extensions         4.5.0                    pypi_0    pypi\ntzdata                    2023c                h71feb2d_0    conda-forge\nurllib3                   1.26.15                  pypi_0    pypi\nwerkzeug                  2.2.3                    pypi_0    pypi\nwheel                     0.40.0             pyhd8ed1ab_0    conda-forge\nwrapt                     1.15.0                   pypi_0    pypi\nxz                        5.2.6                h57fd34a_0    conda-forge\nzlib                      1.2.13               h03a7124_4    conda-forge\nzstd                      1.5.2                hf913c23_6    conda-forge\n```","metadata":{}},{"cell_type":"markdown","source":"> ","metadata":{}},{"cell_type":"markdown","source":"","metadata":{}}]}