diff Syncopation models/LHL.py @ 12:4acddc008048

Revised LHL and PRS model's argument list; refactored the variable names
author csong <csong@eecs.qmul.ac.uk>
date Fri, 03 Apr 2015 16:38:32 +0100
parents 031e2ccb1fb6
children 9030967a05f8
line wrap: on
line diff
--- a/Syncopation models/LHL.py	Fri Apr 03 11:41:01 2015 +0100
+++ b/Syncopation models/LHL.py	Fri Apr 03 16:38:32 2015 +0100
@@ -3,65 +3,85 @@
 Institution: Centre for Digital Music, Queen Mary University of London
 '''
 
-from BasicFuncs import concatenate, repeat, subdivide, ceiling
+from basic_functions import concatenate, repeat, subdivide, ceiling, get_rhythm_category
 
-terminal_nodes = []		# Global variable, storing all the terminal nodes from recursive tree structure in time order
+terminalNodes = []		# Global variable, storing all the terminal nodes from recursive tree structure in time order
 
 # Each terminnal node contains two properties: its node type (note or rest) and its metrical weight.
 class Node:
-	def __init__(self,node_type,metrical_weight):
-		self.node_type = node_type
-		self.metrical_weight = metrical_weight
+	def __init__(self,nodeType,metricalWeight):
+		self.nodeType = nodeType
+		self.metricalWeight = metricalWeight
 
 # This function will recurse the tree for a binary sequence and return a sequence containing the terminal nodes in time order.
-def recursive_tree(seq, subdivision_seq, weight_seq, metrical_weight, level):
-	if seq == concatenate([1],repeat([0],len(seq)-1)):	# If matching to a Note type, add to terminal nodes
-		terminal_nodes.append(Node('N',metrical_weight))
+def recursive_tree(binarySequence, subdivisionSequence, weightSequence, metricalWeight, level):
+	# If matching to a Note type, add to terminal nodes
+	if binarySequence == concatenate([1],repeat([0],len(binarySequence)-1)):	
+		terminalNodes.append(Node('N',metricalWeight))
 
-	elif seq == repeat([0],len(seq)):					# If matching to a Rest type, add to terminal nodes
-		terminal_nodes.append(Node('R',metrical_weight))
+	# If matching to a Rest type, add to terminal nodes
+	elif binarySequence == repeat([0],len(binarySequence)):					
+		terminalNodes.append(Node('R',metricalWeight))
 
-	else:													# Keep subdividing by the subdivisor of the next level
-		sub_seq = subdivide(seq, subdivision_seq[level+1])	
-		sub_weight_seq = concatenate([metrical_weight],repeat([weight_seq[level+1]],subdivision_seq[level+1]-1))
-		for a in range(len(sub_seq)):
-			recursive_tree(sub_seq[a], subdivision_seq, weight_seq, sub_weight_seq[a], level+1)
+	# Keep subdividing by the subdivisor of the next level
+	else:													
+		subBinarySequences = subdivide(binarySequence, subdivisionSequence[level+1])	
+		subWeightSequences = concatenate([metricalWeight],repeat([weightSequence[level+1]],subdivisionSequence[level+1]-1))
+		for a in range(len(subBinarySequences)):
+			recursive_tree(subBinarySequences[a], subdivisionSequence, weightSequence, subWeightSequences[a], level+1)
 
-# This function calculate syncoaption score for LHL model. 
-def get_syncopation(seq, subdivision_seq, weight_seq, prebar_seq, rhythm_category):
+def get_syncopation(bar, weightSequence = None, LMax = None):
+	'''
+	The get_syncopation function calculates syncopation value . 
+	'''
+#def get_syncopation(seq, subdivision_seq, weight_seq, prebar_seq, rhythm_category):
 	syncopation = None
-	if rhythm_category == 'poly':
-		print 'Error: LHL model cannot deal with polyrhythms.'
+
+	binarySequence = bar.get_binary_sequence()
+	subdivisionSequence = bar.get_subdivision_sequence()
+
+	if get_rhythm_category(binarySequence, subdivisionSequence) == 'poly':
+		print 'Warning: LHL model detects polyrhythms so returning None.'
 	else:
+		if weightSequence == None:
+			if LMax == None:
+				LMax  = 5
+				weightSequence = range(0,-LMax,-1)
+
 		# If there is rhythm in previous bar, process its tree structure
-		if prebar_seq != None:		
-			recursive_tree(ceiling(prebar_seq), subdivision_seq, weight_seq, weight_seq[0],0)
+		if bar.get_previous_bar() != None:
+			prebarBinarySequence = bar.get_previous_bar().get_binary_sequence()
+			recursive_tree(ceiling(prebarBinarySequence), subdivisionSequence, weightSequence, weightSequence[0],0)
 			
 			# Only keep the last note-type node
-			while terminal_nodes[-1].node_type != 'N':
-				del terminal_nodes[-1]
-			del terminal_nodes[0:-1]
+			while terminalNodes[-1].node_type != 'N':
+				del terminalNodes[-1]
+			del terminalNodes[0:-1]
 
 		# For the rhythm in the current bar, process its tree structure and store the terminal nodes 
-		recursive_tree(ceiling(seq), subdivision_seq, weight_seq, weight_seq[0],0)
+		recursive_tree(ceiling(binarySequence), subdivisionSequence, weightSequence, weightSequence[0],0)
 		
-		# for t in terminal_nodes:
+		# for t in terminalNodes:
 		# 	print '<', t.node_type, t.metrical_weight, '>'
 
-		# Search for the NR pairs that contribute to syncopation, add the weight-difference to the NR_pair_syncopation list
-		NR_pair_syncopation = []
-		for i in range(len(terminal_nodes)-1,0,-1):
-			if terminal_nodes[i].node_type == 'R':
+		# Search for the NR pairs that contribute to syncopation, 
+		# then add the weight-difference to the NRpairSyncopation list
+		NRpairSyncopation = []
+		for i in range(len(terminalNodes)-1,0,-1):
+			if terminalNodes[i].node_type == 'R':
 				for j in range(i-1, -1, -1):
-					if (terminal_nodes[j].node_type == 'N') & (terminal_nodes[i].metrical_weight >= terminal_nodes[j].metrical_weight):
-						NR_pair_syncopation.append(terminal_nodes[i].metrical_weight - terminal_nodes[j].metrical_weight)
+					if (terminalNodes[j].node_type == 'N') & (terminalNodes[i].metricalWeight >= terminalNodes[j].metricalWeight):
+						NRpairSyncopation.append(terminalNodes[i].metricalWeight - terminalNodes[j].metricalWeight)
 						break
-		#print NR_pair_syncopation
+		#print NRpairSyncopation
 
-		# If no syncopation, the value is -1; otherwise, sum all the local syncopation values stored in NR_pair_syncopation list	
-		if len(NR_pair_syncopation) != 0:
-			syncopation = sum(NR_pair_syncopation)	
-		elif len(terminal_nodes) != 0:
+		# If there are syncopation, sum all the local syncopation values stored in NRpairSyncopation list	
+		if len(NRpairSyncopation) != 0:
+			syncopation = sum(NRpairSyncopation)
+		# If no syncopation, the value is -1; 	
+		elif len(terminalNodes) != 0:
 			syncopation = -1
 
 	return syncopation
+
+