comparison Syncopation models/TMC.py @ 20:b959c2acb927

Refactored all models except for KTH, all past testing except for SG.
author csong <csong@eecs.qmul.ac.uk>
date Tue, 07 Apr 2015 19:05:07 +0100
parents 031e2ccb1fb6
children df1e7c378ee0
comparison
equal deleted inserted replaced
19:9030967a05f8 20:b959c2acb927
2 Author: Chunyang Song 2 Author: Chunyang Song
3 Institution: Centre for Digital Music, Queen Mary University of London 3 Institution: Centre for Digital Music, Queen Mary University of London
4 4
5 ''' 5 '''
6 6
7 from BasicFuncs import get_H, ceiling, get_min_timeSpan 7 from basic_functions import get_H, ceiling, get_min_timeSpan, get_rhythm_category
8 8
9 # The get_metricity function calculates the metricity for a binary sequence with given sequence of metrical weights in a certain metrical level. 9 # The get_metricity function calculates the metricity for a binary sequence with given sequence of metrical weights in a certain metrical level.
10 def get_metricity(seq, H): 10 def get_metricity(binarySequence, H):
11 metricity = 0 11 metricity = 0
12 for m in range(len(seq)): 12 for m in range(len(binarySequence)):
13 metricity = metricity + seq[m]*H[m] 13 metricity = metricity + binarySequence[m]*H[m]
14 return metricity 14 return metricity
15 15
16 # The get_max_metricity function calculates the maximum metricity for the same number of notes in a binary sequence. 16 # The get_max_metricity function calculates the maximum metricity for the same number of notes in a binary sequence.
17 def get_max_metricity(seq, H): 17 def get_max_metricity(binarySequence, H):
18 max_metricity = 0 18 maxMetricity = 0
19 H.sort(reverse=True) # Sort the metrical weight sequence from large to small 19 H.sort(reverse=True) # Sort the metrical weight sequence from large to small
20 for i in range(sum(seq)): 20 for i in range(sum(binarySequence)):
21 max_metricity = max_metricity+H[i] 21 maxMetricity = maxMetricity+H[i]
22 return max_metricity 22 return maxMetricity
23
24 # find the metrical level L that contains the same number of metrical positions as the length of the binary sequence
25 # if the given Lmax is not big enough to analyse the given sequence, request a bigger Lmax
26 def find_L(rhythmSequence, Lmax, weightSequence, subdivisionSequence):
27 L = Lmax
28
29 # initially assuming the Lmax is not big enough
30 needBiggerLmax = True
31
32 # from the lowest metrical level (Lmax) to the highest, find the matching metrical level that
33 # has the same length as the length of binary sequence
34 while L >= 0:
35 if len(get_H(weightSequence,subdivisionSequence, L)) == len(rhythmSequence):
36 needBiggerLmax = False
37 break
38 else:
39 L = L - 1
40
41 # if need a bigger Lmax, print error message and return None; otherwise return the matching metrical level L
42 if needBiggerLmax:
43 print 'Error: needs a bigger L_max (i.e. the lowest metrical level) to match the given rhythm sequence.'
44 L = None
45
46 return L
23 47
24 # The get_syncopation function calculates the syncopation value of the given sequence for TMC model. 48 # The get_syncopation function calculates the syncopation value of the given sequence for TMC model.
25 def get_syncopation(seq, subdivision_seq, weight_seq, L_max, rhythm_category): 49 #def get_syncopation(seq, subdivision_seq, weight_seq, L_max, rhythm_category):
50 def get_syncopation(bar, parameters = None):
26 syncopation = None 51 syncopation = None
27 if rhythm_category == 'poly': 52 binarySequence = bar.get_binary_sequence()
28 print 'Error: TMC model cannot deal with polyrhythms.' 53 subdivisionSequence = bar.get_subdivision_sequence()
54
55 if get_rhythm_category(binarySequence, subdivisionSequence) == 'poly':
56 print 'Warning: TMC model detects polyrhythms so returning None.'
29 else: 57 else:
30 seq = get_min_timeSpan(seq) # converting to the minimum time-span format 58 binarySequence = get_min_timeSpan(binarySequence) # converting to the minimum time-span format
31 59
32 # checking whether the given L_max is enough to analyse the given sequence, if not, request a bigger L_max 60 # If the parameters are not given, use the default settings
33 new_L_max = True 61 if parameters == None:
34 matching_level = L_max 62 Lmax = 5
35 while matching_level >= 0: 63 weightSequence = range(Lmax+1,0,-1) # i.e. [6,5,4,3,2,1]
36 if len(get_H(weight_seq,subdivision_seq, matching_level)) == len(seq): 64 else:
37 new_L_max = False 65 if are_parameters_valid(parameters):
38 break 66 Lmax = parameters['Lmax']
67 weightSequence = parameters['W']
39 else: 68 else:
40 matching_level = matching_level - 1 69 pass
70 #raise InvalidParameterError
41 71
42 if new_L_max == True: 72 L = find_L(binarySequence, Lmax, weightSequence, subdivisionSequence)
43 print 'Error: needs a bigger L_max (i.e. the lowest metrical level) to match the given rhythm sequence.' 73 if L != None:
44 74 #? generate the metrical weights of the lowest level,
45 else: 75 #? using the last matching_level number of elements in the weightSequence, to make sure the last element is 1
46 # generate the metrical weights of the lowest level, 76 H = get_H (weightSequence[-(L+1):], subdivisionSequence, L)
47 # using the last matching_level number of elements in the weight_seq list, to make sure the last element is 1
48 H = get_H (weight_seq[-(matching_level+1):], subdivision_seq, matching_level)
49 77
50 metricity = get_metricity(ceiling(seq), H) # converting to binary sequence then calculate metricity 78 metricity = get_metricity(binarySequence, H) # converting to binary sequence then calculate metricity
51 max_metricity = get_max_metricity(ceiling(seq), H) 79 maxMetricity = get_max_metricity(binarySequence, H)
52 80
53 syncopation = max_metricity - metricity 81 syncopation = maxMetricity - metricity
82
54 return syncopation 83 return syncopation
55 84