Mercurial > hg > syncopation-dataset
diff 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 |
line wrap: on
line diff
--- a/Syncopation models/TMC.py Fri Apr 03 22:57:27 2015 +0100 +++ b/Syncopation models/TMC.py Tue Apr 07 19:05:07 2015 +0100 @@ -4,52 +4,81 @@ ''' -from BasicFuncs import get_H, ceiling, get_min_timeSpan +from basic_functions import get_H, ceiling, get_min_timeSpan, get_rhythm_category # 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): +def get_metricity(binarySequence, H): metricity = 0 - for m in range(len(seq)): - metricity = metricity + seq[m]*H[m] + for m in range(len(binarySequence)): + metricity = metricity + binarySequence[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 +def get_max_metricity(binarySequence, H): + maxMetricity = 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 + for i in range(sum(binarySequence)): + maxMetricity = maxMetricity+H[i] + return maxMetricity + +# find the metrical level L that contains the same number of metrical positions as the length of the binary sequence +# if the given Lmax is not big enough to analyse the given sequence, request a bigger Lmax +def find_L(rhythmSequence, Lmax, weightSequence, subdivisionSequence): + L = Lmax + + # initially assuming the Lmax is not big enough + needBiggerLmax = True + + # from the lowest metrical level (Lmax) to the highest, find the matching metrical level that + # has the same length as the length of binary sequence + while L >= 0: + if len(get_H(weightSequence,subdivisionSequence, L)) == len(rhythmSequence): + needBiggerLmax = False + break + else: + L = L - 1 + + # if need a bigger Lmax, print error message and return None; otherwise return the matching metrical level L + if needBiggerLmax: + print 'Error: needs a bigger L_max (i.e. the lowest metrical level) to match the given rhythm sequence.' + L = None + + return L # 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): +#def get_syncopation(seq, subdivision_seq, weight_seq, L_max, rhythm_category): +def get_syncopation(bar, parameters = None): syncopation = None - if rhythm_category == 'poly': - print 'Error: TMC model cannot deal with polyrhythms.' + binarySequence = bar.get_binary_sequence() + subdivisionSequence = bar.get_subdivision_sequence() + + if get_rhythm_category(binarySequence, subdivisionSequence) == 'poly': + print 'Warning: TMC model detects polyrhythms so returning None.' else: - seq = get_min_timeSpan(seq) # converting to the minimum time-span format + binarySequence = get_min_timeSpan(binarySequence) # 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 + # If the parameters are not given, use the default settings + if parameters == None: + Lmax = 5 + weightSequence = range(Lmax+1,0,-1) # i.e. [6,5,4,3,2,1] + else: + if are_parameters_valid(parameters): + Lmax = parameters['Lmax'] + weightSequence = parameters['W'] else: - matching_level = matching_level - 1 + pass + #raise InvalidParameterError - 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) + L = find_L(binarySequence, Lmax, weightSequence, subdivisionSequence) + if L != None: + #? generate the metrical weights of the lowest level, + #? using the last matching_level number of elements in the weightSequence, to make sure the last element is 1 + H = get_H (weightSequence[-(L+1):], subdivisionSequence, L) - metricity = get_metricity(ceiling(seq), H) # converting to binary sequence then calculate metricity - max_metricity = get_max_metricity(ceiling(seq), H) + metricity = get_metricity(binarySequence, H) # converting to binary sequence then calculate metricity + maxMetricity = get_max_metricity(binarySequence, H) - syncopation = max_metricity - metricity + syncopation = maxMetricity - metricity + return syncopation