csong@0: ''' csong@0: Author: Chunyang Song csong@0: Institution: Centre for Digital Music, Queen Mary University of London csong@0: csong@0: ** Toussaint's Metric Complexity Model ** csong@0: csong@0: Algorithm: csong@0: csong@0: Only applicable to monorhythms. csong@0: csong@0: Define metrical hierarchy by given time signature; csong@0: Calculate how many onsets and determine Maximum Metricality Max_Metric; csong@0: Calculate the Metrical Simplicity - the weights of all onsets; csong@0: Syncopation = Max_Metric - Metric_simplicity. csong@0: Output the predicted syncopation score; -1 indicates non-applicable csong@0: csong@0: ''' csong@0: csong@0: from MeterStructure import MeterStructure csong@0: csong@0: def metricalModel(rhythm, time_sig, category, bar): csong@0: ms = MeterStructure(time_sig) csong@0: meter = ms.getLJWeights(bar) csong@0: if len(meter) !=0: csong@0: csong@0: metricalSimplicity = 0 # sum of weights of onsets per bar csong@0: maxMetrical = 0 # maximum metricity per bar csong@0: onsetCount = 0 # The number of onsets per bar csong@0: csong@0: if 'poly' in category: # not applicable to polyrhythms csong@0: return -1 csong@0: csong@0: # Calculate metricalSimplicity csong@0: else: csong@0: l = len(rhythm) csong@0: for i in range(l): csong@0: if rhythm[i] == 1: # onset detected csong@0: pos = int((float(i)/l) *len(meter)) # looking for the metrical position where this note locates csong@0: metricalSimplicity = metricalSimplicity+meter[pos] csong@0: onsetCount = onsetCount+1 csong@0: csong@0: # Calculate max metricity csong@0: meter.sort(reverse=True) csong@0: for i in range(0,onsetCount): csong@0: maxMetrical = maxMetrical+meter[i] csong@0: csong@0: #print 'test', onsetCount, maxMetrical, metricalSimplicity csong@0: syncopation = (maxMetrical - metricalSimplicity) csong@0: csong@0: return syncopation csong@0: else: csong@0: return -1 csong@0: csong@0: # Retrieve the stimuli csong@0: f = file('stimuli.txt') csong@0: #f = file('stimuli_34only.txt') csong@0: csong@0: #Calculate syncopation for each rhythm pattern csong@0: while True: csong@0: line = f.readline().split(';') csong@0: if len(line) == 1: csong@0: break csong@0: else: csong@0: sti_name = line[0] csong@0: rhythmString = line[1].split() csong@0: time_sig = line[2] csong@0: category = line[3] csong@0: bar = int(line[4]) csong@0: csong@0: rhythm = map(int,rhythmString[0].split(',')) csong@0: csong@0: print sti_name, metricalModel(rhythm, time_sig, category, bar)