annotate Syncopation models/synpy/syncopation.py @ 45:6e9154fc58df

moving the code files to the synpy package directory
author christopherh <christopher.harte@eecs.qmul.ac.uk>
date Thu, 23 Apr 2015 23:52:04 +0100
parents
children e71028851131
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@45 24 barlist = BarList().append(source)
christopher@45 25 sourceType = "single bar"
christopher@45 26 elif isinstance(source, basestring):
christopher@45 27 #treat source as a filename
christopher@45 28 sourceType = source
christopher@45 29 if source[-4:]==".mid":
christopher@45 30 import readmidi
christopher@45 31 midiFile = readmidi.read_midi_file(source)
christopher@45 32 barlist = readmidi.get_bars_from_midi(midiFile)
christopher@45 33
christopher@45 34 elif source[-4:]==".rhy":
christopher@45 35 #import rhythm_parser
christopher@45 36 barlist = read_rhythm(source)
christopher@45 37 else:
christopher@45 38 print "Error in syncopation_barlist_permodel(): Unrecognised file type."
christopher@45 39 else:
christopher@45 40 print "Error in syncopation_barlist_permodel(): unrecognised source type."
christopher@45 41
christopher@45 42 barsDiscarded=0
christopher@45 43 discardedlist = []
christopher@45 44 includedlist = []
christopher@45 45
christopher@45 46 if barlist!=None:
christopher@45 47 for bar in barlist:
christopher@45 48 if not bar.is_empty():
christopher@45 49 barSyncopation = sync_perbar_permodel(model, bar, parameters)
christopher@45 50 else:
christopher@45 51 barSyncopation = None
christopher@45 52 print 'Bar %d cannot be measured because it is empty, returning None.' % barlist.index(bar)
christopher@45 53
christopher@45 54 barResults.append(barSyncopation)
christopher@45 55 if barSyncopation != None:
christopher@45 56 total += barSyncopation
christopher@45 57 numberOfNotes += sum(bar.get_binary_sequence())
christopher@45 58 includedlist.append(barlist.index(bar))
christopher@45 59 else:
christopher@45 60 barsDiscarded += 1
christopher@45 61 discardedlist.append(barlist.index(bar))
christopher@45 62 print 'Model could not measure bar %d, returning None.' % barlist.index(bar)
christopher@45 63
christopher@45 64 import WNBD
christopher@45 65 if model is WNBD:
christopher@45 66 total = total / numberOfNotes
christopher@45 67
christopher@45 68 average = total / (len(barResults)-barsDiscarded)
christopher@45 69
christopher@45 70 output = {
christopher@45 71 "model_name":model.__name__ ,
christopher@45 72 "summed_syncopation":total,
christopher@45 73 "mean_syncopation_per_bar":average,
christopher@45 74 "source":sourceType,
christopher@45 75 "number_of_bars":len(barResults),
christopher@45 76 "number_of_bars_not_measured":barsDiscarded,
christopher@45 77 "bars_with_valid_output":includedlist,
christopher@45 78 "syncopation_by_bar":barResults
christopher@45 79 }
christopher@45 80
christopher@45 81 if outfile!=None:
christopher@45 82
christopher@45 83 if ".xml" in outfile:
christopher@45 84 results_to_xml(output,outfile)
christopher@45 85 elif ".json" in outfile:
christopher@45 86 results_to_json(output,outfile)
christopher@45 87 else:
christopher@45 88 print "Error in syncopation.py: Unrecognised output file type: ", outfile
christopher@45 89
christopher@45 90 return output
christopher@45 91
christopher@45 92
christopher@45 93
christopher@45 94 def results_to_xml(results, outputFilename):
christopher@45 95 from xml.etree.ElementTree import Element, ElementTree
christopher@45 96
christopher@45 97 elem = Element("syncopation_results")
christopher@45 98
christopher@45 99 for key, val in results.items():
christopher@45 100 child = Element(key)
christopher@45 101 child.text = str(val)
christopher@45 102 elem.append(child)
christopher@45 103
christopher@45 104 ElementTree(elem).write(outputFilename)
christopher@45 105
christopher@45 106 def results_to_json(results, outputFilename):
christopher@45 107 import json
christopher@45 108
christopher@45 109 fileHandle = open(outputFilename, 'w')
christopher@45 110 json.dump(results, fileHandle, sort_keys=True, indent=4, separators=(',', ': '))
christopher@45 111 fileHandle.flush()
christopher@45 112