annotate Syncopation models/synpy/syncopation.py @ 50:e71028851131

updating latex and bug fixes to main py files
author christopherh <christopher.harte@eecs.qmul.ac.uk>
date Mon, 27 Apr 2015 09:51:15 +0100
parents 6e9154fc58df
children
rev   line source
christopher@45 1 '''
christopher@45 2 Author: Chunyang Song
christopher@45 3 Institution: Centre for Digital Music, Queen Mary University of London
christopher@45 4
christopher@45 5 '''
christopher@45 6 from rhythm_parser import *
christopher@45 7 from music_objects import *
christopher@45 8
christopher@45 9
christopher@45 10 def sync_perbar_permodel (model, bar, parameters=None):
christopher@45 11 return model.get_syncopation(bar, parameters)
christopher@45 12
christopher@45 13 def calculate_syncopation(model, source, parameters=None, outfile=None):
christopher@45 14 total = 0.0
christopher@45 15 barResults = []
christopher@45 16 numberOfNotes = 0
christopher@45 17
christopher@45 18 barlist = None
christopher@45 19
christopher@45 20 if isinstance(source, BarList):
christopher@45 21 barlist = source
christopher@45 22 sourceType = "bar list"
christopher@45 23 elif isinstance(source, Bar):
christopher@50 24 barlist = BarList()
christopher@50 25 barlist.append(source)
christopher@50 26 print barlist
christopher@45 27 sourceType = "single bar"
christopher@45 28 elif isinstance(source, basestring):
christopher@45 29 #treat source as a filename
christopher@45 30 sourceType = source
christopher@45 31 if source[-4:]==".mid":
christopher@45 32 import readmidi
christopher@45 33 midiFile = readmidi.read_midi_file(source)
christopher@45 34 barlist = readmidi.get_bars_from_midi(midiFile)
christopher@45 35
christopher@45 36 elif source[-4:]==".rhy":
christopher@45 37 #import rhythm_parser
christopher@45 38 barlist = read_rhythm(source)
christopher@45 39 else:
christopher@45 40 print "Error in syncopation_barlist_permodel(): Unrecognised file type."
christopher@45 41 else:
christopher@45 42 print "Error in syncopation_barlist_permodel(): unrecognised source type."
christopher@45 43
christopher@45 44 barsDiscarded=0
christopher@45 45 discardedlist = []
christopher@45 46 includedlist = []
christopher@45 47
christopher@50 48
christopher@45 49 if barlist!=None:
christopher@45 50 for bar in barlist:
christopher@50 51 print 'processing bar %d' % (barlist.index(bar)+1)
christopher@50 52
christopher@50 53 barSyncopation = sync_perbar_permodel(model, bar, parameters)
christopher@50 54
christopher@50 55
christopher@50 56 # if not bar.is_empty():
christopher@50 57 # barSyncopation = sync_perbar_permodel(model, bar, parameters)
christopher@50 58 # else:
christopher@50 59 # barSyncopation = None
christopher@50 60 # print 'Bar %d cannot be measured because it is empty, returning None.' % barlist.index(bar)
christopher@45 61
christopher@45 62 barResults.append(barSyncopation)
christopher@45 63 if barSyncopation != None:
christopher@45 64 total += barSyncopation
christopher@45 65 numberOfNotes += sum(bar.get_binary_sequence())
christopher@45 66 includedlist.append(barlist.index(bar))
christopher@45 67 else:
christopher@45 68 barsDiscarded += 1
christopher@45 69 discardedlist.append(barlist.index(bar))
christopher@50 70 print 'Model could not measure bar %d, returning None.' % (barlist.index(bar)+1)
christopher@45 71
christopher@45 72 import WNBD
christopher@45 73 if model is WNBD:
christopher@45 74 total = total / numberOfNotes
christopher@45 75
christopher@50 76 if len(barResults)>barsDiscarded:
christopher@50 77 average = total / (len(barResults)-barsDiscarded)
christopher@50 78 else:
christopher@50 79 average = total
christopher@45 80
christopher@45 81 output = {
christopher@45 82 "model_name":model.__name__ ,
christopher@45 83 "summed_syncopation":total,
christopher@45 84 "mean_syncopation_per_bar":average,
christopher@45 85 "source":sourceType,
christopher@45 86 "number_of_bars":len(barResults),
christopher@45 87 "number_of_bars_not_measured":barsDiscarded,
christopher@45 88 "bars_with_valid_output":includedlist,
christopher@50 89 "bars_without_valid_output":discardedlist,
christopher@45 90 "syncopation_by_bar":barResults
christopher@45 91 }
christopher@45 92
christopher@45 93 if outfile!=None:
christopher@45 94
christopher@45 95 if ".xml" in outfile:
christopher@45 96 results_to_xml(output,outfile)
christopher@45 97 elif ".json" in outfile:
christopher@45 98 results_to_json(output,outfile)
christopher@45 99 else:
christopher@45 100 print "Error in syncopation.py: Unrecognised output file type: ", outfile
christopher@45 101
christopher@45 102 return output
christopher@45 103
christopher@45 104
christopher@45 105
christopher@45 106 def results_to_xml(results, outputFilename):
christopher@45 107 from xml.etree.ElementTree import Element, ElementTree
christopher@45 108
christopher@45 109 elem = Element("syncopation_results")
christopher@45 110
christopher@45 111 for key, val in results.items():
christopher@45 112 child = Element(key)
christopher@45 113 child.text = str(val)
christopher@45 114 elem.append(child)
christopher@45 115
christopher@45 116 ElementTree(elem).write(outputFilename)
christopher@45 117
christopher@45 118 def results_to_json(results, outputFilename):
christopher@45 119 import json
christopher@45 120
christopher@45 121 fileHandle = open(outputFilename, 'w')
christopher@45 122 json.dump(results, fileHandle, sort_keys=True, indent=4, separators=(',', ': '))
christopher@45 123 fileHandle.flush()
christopher@45 124