annotate Syncopation models/syncopation.py @ 41:903aec3d5b9f

merged
author christopherh <christopher.harte@eecs.qmul.ac.uk>
date Thu, 23 Apr 2015 15:47:48 +0100
parents 6371e8f21f7d
children
rev   line source
csong@9 1 '''
csong@9 2 Author: Chunyang Song
csong@9 3 Institution: Centre for Digital Music, Queen Mary University of London
csong@9 4
csong@9 5 '''
christopher@38 6 from rhythm_parser import *
christopher@38 7 from music_objects import *
christopher@38 8
csong@9 9
csong@35 10 def sync_perbar_permodel (model, bar, parameters=None):
csong@21 11 return model.get_syncopation(bar, parameters)
csong@9 12
christopher@40 13 def calculate_syncopation(model, source, parameters=None):
christopher@38 14 total = 0.0
christopher@38 15 barResults = []
csong@23 16 numberOfNotes = 0
csong@28 17
christopher@38 18 barlist = None
christopher@38 19
christopher@38 20 if isinstance(source, BarList):
christopher@38 21 barlist = source
christopher@38 22 sourceType = "bar list"
christopher@40 23 elif isinstance(source, Bar):
christopher@40 24 barlist = BarList().append(source)
christopher@40 25 sourceType = "single bar"
christopher@38 26 elif isinstance(source, basestring):
christopher@38 27 #treat source as a filename
christopher@38 28 sourceType = source
christopher@38 29 if source[-4:]==".mid":
christopher@38 30 import readmidi
christopher@38 31 midiFile = readmidi.read_midi_file(source)
christopher@38 32 barlist = readmidi.get_bars_from_midi(midiFile)
christopher@38 33
christopher@38 34 elif source[-4:]==".rhy":
christopher@38 35 #import rhythm_parser
christopher@38 36 barlist = read_rhythm(source)
christopher@38 37 else:
christopher@38 38 print "Error in syncopation_barlist_permodel(): Unrecognised file type."
christopher@38 39 else:
christopher@38 40 print "Error in syncopation_barlist_permodel(): unrecognised source type."
csong@35 41
christopher@38 42 barsDiscarded=0
christopher@40 43 discardedlist = []
christopher@40 44 includedlist = []
csong@28 45
christopher@38 46 if barlist!=None:
christopher@38 47 for bar in barlist:
christopher@38 48 if not bar.is_empty():
christopher@38 49 barSyncopation = sync_perbar_permodel(model, bar, parameters)
christopher@38 50 else:
christopher@38 51 barSyncopation = None
christopher@38 52 print 'Bar %d cannot be measured because it is empty, returning None.' % barlist.index(bar)
christopher@38 53
christopher@38 54 barResults.append(barSyncopation)
christopher@38 55 if barSyncopation != None:
christopher@38 56 total += barSyncopation
christopher@38 57 numberOfNotes += sum(bar.get_binary_sequence())
christopher@40 58 includedlist.append(barlist.index(bar))
christopher@38 59 else:
christopher@38 60 barsDiscarded += 1
christopher@40 61 discardedlist.append(barlist.index(bar))
christopher@38 62 print 'Model could not measure bar %d, returning None.' % barlist.index(bar)
csong@23 63
christopher@38 64 import WNBD
christopher@38 65 if model is WNBD:
christopher@38 66 total = total / numberOfNotes
csong@9 67
christopher@38 68 average = total / (len(barResults)-barsDiscarded)
csong@9 69
christopher@40 70 return {
christopher@40 71 "model_name":model.__name__ ,
christopher@40 72 "summed_syncopation":total,
christopher@40 73 "mean_syncopation_per_bar":average,
christopher@40 74 "source":sourceType,
christopher@40 75 "number_of_bars":len(barResults),
christopher@40 76 "number_of_bars_not_measured":barsDiscarded,
christopher@40 77 "bars_with_valid_output":includedlist,
christopher@40 78 "syncopation_by_bar":barResults
christopher@40 79 }
csong@21 80
csong@9 81
csong@9 82
christopher@38 83 def results_to_xml(results, outputFilename):
christopher@38 84 from xml.etree.ElementTree import Element, ElementTree
csong@9 85
christopher@38 86 elem = Element("syncopation_results")
csong@9 87
christopher@38 88 for key, val in results.items():
christopher@38 89 child = Element(key)
christopher@38 90 child.text = str(val)
christopher@38 91 elem.append(child)
csong@9 92
christopher@38 93 ElementTree(elem).write(outputFilename)
csong@9 94
csong@9 95