Last active
May 9, 2019 13:40
-
-
Save angelormrl/32a4060de753bae24e1e84922f6392de to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
{ | |
"cells": [ | |
{ | |
"cell_type": "markdown", | |
"metadata": {}, | |
"source": [ | |
"# Importing and Feature Extraction\n", | |
"\n", | |
"This Notebook handles the importing of audio files, the extraction of audio features and the writing of the dataset to a csv file." | |
] | |
}, | |
{ | |
"cell_type": "code", | |
"execution_count": 1, | |
"metadata": { | |
"collapsed": true | |
}, | |
"outputs": [], | |
"source": [ | |
"# mathmatical functionaliy\n", | |
"import numpy as np\n", | |
"# operating system interaction, specifically querying for list of file names in a directory\n", | |
"import os\n", | |
"# audio feature extraction\n", | |
"import librosa\n", | |
"# write to a csv file\n", | |
"import csv" | |
] | |
}, | |
{ | |
"cell_type": "code", | |
"execution_count": 2, | |
"metadata": {}, | |
"outputs": [ | |
{ | |
"name": "stdout", | |
"output_type": "stream", | |
"text": [ | |
"write to csv complete!\n" | |
] | |
} | |
], | |
"source": [ | |
"## ======== FUNCTION DEFINITIONS ======== ##\n", | |
"\n", | |
"\n", | |
"# returns attack length of synthesizer patch in seconds\n", | |
"# y: sample data of the sound file as a list / sr: the sample rate\n", | |
"def getAttack(y, sr):\n", | |
" maxVal = 0\n", | |
" maxSamp = 0\n", | |
" # searches for index of the sample with the largest value\n", | |
" for i in range(len(y)):\n", | |
" if(y[i] > maxVal):\n", | |
" maxVal = y[i]\n", | |
" maxSamp = i\n", | |
" # dividing this index by the sample rate returns the time between the start and this sample in seconds\n", | |
" attack = maxSamp / sr\n", | |
" return attack\n", | |
"\n", | |
"# returns integer corresponding to the class of sample. used to create target data for each example\n", | |
"# name: name of the soundfile as string / classes: list of the titles of classes as present in soundfile names\n", | |
"def getClass(name, classes):\n", | |
" # loops through each class name and tests whether it is present in file name\n", | |
" for i in range(len(classes)):\n", | |
" if classes[i] in name:\n", | |
" # if it is the the class index is set accordingly\n", | |
" c = classes[i]\n", | |
" break\n", | |
" return c\n", | |
"\n", | |
"# returns list of mean values for each MFCC\n", | |
"# y: sample data of the sound file as a list / sr: the sample rate / n_mfcc: the number of MFCCs to calculate\n", | |
"def getMeanMFCCs(y, sr, n_mfcc):\n", | |
" hop_length = 512\n", | |
" mfccs = librosa.feature.mfcc(y = y, sr = sr, hop_length = hop_length, n_mfcc = n_mfcc)\n", | |
" means = []\n", | |
" # loop through each mfcc and calculate its mean across the time period\n", | |
" for i in range(0, n_mfcc):\n", | |
" total = 0\n", | |
" for j in range(0, len(mfccs[0])):\n", | |
" total += mfccs[i][j]\n", | |
" mean = (total / np.shape(mfccs[0]))\n", | |
" means.append(mean[0])\n", | |
" return(means)\n", | |
"\n", | |
"# write a list of sublists to a csv file\n", | |
"# data: the list of data\n", | |
"def writeCSV(data, path, title):\n", | |
" myFiles = open(path + '/' + title, 'wb')\n", | |
" with myFiles:\n", | |
" writer = csv.writer(myFiles)\n", | |
" writer.writerows(data)\n", | |
" print('write to .CSV complete!')\n", | |
"\n", | |
"\n", | |
"## ======== END FUNCTION DEFINITIONS ======== ##\n", | |
"\n", | |
"\n", | |
"# path to directory to load files from. must only contain audio files or will throw error\n", | |
"loadPath = '/Users/angelorussell/Desktop/pads'\n", | |
"# returns a list of all names of files in a directory\n", | |
"files = os.listdir(loadPath)\n", | |
"\n", | |
"# titles of each class as substrings to be found in file name strings\n", | |
"classes = ['bass', 'pad', 'lead']\n", | |
"\n", | |
"# number of mel frequency cepstrum coeffcients to test for\n", | |
"n_mfccs = 20\n", | |
"\n", | |
"# number of decimal places to round floating point values to\n", | |
"round_n = 4\n", | |
"\n", | |
"# define list for data to be stored in csv\n", | |
"data = [[]]\n", | |
"# first sublist set to title of each collumn\n", | |
"data[0].append('attack')\n", | |
"for i in range(n_mfccs):\n", | |
" data[0].append('mfcc_'+str(i+1))\n", | |
"data[0].append('class')\n", | |
"\n", | |
"# extract features and classes from each audio file, fill lists dat and tar respectively\n", | |
"for i in range(len(files)):\n", | |
" # concatenate strings for the directory path and each file name to load audio files\n", | |
" concat = loadPath + '/' + files[i]\n", | |
" y, sr = librosa.load(concat)\n", | |
" # append new list and set first element to the attack rate of the sample\n", | |
" data.append([])\n", | |
" data[i+1].append(round(getAttack(y, sr), round_n))\n", | |
" # set the following n_mfcc elements to the means of each mfcc\n", | |
" #data[i+1].extend(round(getMeanMFCCs(y, sr, n_mfccs), round_n))\n", | |
" data[i+1].extend(round(elem, round_n) for elem in getMeanMFCCs(y, sr, n_mfccs))\n", | |
" # append \n", | |
" data[i+1].append(getClass(files[i], classes))\n", | |
"\n", | |
"# path to directory for csv to write to. must be different to the read path\n", | |
"writePath = '/Users/angelorussell/Desktop'\n", | |
"writeCSV(data, writePath, 'synthPatch.csv')" | |
] | |
}, | |
{ | |
"cell_type": "code", | |
"execution_count": null, | |
"metadata": { | |
"collapsed": true | |
}, | |
"outputs": [], | |
"source": [] | |
} | |
], | |
"metadata": { | |
"kernelspec": { | |
"display_name": "Python 2", | |
"language": "python", | |
"name": "python2" | |
}, | |
"language_info": { | |
"codemirror_mode": { | |
"name": "ipython", | |
"version": 2 | |
}, | |
"file_extension": ".py", | |
"mimetype": "text/x-python", | |
"name": "python", | |
"nbconvert_exporter": "python", | |
"pygments_lexer": "ipython2", | |
"version": "2.7.14" | |
} | |
}, | |
"nbformat": 4, | |
"nbformat_minor": 2 | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment