diff Syncopation models/syncopation.py @ 38:cc38b3047ed9

updated syncopation.y to allow output of sync for a bar list also fixed some problems in models and other modules
author christopherh <christopher.harte@eecs.qmul.ac.uk>
date Mon, 13 Apr 2015 23:06:49 +0100
parents 3a878de00d19
children 6371e8f21f7d
line wrap: on
line diff
--- a/Syncopation models/syncopation.py	Mon Apr 13 22:36:51 2015 +0100
+++ b/Syncopation models/syncopation.py	Mon Apr 13 23:06:49 2015 +0100
@@ -3,102 +3,77 @@
 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 syncopation_barlist_permodel(model, source, parameters=None):
- 	total = 0
+def syncopation_barlist_permodel(model, source, parameters=None):
+ 	total = 0.0
+ 	barResults = []
  	numberOfNotes = 0
 
+	barlist = None
+
+ 	if isinstance(source, BarList):
+ 		barlist = source
+ 		sourceType = "bar list"
+	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
 
- 	for bar in barlist:
- 		if sync_perbar_permodel(model, bar, parameters) != None:
- 			total += sync_perbar_permodel(model, bar, parameters)
- 			numberOfNotes += sum(bar.get_binary_sequence())
- 		else:
- 			print 'Bar %d cannot be measured, returning None.' % barlist.index(bar)
+	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())
+			else:
+				barsDiscarded += 1
+				print 'Model could not measure bar %d, returning None.' % barlist.index(bar)
 
- 	if model is WNBD:
- 		total = (float) total/ numberOfNotes
+		import WNBD
+		if model is WNBD:
+			total =  total / numberOfNotes
 
-# def sync_perbar_permodel(seq, model, timesig = None, subdivision_seq = None, weight_seq = None, L_max = 5, prebar_seq = None, postbar_seq = None, strong_beat_level = None):
-# 	syncopation = None
+		average = total / (len(barResults)-barsDiscarded)
 
-# 	if seq == None or model == None:
-# 		print 'Error: please indicate rhythm sequence and syncopation model.'
+ 	return {"summed_syncopation":total, "average_syncopation_per_bar":average, "source":sourceType, "number_of_bars":len(barResults), "number_of_bars_not_measured":barsDiscarded, "syncopation_by_bar":barResults}
 
-# 	elif timesig == None and subdivision_seq == None:
-# 		print 'Error: please indicate either time signature or subdivision sequence.'
-	
-# 	else:
-# 		while subdivision_seq == None:
-# 			from basic_functions import get_subdivision_seq
-# 			subdivision_seq = get_subdivision_seq(timesig, L_max)
 
-# 		# The get_rhythm_category function is used to detect rhythm category: monorhythm or polyrhythm.
-# 		# For monorhythms, all prime factors of the length of minimum time-span representation of this sequence are
-# 		# elements of its subdivision_seq, otherwise it is polyrhythm; 
-# 		# e.g. prime_factors of polyrhythm 100100101010 in 4/4 is [2,3] but subdivision_seq = [1,2,2] for 4/4 
-# 		def get_rhythm_category():
-# 			rhythm_category = 'mono'
-# 			from basic_functions import get_min_timeSpan, find_prime_factors
-# 			for f in find_prime_factors(len(get_min_timeSpan(seq))):
-# 				if not (f in subdivision_seq): 
-# 					rhythm_category = 'poly'
-# 					break
-# 			return rhythm_category
-		
-# 		rhythm_category = get_rhythm_category()
 
-# 		if model == 'LHL':	
-# 			import LHL
-# 			if weight_seq == None:
-# 				weight_seq = range(0,-L_max,-1)
-# 			syncopation = LHL.get_syncopation(seq, subdivision_seq, weight_seq, prebar_seq, rhythm_category)
-# 		elif model == 'PRS':	
-# 			import PRS
-# 			syncopation = PRS.get_syncopation(seq, subdivision_seq, postbar_seq, rhythm_category)
-# 		elif model == 'TMC':	
-# 			import TMC
-# 			if weight_seq == None:
-# 				weight_seq = range(L_max+1,0,-1)
-# 			syncopation = TMC.get_syncopation(seq, subdivision_seq, weight_seq, L_max, rhythm_category)
-# 		elif model == 'SG':		
-# 			import SG
-# 			if weight_seq == None:
-# 				weight_seq = range(L_max+1)
-# 			syncopation = SG.get_syncopation(seq, subdivision_seq, weight_seq, L_max, rhythm_category)
-# 		elif model == 'KTH':
-# 			import KTH
-# 			syncopation = KTH.get_syncopation(seq, timesig, postbar_seq)
-# 		elif model == 'TOB':	
-# 			import TOB
-# 			syncopation = TOB.get_syncopation(seq)
-# 		elif model == 'WNBD':
-# 			import WNBD
-# 			if strong_beat_level == None:
-# 				if timesig == '4/4':
-# 					strong_beat_level = 2
-# 				else:
-# 					strong_beat_level = 1 
-# 			syncopation = WNBD.get_syncopation(seq, subdivision_seq, strong_beat_level, postbar_seq)
+def results_to_xml(results, outputFilename):
+	from xml.etree.ElementTree import Element, ElementTree
 
-# 		else:
-# 			print 'Error: undefined syncopation model.'
+	elem = Element("syncopation_results")
 
-# 	return syncopation
+	for key, val in results.items():
+		child = Element(key)
+		child.text = str(val)
+		elem.append(child)
 
-# def syncopation_all(rhythm, model, timesig, subdivision_seq = None, weight_seq = None, L_max = 5, strong_beat_level = None):
-# 	syncopation = 0
-# 	# Chope rhythm into seq
-# 	# ...
+	ElementTree(elem).write(outputFilename)
 
-# 	for (seq_perbar in seq):
-# 		sync_perbar = syncopation_perbar(seq_perbar,model, timesig, subdivision_seq, weight_seq, L_max, strong_beat_level)
-# 		if sync_perbar != None:
-# 			syncopation = syncopation + sync_perbar
 
-# 	return syncopation
-