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