diff 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
line wrap: on
line diff
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/Syncopation models/synpy/syncopation.py	Thu Apr 23 23:52:04 2015 +0100
@@ -0,0 +1,112 @@
+'''
+Author: Chunyang Song
+Institution: Centre for Digital Music, Queen Mary University of London
+
+'''
+from rhythm_parser import *
+from music_objects import *
+
+
+def sync_perbar_permodel (model, bar, parameters=None):
+	return model.get_syncopation(bar, parameters)
+
+def calculate_syncopation(model, source, parameters=None, outfile=None):
+ 	total = 0.0
+ 	barResults = []
+ 	numberOfNotes = 0
+
+	barlist = None
+
+ 	if isinstance(source, BarList):
+ 		barlist = source
+ 		sourceType = "bar list"
+ 	elif isinstance(source, Bar):
+ 		barlist = BarList().append(source)
+ 		sourceType = "single bar"
+	elif isinstance(source, basestring):
+		#treat source as a filename
+		sourceType = source
+		if source[-4:]==".mid":
+			import readmidi
+			midiFile = readmidi.read_midi_file(source)
+			barlist = readmidi.get_bars_from_midi(midiFile)
+
+		elif source[-4:]==".rhy":
+			#import rhythm_parser 
+			barlist = read_rhythm(source)
+		else:
+			print "Error in syncopation_barlist_permodel(): Unrecognised file type."
+	else:
+		print "Error in syncopation_barlist_permodel(): unrecognised source type."
+	
+	barsDiscarded=0
+	discardedlist = []
+	includedlist = []
+
+	if barlist!=None:
+		for bar in barlist:
+			if not bar.is_empty():
+				barSyncopation = sync_perbar_permodel(model, bar, parameters)
+			else:
+				barSyncopation = None
+				print 'Bar %d cannot be measured because it is empty, returning None.' % barlist.index(bar)
+			
+			barResults.append(barSyncopation)
+			if barSyncopation != None:
+				total += barSyncopation
+				numberOfNotes += sum(bar.get_binary_sequence())
+				includedlist.append(barlist.index(bar))
+			else:
+				barsDiscarded += 1
+				discardedlist.append(barlist.index(bar))
+				print 'Model could not measure bar %d, returning None.' % barlist.index(bar)
+
+		import WNBD
+		if model is WNBD:
+			total =  total / numberOfNotes
+
+		average = total / (len(barResults)-barsDiscarded)
+
+	output = {
+ 			"model_name":model.__name__ , 
+ 			"summed_syncopation":total, 
+ 			"mean_syncopation_per_bar":average, 
+ 			"source":sourceType, 
+ 			"number_of_bars":len(barResults), 
+ 			"number_of_bars_not_measured":barsDiscarded, 
+ 			"bars_with_valid_output":includedlist, 
+ 			"syncopation_by_bar":barResults
+ 			}
+
+ 	if outfile!=None:
+ 		
+ 		if ".xml" in outfile:
+ 			results_to_xml(output,outfile)
+ 		elif ".json" in outfile:
+ 			results_to_json(output,outfile)
+ 		else:
+ 			print "Error in syncopation.py: Unrecognised output file type: ", outfile
+
+ 	return output
+
+
+
+def results_to_xml(results, outputFilename):
+	from xml.etree.ElementTree import Element, ElementTree
+
+	elem = Element("syncopation_results")
+
+	for key, val in results.items():
+		child = Element(key)
+		child.text = str(val)
+		elem.append(child)
+
+	ElementTree(elem).write(outputFilename)
+
+def results_to_json(results, outputFilename):
+	import json
+
+	fileHandle = open(outputFilename, 'w')
+	json.dump(results, fileHandle, sort_keys=True, indent=4, separators=(',', ': '))
+	fileHandle.flush()
+