view Syncopation models/TMC.py @ 2:031e2ccb1fb6

Added rhythm parser and parameter setter
author Chunyang Song <csong@eecs.qmul.ac.uk>
date Fri, 20 Mar 2015 18:28:08 +0000
parents b2da092dc2e0
children b959c2acb927
line wrap: on
line source
'''
Author: Chunyang Song
Institution: Centre for Digital Music, Queen Mary University of London

'''

from BasicFuncs import get_H, ceiling, get_min_timeSpan

# The get_metricity function calculates the metricity for a binary sequence with given sequence of metrical weights in a certain metrical level.
def get_metricity(seq, H):
	metricity = 0
	for m in range(len(seq)):
		metricity = metricity + seq[m]*H[m]
	return metricity

# The get_max_metricity function calculates the maximum metricity for the same number of notes in a binary sequence.
def get_max_metricity(seq, H):
	max_metricity = 0
	H.sort(reverse=True) # Sort the metrical weight sequence from large to small
	for i in range(sum(seq)):
		max_metricity = max_metricity+H[i]
	return max_metricity

# The get_syncopation function calculates the syncopation value of the given sequence for TMC model. 
def get_syncopation(seq, subdivision_seq, weight_seq, L_max, rhythm_category):
	syncopation = None
	if rhythm_category == 'poly':
		print 'Error: TMC model cannot deal with polyrhythms.'
	else:
		seq = get_min_timeSpan(seq)	# converting to the minimum time-span format

		# checking whether the given L_max is enough to analyse the given sequence, if not, request a bigger L_max
		new_L_max = True
		matching_level = L_max
		while matching_level >= 0:
			if len(get_H(weight_seq,subdivision_seq, matching_level)) == len(seq):
				new_L_max = False
				break
			else:
				matching_level = matching_level - 1

		if new_L_max == True:
			print 'Error: needs a bigger L_max (i.e. the lowest metrical level) to match the given rhythm sequence.'
		
		else:
			# generate the metrical weights of the lowest level, 
			# using the last matching_level number of elements in the weight_seq list, to make sure the last element is 1
			H = get_H (weight_seq[-(matching_level+1):], subdivision_seq, matching_level)
			
			metricity = get_metricity(ceiling(seq), H)	# converting to binary sequence then calculate metricity
			max_metricity = get_max_metricity(ceiling(seq), H)

			syncopation = max_metricity - metricity
	return syncopation