christopher@45
|
1 '''
|
christopher@45
|
2 Author: Chunyang Song
|
christopher@45
|
3 Institution: Centre for Digital Music, Queen Mary University of London
|
christopher@45
|
4
|
christopher@45
|
5 '''
|
christopher@45
|
6
|
christopher@71
|
7 from basic_functions import get_H, ceiling, velocity_sequence_to_min_timespan, get_rhythm_category, find_rhythm_Lmax
|
christopher@45
|
8 from parameter_setter import are_parameters_valid
|
christopher@45
|
9
|
christopher@45
|
10 # The get_metricity function calculates the metricity for a binary sequence with given sequence of metrical weights in a certain metrical level.
|
christopher@45
|
11 def get_metricity(binarySequence, H):
|
christopher@45
|
12 metricity = 0
|
christopher@45
|
13 for m in range(len(binarySequence)):
|
christopher@45
|
14 metricity = metricity + binarySequence[m]*H[m]
|
christopher@45
|
15 return metricity
|
christopher@45
|
16
|
christopher@45
|
17 # The get_max_metricity function calculates the maximum metricity for the same number of notes in a binary sequence.
|
christopher@45
|
18 def get_max_metricity(binarySequence, H):
|
christopher@45
|
19 maxMetricity = 0
|
christopher@45
|
20 H.sort(reverse=True) # Sort the metrical weight sequence from large to small
|
christopher@45
|
21 for i in range(sum(binarySequence)):
|
christopher@45
|
22 maxMetricity = maxMetricity+H[i]
|
christopher@45
|
23 return maxMetricity
|
christopher@45
|
24
|
christopher@45
|
25
|
christopher@45
|
26
|
christopher@45
|
27 # The get_syncopation function calculates the syncopation value of the given sequence for TMC model.
|
christopher@45
|
28 #def get_syncopation(seq, subdivision_seq, weight_seq, L_max, rhythm_category):
|
christopher@45
|
29 def get_syncopation(bar, parameters = None):
|
christopher@45
|
30 syncopation = None
|
christopher@45
|
31 binarySequence = bar.get_binary_sequence()
|
christopher@45
|
32 subdivisionSequence = bar.get_subdivision_sequence()
|
christopher@45
|
33
|
christopher@45
|
34 if get_rhythm_category(binarySequence, subdivisionSequence) == 'poly':
|
christopher@45
|
35 print 'Warning: TMC model detects polyrhythms so returning None.'
|
christopher@45
|
36 else:
|
christopher@45
|
37
|
christopher@45
|
38 # set the defaults
|
christopher@45
|
39 Lmax = 5
|
christopher@45
|
40 weightSequence = range(Lmax+1,0,-1) # i.e. [6,5,4,3,2,1]
|
christopher@45
|
41
|
christopher@45
|
42 if parameters!= None:
|
christopher@45
|
43 if 'Lmax' in parameters:
|
christopher@45
|
44 Lmax = parameters['Lmax']
|
christopher@45
|
45 if 'W' in parameters:
|
christopher@45
|
46 weightSequence = parameters['W']
|
christopher@45
|
47
|
christopher@45
|
48 if not are_parameters_valid(Lmax, weightSequence, subdivisionSequence):
|
christopher@45
|
49 print 'Error: the given parameters are not valid.'
|
christopher@45
|
50 else:
|
christopher@45
|
51 binarySequence = velocity_sequence_to_min_timespan(binarySequence) # converting to the minimum time-span format
|
christopher@71
|
52 L = find_rhythm_Lmax(binarySequence, Lmax, weightSequence, subdivisionSequence)
|
christopher@45
|
53 if L != None:
|
christopher@45
|
54 #? generate the metrical weights of the lowest level,
|
christopher@45
|
55 #? using the last matching_level number of elements in the weightSequence, to make sure the last element is 1
|
christopher@45
|
56 H = get_H (weightSequence[-(L+1):], subdivisionSequence, L)
|
christopher@45
|
57 metricity = get_metricity(binarySequence, H) # converting to binary sequence then calculate metricity
|
christopher@45
|
58 maxMetricity = get_max_metricity(binarySequence, H)
|
christopher@45
|
59
|
christopher@45
|
60 syncopation = maxMetricity - metricity
|
christopher@45
|
61
|
christopher@45
|
62 return syncopation
|
christopher@45
|
63
|