def testDataSet(): fes = features.extractorsById(['ql1', 'ql2', 'ql3']) ds = features.DataSet(classLabel='Composer') ds.addFeatureExtractors(fes) b1 = corpus.parse('bwv1080', 7).measures(0,50) ds.addData(b1, classValue='Bach', id='artOfFugue') ds.addData('bwv66.6.xml', classValue='Bach') # ds.addData('c:/handel/hwv56/movement3-05.md', ds.addData('hwv56/movement3-05.md', classValue='Handel') ds.addData('http://www.midiworld.com/midis/other/handel/gfh-jm01.mid') ds.process() print (ds.getAttributeLabels()) ds.write('d:/desktop/baroqueQLs.csv') fList = ds.getFeaturesAsList() print (fList[0]) print (features.OutputTabOrange(ds).getString()) for i in range(len(fList)): # display scores as pngs generated by Lilypond # if the most common note is an eighth note (0.5) # (finds the two Handel scores) if fList[i][2] == 0.5: pass # ds.streams[i].show('lily.png') p = graph.PlotFeatures(ds.streams, fes[1:], roundDigits = 2) p.process()
def music21ModWSGIFeatureApplication(environ, start_response): ''' Music21 webapp to demonstrate processing of a zip file containing scores. Will be moved and integrated into __init__.py upon developing a standardized URL format as application that can perform variety of commands on user-uploaded files ''' status = '200 OK' pathInfo = environ[ 'PATH_INFO'] # Contents of path after mount point of wsgi app but before question mark if pathInfo == '/uploadForm': output = getUploadForm() response_headers = [('Content-type', 'text/html'), ('Content-Length', str(len(output)))] start_response(status, response_headers) return [output] #command = pathInfo formFields = cgi.FieldStorage(fp=environ['wsgi.input'], environ=environ) # Check if form data is present. If not found, display error try: unused_subUploadFormFile = formFields['subUploadForm'] except: html = """ <html > <body style='font-family:calibri' bgcolor='#EEE' onLoad="toggleExtractors('m21')"> <table border=0 width='100%'> <tr><td align='center'> <table border=0 width='500px' cellpadding='10px' style='background-color:#FFF'> <tr><td align='left'> <h1>Error:</h1> <p>Form information not found</p> <p><a href='/music21/featureapp/uploadForm'>Try Again</a></p> </td></tr></table> </td></tr></table> </body></html> """ response_headers = [('Content-type', 'text/html'), ('Content-Length', str(len(html)))] start_response(status, response_headers) return [html] # Get file from POST uploadedFile = formFields['fileupload'].file filename = formFields['fileupload'].filename uploadType = formFields['fileupload'].type # Check if filename is empty - display no file chosen error if filename == "": html = """ <html > <body style='font-family:calibri' bgcolor='#EEE' onLoad="toggleExtractors('m21')"> <table border=0 width='100%'> <tr><td align='center'> <table border=0 width='500px' cellpadding='10px' style='background-color:#FFF'> <tr><td align='left'> <h1>Music 21 Feature Extraction:</h1> <p><b>Error:</b> No file selected</p> <p><a href='/music21/featureapp/uploadForm'>Try Again</a></p> </td></tr></table> </td></tr></table> </body></html> """ response_headers = [('Content-type', 'text/html'), ('Content-Length', str(len(html)))] start_response(status, response_headers) return [html] # Check if uploadType is zip - display no file chosen error if uploadType != "application/zip": html = """ <html > <body style='font-family:calibri' bgcolor='#EEE' onLoad="toggleExtractors('m21')"> <table border=0 width='100%'> <tr><td align='center'> <table border=0 width='500px' cellpadding='10px' style='background-color:#FFF'> <tr><td align='left'> <h1>Music 21 Feature Extraction:</h1> <p><b>Error:</b> File not in .zip format</p> <p><a href='/music21/featureapp/uploadForm'>Try Again</a></p> </td></tr></table> </td></tr></table> </body></html> """ response_headers = [('Content-type', 'text/html'), ('Content-Length', str(len(html)))] start_response(status, response_headers) return [html] # Setup Feature Extractors and Data Set ds = features.DataSet(classLabel='Class') featureIDList = list() # Check if features have been selected. Else display error try: unused_featureFile = formFields['features'] except: html = """ <html ><body> <h1>Error:</h1> <p>No extractors selected</p> <p><a href='/music21/featureapp/uploadForm'>try again</a></p> </body></html> """ return html if common.isListLike(formFields['features']): print(formFields['features']) for featureId in formFields['features']: featureIDList.append(str(featureId.value)) else: featureIDList.append(formFields['features'].value) fes = features.extractorsById(featureIDList) ds.addFeatureExtractors(fes) # Create ZipFile Object zipf = zipfile.ZipFile(uploadedFile, 'r') # Loop Through Files for scoreFileInfo in zipf.infolist(): filePath = scoreFileInfo.filename # Skip Directories if (filePath.endswith('/')): continue scoreFile = zipf.open(filePath) # Use Music21's converter to parse file parsedFile = idAndParseFile(scoreFile, filePath) # If valid music21 format, add to data set if parsedFile is not None: # Split into directory structure and filname pathPartitioned = filePath.rpartition('/') directory = pathPartitioned[0] filename = pathPartitioned[2] if directory == "": directory = 'uncategorized' ds.addData(parsedFile, classValue=directory, id=filename) # Process data set ds.process() # Get output format from POST and set appropriate output: outputFormatID = formFields['outputformat'].value if outputFormatID == CSV_OUTPUT_ID: output = features.OutputCSV(ds).getString() elif outputFormatID == ORANGE_OUTPUT_ID: output = features.OutputTabOrange(ds).getString() elif outputFormatID == ARFF_OUTPUT_ID: output = features.OutputARFF(ds).getString() else: output = "invalid output format" response_headers = [('Content-type', 'text/plain'), ('Content-Length', str(len(output)))] start_response(status, response_headers) return [output]