view 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 source
'''
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 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

	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)

		import WNBD
		if model is WNBD:
			total =  total / numberOfNotes

		average = total / (len(barResults)-barsDiscarded)

 	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}



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)