Mercurial > hg > syncopation-dataset
comparison Syncopation models/LHL.py @ 28:5de1cb45c145
Parameters setting implemented.
author | csong <csong@eecs.qmul.ac.uk> |
---|---|
date | Sun, 12 Apr 2015 22:34:35 +0100 |
parents | b959c2acb927 |
children | f5abd2e8cafe |
comparison
equal
deleted
inserted
replaced
27:ed29ed80635c | 28:5de1cb45c145 |
---|---|
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 from basic_functions import concatenate, repeat, subdivide, ceiling, get_rhythm_category | 6 from basic_functions import concatenate, repeat, subdivide, ceiling, get_rhythm_category |
7 from parameter_setter import are_parameters_valid | |
7 | 8 |
8 terminalNodes = [] # Global variable, storing all the terminal nodes from recursive tree structure in time order | 9 terminalNodes = [] # Global variable, storing all the terminal nodes from recursive tree structure in time order |
9 | 10 |
10 # Each terminnal node contains two properties: its node type (note or rest) and its metrical weight. | 11 # Each terminnal node contains two properties: its node type (note or rest) and its metrical weight. |
11 class Node: | 12 class Node: |
28 subBinarySequences = subdivide(binarySequence, subdivisionSequence[level+1]) | 29 subBinarySequences = subdivide(binarySequence, subdivisionSequence[level+1]) |
29 subWeightSequences = concatenate([metricalWeight],repeat([weightSequence[level+1]],subdivisionSequence[level+1]-1)) | 30 subWeightSequences = concatenate([metricalWeight],repeat([weightSequence[level+1]],subdivisionSequence[level+1]-1)) |
30 for a in range(len(subBinarySequences)): | 31 for a in range(len(subBinarySequences)): |
31 recursive_tree(subBinarySequences[a], subdivisionSequence, weightSequence, subWeightSequences[a], level+1) | 32 recursive_tree(subBinarySequences[a], subdivisionSequence, weightSequence, subWeightSequences[a], level+1) |
32 | 33 |
33 #!!!! needs fixing | |
34 def are_parameters_valid(parameters): | |
35 areValid = True | |
36 # if 'Lmax' not in parameters : | |
37 | 34 |
38 def get_syncopation(bar, parameters = None): | 35 def get_syncopation(bar, parameters = None): |
39 del terminalNodes[:] | 36 del terminalNodes[:] |
40 syncopation = None | 37 syncopation = None |
41 | 38 |
42 binarySequence = bar.get_binary_sequence() | 39 binarySequence = bar.get_binary_sequence() |
43 subdivisionSequence = bar.get_subdivision_sequence() | 40 subdivisionSequence = bar.get_subdivision_sequence() |
44 | 41 |
42 # LHL can only measure monorhythms | |
45 if get_rhythm_category(binarySequence, subdivisionSequence) == 'poly': | 43 if get_rhythm_category(binarySequence, subdivisionSequence) == 'poly': |
46 print 'Warning: LHL model detects polyrhythms so returning None.' | 44 print 'Warning: LHL model detects polyrhythms so returning None.' |
47 else: | 45 else: |
48 # If the parameters are not given, use the default settings | 46 # set defaults |
49 if parameters == None: | 47 Lmax = 5 |
50 Lmax = 5 | 48 weightSequence = range(0,-Lmax,-1) |
51 weightSequence = range(0,-Lmax,-1) # i.e. [0,-1,-2,-3,-4] | 49 # if parameters are specified by users, check their validities and update parameters if valid |
50 if parameters!= None: | |
51 if 'Lmax' in parameters: | |
52 Lmax = parameters['Lmax'] | |
53 if 'W' in parameters: | |
54 weightSequence = parameters['W'] | |
55 | |
56 if not are_parameters_valid(Lmax, weightSequence, subdivisionSequence): | |
57 print 'Error: the given parameters are not valid.' | |
52 else: | 58 else: |
53 if are_parameters_valid(parameters): | 59 # If there is rhythm in previous bar, process its tree structure |
54 Lmax = parameters['Lmax'] | 60 if bar.get_previous_bar() != None: |
55 weightSequence = parameters['W'] | 61 prebarBinarySequence = bar.get_previous_bar().get_binary_sequence() |
56 else: | 62 recursive_tree(ceiling(prebarBinarySequence), subdivisionSequence, weightSequence, weightSequence[0],0) |
57 pass | 63 |
58 #raise InvalidParameterError | 64 # Only keep the last note-type node |
65 while terminalNodes[-1].nodeType != 'N': | |
66 del terminalNodes[-1] | |
67 del terminalNodes[0:-1] | |
59 | 68 |
60 # If there is rhythm in previous bar, process its tree structure | 69 # For the rhythm in the current bar, process its tree structure and store the terminal nodes |
61 if bar.get_previous_bar() != None: | 70 recursive_tree(ceiling(binarySequence), subdivisionSequence, weightSequence, weightSequence[0],0) |
62 prebarBinarySequence = bar.get_previous_bar().get_binary_sequence() | |
63 recursive_tree(ceiling(prebarBinarySequence), subdivisionSequence, weightSequence, weightSequence[0],0) | |
64 | 71 |
65 # Only keep the last note-type node | 72 # for t in terminalNodes: |
66 while terminalNodes[-1].nodeType != 'N': | 73 # print '<', t.nodeType, t.metricalWeight, '>' |
67 del terminalNodes[-1] | |
68 del terminalNodes[0:-1] | |
69 | 74 |
70 # For the rhythm in the current bar, process its tree structure and store the terminal nodes | 75 # Search for the NR pairs that contribute to syncopation,then add the weight-difference to the NRpairSyncopation list |
71 recursive_tree(ceiling(binarySequence), subdivisionSequence, weightSequence, weightSequence[0],0) | 76 NRpairSyncopation = [] |
72 | 77 for i in range(len(terminalNodes)-1,0,-1): |
73 # for t in terminalNodes: | 78 if terminalNodes[i].nodeType == 'R': |
74 # print '<', t.nodeType, t.metricalWeight, '>' | 79 for j in range(i-1, -1, -1): |
80 if (terminalNodes[j].nodeType == 'N') & (terminalNodes[i].metricalWeight >= terminalNodes[j].metricalWeight): | |
81 NRpairSyncopation.append(terminalNodes[i].metricalWeight - terminalNodes[j].metricalWeight) | |
82 break | |
83 #print NRpairSyncopation | |
75 | 84 |
76 # Search for the NR pairs that contribute to syncopation, | 85 # If there are syncopation, sum all the local syncopation values stored in NRpairSyncopation list |
77 # then add the weight-difference to the NRpairSyncopation list | 86 if len(NRpairSyncopation) != 0: |
78 NRpairSyncopation = [] | 87 syncopation = sum(NRpairSyncopation) |
79 for i in range(len(terminalNodes)-1,0,-1): | 88 # If no syncopation, the value is -1; |
80 if terminalNodes[i].nodeType == 'R': | 89 elif len(terminalNodes) != 0: |
81 for j in range(i-1, -1, -1): | 90 syncopation = -1 |
82 if (terminalNodes[j].nodeType == 'N') & (terminalNodes[i].metricalWeight >= terminalNodes[j].metricalWeight): | |
83 NRpairSyncopation.append(terminalNodes[i].metricalWeight - terminalNodes[j].metricalWeight) | |
84 break | |
85 #print NRpairSyncopation | |
86 | |
87 # If there are syncopation, sum all the local syncopation values stored in NRpairSyncopation list | |
88 if len(NRpairSyncopation) != 0: | |
89 syncopation = sum(NRpairSyncopation) | |
90 # If no syncopation, the value is -1; | |
91 elif len(terminalNodes) != 0: | |
92 syncopation = -1 | |
93 | 91 |
94 return syncopation | 92 return syncopation |
95 | 93 |
96 | 94 |