Mercurial > hg > syncopation-dataset
view Syncopation models/TMC.py @ 23:df1e7c378ee0
fixed KTH, and WNBD
author | csong <csong@eecs.qmul.ac.uk> |
---|---|
date | Sun, 12 Apr 2015 13:06:17 +0100 |
parents | b959c2acb927 |
children | 5de1cb45c145 |
line wrap: on
line source
''' Author: Chunyang Song Institution: Centre for Digital Music, Queen Mary University of London ''' from basic_functions import get_H, ceiling, velocity_sequence_to_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(binarySequence, H): metricity = 0 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(binarySequence, H): maxMetricity = 0 H.sort(reverse=True) # Sort the metrical weight sequence from large to small 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(bar, parameters = None): syncopation = None 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: binarySequence = velocity_sequence_to_min_timespan(binarySequence) # converting to the minimum time-span format # 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: pass #raise InvalidParameterError 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(binarySequence, H) # converting to binary sequence then calculate metricity maxMetricity = get_max_metricity(binarySequence, H) syncopation = maxMetricity - metricity return syncopation