annotate Syncopation models/TMC.py @ 1:b2da092dc2e0

The consolidated syncopation software. Have finished individual model and basic functions. Need to revise the coding in main.py, and add rhythm-input interface.
author Chunyang Song <csong@eecs.qmul.ac.uk>
date Sun, 05 Oct 2014 21:52:41 +0100
parents 76ce27beba95
children 031e2ccb1fb6
rev   line source
csong@0 1 '''
csong@0 2 Author: Chunyang Song
csong@0 3 Institution: Centre for Digital Music, Queen Mary University of London
csong@0 4
csong@0 5 '''
csong@0 6
csong@1 7 from basic_functions import get_H, ceiling, get_min_timeSpan
csong@0 8
csong@1 9 # The get_metricity function calculates the metricity for a binary sequence with given sequence of metrical weights in a certain metrical level.
csong@1 10 def get_metricity(seq, H):
csong@1 11 metricity = 0
csong@1 12 for m in range(len(seq)):
csong@1 13 metricity = metricity + seq[m]*H[m]
csong@1 14 return metricity
csong@1 15
csong@1 16 # The get_max_metricity function calculates the maximum metricity for the same number of notes in a binary sequence.
csong@1 17 def get_max_metricity(seq, H):
csong@1 18 max_metricity = 0
csong@1 19 H.sort(reverse=True) # Sort the metrical weight sequence from large to small
csong@1 20 for i in range(sum(seq)):
csong@1 21 max_metricity = max_metricity+H[i]
csong@1 22 return max_metricity
csong@1 23
csong@1 24 # The get_syncopation function calculates the syncopation value of the given sequence for TMC model.
csong@1 25 def get_syncopation(seq, subdivision_seq, weight_seq, L_max, rhythm_category):
csong@1 26 syncopation = None
csong@1 27 if rhythm_category == 'poly':
csong@1 28 print 'Error: TMC model cannot deal with polyrhythms.'
csong@1 29 else:
csong@1 30 seq = get_min_timeSpan(seq) # converting to the minimum time-span format
csong@1 31
csong@1 32 # checking whether the given L_max is enough to analyse the given sequence, if not, request a bigger L_max
csong@1 33 new_L_max = True
csong@1 34 matching_level = L_max
csong@1 35 while matching_level >= 0:
csong@1 36 if len(get_H(weight_seq,subdivision_seq, matching_level)) == len(seq):
csong@1 37 new_L_max = False
csong@1 38 break
csong@1 39 else:
csong@1 40 matching_level = matching_level - 1
csong@1 41
csong@1 42 if new_L_max == True:
csong@1 43 print 'Error: needs a bigger L_max (i.e. the lowest metrical level) to match the given rhythm sequence.'
csong@0 44
csong@0 45 else:
csong@1 46 # generate the metrical weights of the lowest level,
csong@1 47 # using the last matching_level number of elements in the weight_seq list, to make sure the last element is 1
csong@1 48 H = get_H (weight_seq[-(matching_level+1):], subdivision_seq, matching_level)
csong@0 49
csong@1 50 metricity = get_metricity(ceiling(seq), H) # converting to binary sequence then calculate metricity
csong@1 51 max_metricity = get_max_metricity(ceiling(seq), H)
csong@0 52
csong@1 53 syncopation = max_metricity - metricity
csong@1 54 return syncopation
csong@0 55