view Syncopation models/TMC.py @ 0:76ce27beba95

Have uploaded the syncopation dataset and audio wavefies.
author Chunyang Song <csong@eecs.qmul.ac.uk>
date Fri, 21 Mar 2014 15:49:46 +0000
parents
children b2da092dc2e0
line wrap: on
line source
'''
Author: Chunyang Song
Institution: Centre for Digital Music, Queen Mary University of London

** Toussaint's Metric Complexity Model **

Algorithm:

Only applicable to monorhythms.

Define metrical hierarchy by given time signature;
Calculate how many onsets and determine Maximum Metricality Max_Metric;
Calculate the Metrical Simplicity - the weights of all onsets;
Syncopation = Max_Metric - Metric_simplicity.
Output the predicted syncopation score; -1 indicates non-applicable

'''

from MeterStructure import MeterStructure

def metricalModel(rhythm, time_sig, category, bar):
	ms = MeterStructure(time_sig)
	meter = ms.getLJWeights(bar)
	if len(meter) !=0:
		
		metricalSimplicity = 0  # sum of weights of onsets per bar
		maxMetrical = 0 	 # maximum metricity per bar
		onsetCount = 0		 # The number of onsets per bar
	
		if 'poly' in category:  # not applicable to polyrhythms
			return -1
	
		# Calculate metricalSimplicity
		else:
			l = len(rhythm)
			for i in range(l):
				if rhythm[i] == 1: # onset detected
					pos = int((float(i)/l) *len(meter)) # looking for the metrical position where this note locates
					metricalSimplicity = metricalSimplicity+meter[pos]
					onsetCount = onsetCount+1
		
			# Calculate max metricity
			meter.sort(reverse=True)
			for i in range(0,onsetCount):
				maxMetrical = maxMetrical+meter[i]
			
			#print 'test', onsetCount, maxMetrical, metricalSimplicity
			syncopation = (maxMetrical - metricalSimplicity)
	
			return syncopation	
	else:
		return -1

# Retrieve the stimuli
f = file('stimuli.txt')
#f = file('stimuli_34only.txt')

#Calculate syncopation for each rhythm pattern
while True:
	line = f.readline().split(';')
	if len(line) == 1:
		 break
	else:
		sti_name = line[0]
		rhythmString = line[1].split()
		time_sig = line[2]
		category = line[3]
		bar = int(line[4])
		
		rhythm = map(int,rhythmString[0].split(','))

		print sti_name, metricalModel(rhythm, time_sig, category, bar)