{"cells":[{"metadata":{},"cell_type":"markdown","source":"Collects true-positive and false-positive audio data for a given species for side-by-side comparison of spectrograms, sound, and waveshape.  Limits false positive data to same length as true positives to increase the usefulness for comparison.\n\nNormalization is enabled to make the spectral patterns more clear."},{"metadata":{"trusted":true},"cell_type":"code","source":"speciesOfInterest = 22","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"import numpy as np # linear algebra\nimport pandas as pd # data processing, CSV file I/O (e.g. pd.read_csv)\n\nimport soundfile as sf\nimport scipy.signal as signal\nimport matplotlib.pyplot as plt \nimport matplotlib.patches as patches\nimport seaborn as sns\n\nfrom IPython.display import Audio\n\ndef getFPAudioWithSpeciesId(speciesId):\n    train_fp = pd.read_csv('../input/rfcx-species-audio-detection/train_fp.csv')\n    return getAudioWithSpeciesId(speciesId, train_fp)\n    \ndef getTPAudioWithSpeciesId(speciesId):\n    train_tp = pd.read_csv('../input/rfcx-species-audio-detection/train_tp.csv')\n    return getAudioWithSpeciesId(speciesId, train_tp)\n\ndef getAudioWithSpeciesId(speciesId, trainSet):\n    recordingIds = []\n    speciesMinTime = []\n    speciesMaxTime = []\n    speciesMinFreq = []\n    speciesMaxFreq = []\n    for i, rid in enumerate(trainSet['species_id']):\n        if rid == speciesId:\n            recordingIds.append(trainSet['recording_id'][i])\n            speciesMinTime.append(trainSet['t_min'][i])\n            speciesMaxTime.append(trainSet['t_max'][i])\n            speciesMinFreq.append(trainSet['f_min'][i])\n            speciesMaxFreq.append(trainSet['f_max'][i])\n    return recordingIds, speciesMinTime, speciesMaxTime, speciesMinFreq, speciesMaxFreq\n\ndef normalize(data):\n    maxSample = max(data)\n    maxVal = np.finfo(np.float32).max  ## float32-max selection is arbitrary\n    fraction = maxSample / maxVal\n    factor = 1.0 / fraction\n    data_out = []\n    for i, datum in enumerate(data):\n        data_out.append(data[i] * factor)\n    return np.array(data_out)\n\ndef hearAudioOfSpecies(speciesId, truePositive):\n    if truePositive:\n        audioIdList, minTimeList, maxTimeList, speciesMinFreqs, speciesMaxFreqs = getTPAudioWithSpeciesId(speciesId)\n    else:\n        audioIdList, minTimeList, maxTimeList, speciesMinFreqs, speciesMaxFreqs = getFPAudioWithSpeciesId(speciesId)\n    defaultSampleRate = 48000\n    allAudioData = []\n    startTimes = []\n    endTimes = []\n    startTimes.append(0)\n    currentTime = 0\n    \n    for i, audioId in enumerate(audioIdList):\n        path = '../input/rfcx-species-audio-detection/train/' + str(audioId) + '.flac' \n        data, samplerate = sf.read(path)\n        minTimeSamples = int(minTimeList[i] * samplerate)\n        maxTimeSamples = int(maxTimeList[i] * samplerate)\n        relevantData = data[minTimeSamples:maxTimeSamples]\n        relevantData = normalize(relevantData)\n        allAudioData.extend(relevantData)\n        currentTime += len(relevantData)\n        startTimes.append(currentTime)\n        endTimes.append(currentTime)\n        \n    return allAudioData, defaultSampleRate, len(audioIdList), speciesMinFreqs, speciesMaxFreqs, startTimes, endTimes\n\n\ndataTp, samplerateTp, numSourcesTp, minFreqTp, maxFreqTp, startTimesTp, endTimesTp = hearAudioOfSpecies(speciesOfInterest, True)\ndataFp, samplerateFp, numSourcesFp, minFreqFp, maxFreqFp, startTimesFp, endTimesFp = hearAudioOfSpecies(speciesOfInterest, False)\n\ndataTp = np.array(dataTp)\ndataFp = np.array(dataFp[0:len(dataTp)]) \n\nprint('True Positive data taken from ' + str(numSourcesTp) + ' recordings')\nprint('False Positive data taken from ' + str(numSourcesFp) + ' recordings')","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"Audio(dataTp, rate=samplerateTp)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"Audio(dataFp, rate=samplerateFp)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"def makePatch(ax, data, minFreq, maxFreq, minTime, maxTime, clr):\n    rect = patches.Rectangle((minTime, minFreq), maxTime-minTime, maxFreq-minFreq, linewidth=1, facecolor=clr, alpha=.2)\n    ax.add_patch(rect)","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"**True Positive Spectrogram**"},{"metadata":{"trusted":true},"cell_type":"code","source":"fig, ax = plt.subplots(1,figsize=(20,5))\nPxx, freqs, bins, im = plt.specgram(dataTp, Fs=samplerateTp)\n\nfor i in range(numSourcesTp):\n    makePatch(ax, Pxx, minFreqTp[i], maxFreqTp[i], startTimesTp[i], endTimesTp[i], 'r')\n\nplt.savefig('spectrum-tp.png', dpi=600, format='png')","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"**False Positive Spectrogram**"},{"metadata":{"trusted":true},"cell_type":"code","source":"fig, ax = plt.subplots(1,figsize=(20,5))\nPxx, freqs, bins, im = plt.specgram(dataFp, Fs=samplerateFp)\n\nfor i in range(numSourcesFp):\n    makePatch(ax, Pxx, minFreqFp[i], maxFreqFp[i], startTimesFp[i], endTimesFp[i], 'r')\n\nplt.savefig('spectrum-fp.png', dpi=600, format='png')","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}