annotate synpy/syncopation.py @ 76:90b68f259541 tip

updated parameter_setter to be able to find the TimeSignature.pkl file without putting it in the pwd
author christopherh <christopher.harte@eecs.qmul.ac.uk>
date Wed, 13 May 2015 09:27:36 +0100
parents 0c744fb4c202
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@75 13 def calculate_syncopation(model, source, parameters=None, outfile=None, barRange=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@75 50
christopher@75 51 if barRange==None:
christopher@75 52 barstart=0
christopher@75 53 barend=len(barlist)
christopher@75 54 else:
christopher@75 55 barstart = barRange[0]
christopher@75 56 barend = barRange[1]
christopher@75 57
christopher@75 58
christopher@75 59 for bar in barlist[barstart:barend]:
christopher@50 60 print 'processing bar %d' % (barlist.index(bar)+1)
christopher@50 61
christopher@50 62 barSyncopation = sync_perbar_permodel(model, bar, parameters)
christopher@50 63
christopher@50 64
christopher@50 65 # if not bar.is_empty():
christopher@50 66 # barSyncopation = sync_perbar_permodel(model, bar, parameters)
christopher@50 67 # else:
christopher@50 68 # barSyncopation = None
christopher@50 69 # print 'Bar %d cannot be measured because it is empty, returning None.' % barlist.index(bar)
christopher@45 70
christopher@45 71 barResults.append(barSyncopation)
christopher@45 72 if barSyncopation != None:
christopher@45 73 total += barSyncopation
christopher@45 74 numberOfNotes += sum(bar.get_binary_sequence())
christopher@45 75 includedlist.append(barlist.index(bar))
christopher@45 76 else:
christopher@45 77 barsDiscarded += 1
christopher@45 78 discardedlist.append(barlist.index(bar))
christopher@50 79 print 'Model could not measure bar %d, returning None.' % (barlist.index(bar)+1)
christopher@45 80
christopher@45 81 import WNBD
christopher@45 82 if model is WNBD:
christopher@45 83 total = total / numberOfNotes
christopher@75 84
christopher@50 85 if len(barResults)>barsDiscarded:
christopher@50 86 average = total / (len(barResults)-barsDiscarded)
christopher@50 87 else:
christopher@50 88 average = total
christopher@45 89
christopher@45 90 output = {
christopher@45 91 "model_name":model.__name__ ,
christopher@45 92 "summed_syncopation":total,
christopher@45 93 "mean_syncopation_per_bar":average,
christopher@45 94 "source":sourceType,
christopher@45 95 "number_of_bars":len(barResults),
christopher@45 96 "number_of_bars_not_measured":barsDiscarded,
christopher@45 97 "bars_with_valid_output":includedlist,
christopher@50 98 "bars_without_valid_output":discardedlist,
christopher@45 99 "syncopation_by_bar":barResults
christopher@45 100 }
christopher@45 101
christopher@45 102 if outfile!=None:
christopher@45 103
christopher@45 104 if ".xml" in outfile:
christopher@45 105 results_to_xml(output,outfile)
christopher@45 106 elif ".json" in outfile:
christopher@45 107 results_to_json(output,outfile)
christopher@45 108 else:
christopher@45 109 print "Error in syncopation.py: Unrecognised output file type: ", outfile
christopher@45 110
christopher@45 111 return output
christopher@45 112
christopher@45 113
christopher@45 114
christopher@45 115 def results_to_xml(results, outputFilename):
christopher@45 116 from xml.etree.ElementTree import Element, ElementTree
christopher@45 117
christopher@45 118 elem = Element("syncopation_results")
christopher@45 119
christopher@45 120 for key, val in results.items():
christopher@45 121 child = Element(key)
christopher@45 122 child.text = str(val)
christopher@45 123 elem.append(child)
christopher@45 124
christopher@45 125 ElementTree(elem).write(outputFilename)
christopher@45 126
christopher@45 127 def results_to_json(results, outputFilename):
christopher@45 128 import json
christopher@45 129
christopher@45 130 fileHandle = open(outputFilename, 'w')
christopher@45 131 json.dump(results, fileHandle, sort_keys=True, indent=4, separators=(',', ': '))
christopher@45 132 fileHandle.flush()
christopher@45 133