{"cells":[{"metadata":{"_uuid":"8f2839f25d086af736a60e9eeb907d3b93b6e0e5","_cell_guid":"b1076dfc-b9ad-4769-8c92-a6c4dae69d19","trusted":true},"cell_type":"code","source":"import os\n\n# Data processing\nimport pandas as pd\nimport numpy as np\nimport librosa\nimport IPython.display as ipd\nimport plotly.graph_objects as go\n\n## Paths\nDIR = '../'\n\nINPUT   = DIR + 'input/'\nLIB     = DIR + 'lib/'\nWORKING = DIR + 'working/'\n\n# Internal\nBIRDSONG_RECOG = INPUT + 'birdsong-recognition' + '/'\n\nBIRDSONG_TRAIN_AUDIO = BIRDSONG_RECOG + 'train_audio/'\nEXAMPLE_TEST_AUDIO   = BIRDSONG_RECOG + 'example_test_audio/'\n\n## Data structures\n\n# Internal\nBIRDS_LS = os.listdir(BIRDSONG_TRAIN_AUDIO)\nTRAIN    = pd.read_csv(BIRDSONG_RECOG + 'train.csv')\nTRAIN['path'] = BIRDSONG_RECOG + TRAIN['ebird_code'] + '/' + TRAIN['filename']\n\nEXAMPLE_TEXT_AUDIO_METADATA = pd.read_csv(BIRDSONG_RECOG + 'example_test_audio_metadata.csv')\nEXAMPLE_TEXT_AUDIO_SUMMARY = pd.read_csv(BIRDSONG_RECOG + 'example_test_audio_summary.csv')\n\nBIRD_COLORS = {\n 'squirrel' : 'burlywood',\n 'brncre' : 'brown',\n 'stejay' : 'steelblue',\n 'mouqua' : 'firebrick',\n 'rebsap' : 'darkred', \n 'unk'    : 'black',\n 'hawo'   : 'darkgray',\n 'daejun' : 'darkgoldenrod',\n 'westan' : 'orange',\n 'mouchi' : 'lightgray',\n 'gockin' : 'forestgreen',\n 'rebnut' : 'darkorange',\n 'whhwoo' : 'red',\n 'yerwar' : 'khaki',\n}","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"def load_audio(path, sr=44100):\n    x , sr = librosa.load(path, sr=sr)\n    audio_data = (x, sr)\n    return audio_data\n\ndef display_audio(path):\n    return ipd.Audio(path)\n\ndef create_frame(audio_data):\n    df = pd.DataFrame()\n    df['signal']  = audio_data[0]\n    df['seconds'] = df.index/audio_data[1]\n    \n    return df","execution_count":null,"outputs":[]},{"metadata":{"_uuid":"d629ff2d2480ee46fbb7e2d37f6b5fab8052498a","_cell_guid":"79c7e3d0-c299-4dcb-8224-4455121ee9b0","trusted":true},"cell_type":"code","source":"def build_overall_scatter(signal, fig):\n    line = {\n        'color' : 'darkgray',\n        'width' : 1\n    }\n    scatter = go.Scatter(\n        x = signal['seconds'],\n        y = signal['signal'],\n        name = 'audio',\n        line = line\n        \n    )\n    \n    fig = fig.add_trace(scatter)\n    return fig\n\n\ndef build_birdcall_scatter(signal, s, e, fig):\n    fil    = (signal['seconds'] >= s) & (signal['seconds'] <= e)\n    signal = signal[fil]\n    \n    line = {\n        'color' : 'rgb(84,84,84)',\n        'width' : 1\n    }\n    \n    scatter = go.Scatter(\n        x = signal['seconds'],\n        y = signal['signal'],\n        line = line\n        \n    )\n    \n    fig = fig.add_trace(scatter)\n    return fig\n\n\ndef build_birdcall_label(signal, birdcall, index, fig):\n    mul = 1 if (index % 2 == 0) else -1\n    s = birdcall['time_start']\n    e = birdcall['time_end']\n    color = BIRD_COLORS[birdcall['ebird_code']]\n    scatter = go.Scatter(\n        x = [s, e],\n        y = [mul * 0.35, mul * 0.35],\n    mode=\"lines\",\n    line=dict(color=color, width=2),\n    )\n    \n    fig = fig.add_annotation(\n        x=((e-s) / 2) + s,\n        y=mul * 0.35 + mul * 0.075,\n        xref=\"x\",\n        yref=\"y\",\n        text=birdcall['ebird_code'],\n        showarrow=False,\n        font=dict(\n            family=\"Avenir\",\n            size=10,\n            color=\"rgb(84,84,84)\"\n            ),\n        align=\"center\",\n        arrowcolor=\"#636363\",\n        ax=30,\n        ay=-30,\n        bordercolor=BIRD_COLORS[birdcall['ebird_code']],\n        borderwidth=2,\n        borderpad=2,\n        bgcolor=\"lightgray\",\n        opacity=1\n        )\n    \n    fig = fig.add_trace(scatter)\n    return fig\n\n\ndef update_x_axes(fig, s, e):\n    fig = fig.update_xaxes(showgrid=False, range=[s, e + 2])\n    return fig\n    \n    \ndef update_y_axes(fig, signal):\n    upper = signal['signal'].max() + .25\n    lower = signal['signal'].min() - .25\n    fig = fig.update_yaxes(\n        showgrid=True, \n        showticklabels=False,\n        showline=True, \n        linewidth=2, \n        linecolor='rgb(80,80,80)', \n        gridwidth=2,  \n        range=[lower, upper], \n        dtick=.2, \n        gridcolor='lightgray', \n        zeroline=True, \n        zerolinecolor='darkgray')\n    return fig","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"def plot_interval(device, df, metadata, s, e):\n    '''Just to make the graphing easier, only allow graphing 20 seconds at a time.\n    '''\n    if (e-s) > 20:\n        raise Exception\n    df_fil       = df[(df['seconds'] >= s) & (df['seconds'] <= e)]\n    metadata_fil = metadata[(metadata['device'] == device) & \n                            (metadata['time_start'] <= e) & \n                            (metadata['time_end'] >= s)].reset_index(drop=True)\n    \n    # Basic titles and characteristics\n    title       = f'{device} Interval: {s} - {e}s'\n    xaxis_title = 'Amplitude'\n    yaxis_title = 'Seconds'\n    font        = {\n        'family' : 'Avenir',\n        'size'   : 12,\n        'color'  : \"#7f7f7f\"\n    }\n    bgcolor = '#fff'\n    \n    # Create initial figure\n    fig = go.Figure(\n        layout=dict(\n        title = title,\n        xaxis_title = xaxis_title,\n        yaxis_title = yaxis_title,\n        font = font,\n        plot_bgcolor = bgcolor,\n        showlegend=False\n        )\n    )\n    \n    fig = build_overall_scatter(df_fil, fig)\n    fig = update_x_axes(fig, s, e)\n    fig = update_y_axes(fig, df_fil)\n    \n    for index, row in metadata_fil.iterrows():\n        fig = build_birdcall_scatter(df_fil, row['time_start'], row['time_end'], fig)\n        fig = build_birdcall_label(df_fil, row, index, fig)\n    \n    return fig","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"orange = load_audio(EXAMPLE_TEST_AUDIO + 'ORANGE-7-CAP_20190606_093000.pt623.mp3', sr=22050)\norange = create_frame(orange)\nplot_interval('ORANGE-7-CAP', orange, EXAMPLE_TEXT_AUDIO_METADATA, 15, 35)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"orange = load_audio(EXAMPLE_TEST_AUDIO + 'ORANGE-7-CAP_20190606_093000.pt623.mp3', sr=22050)\norange = create_frame(orange)\nplot_interval('ORANGE-7-CAP', orange, EXAMPLE_TEXT_AUDIO_METADATA, 70, 90)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"blkfr = load_audio(EXAMPLE_TEST_AUDIO + 'BLKFR-10-CPL_20190611_093000.pt540.mp3', sr=22050)\nblkfr = create_frame(blkfr)\nplot_interval('BLKFR-10-CPL', blkfr, EXAMPLE_TEXT_AUDIO_METADATA, 30, 50)","execution_count":null,"outputs":[]}],"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":4,"nbformat_minor":4}