Mercurial > hg > syncopation-dataset
view Syncopation models/PRS.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 | cc38b3047ed9 |
line wrap: on
line source
''' Author: Chunyang Song Institution: Centre for Digital Music, Queen Mary University of London ''' from basic_functions import repeat, subdivide, ceiling, velocity_sequence_to_min_timespan, get_rhythm_category def get_cost(sequence,nextSequence): sequence = velocity_sequence_to_min_timespan(sequence) # converting to the minimum time-span format if sequence[1:] == repeat([0],len(sequence)-1): # null prototype cost = 0 elif sequence == repeat([1],len(sequence)): # filled prototype cost = 1 elif sequence[0] == 1 and sequence[-1] == 0: # run1 prototype cost = 2 elif sequence[0] == 1 and (nextSequence == None or nextSequence[0] == 0): # run2 prototype cost = 2 elif sequence[-1] == 1 and nextSequence != None and nextSequence[0] == 1: # upbeat prototype cost = 3 elif sequence[0] == 0: # syncopated prototype cost = 5 return cost # This function calculates the syncopation value (cost) for the sequence with the postbar_seq for a certain level. def syncopation_perlevel(subSequences): print 'subSequences', subSequences total = 0 for l in range(len(subSequences)-1): print 'cost', get_cost(subSequences[l], subSequences[l+1]) total = total + get_cost(subSequences[l], subSequences[l+1]) print 'total this level', total normalised = float(total)/(len(subSequences)-1) return normalised def get_syncopation(bar, parameters = None): syncopation = None binarySequence = bar.get_binary_sequence() subdivisionSequence = bar.get_subdivision_sequence() # PRS does not handle polyrhythms if get_rhythm_category(binarySequence, subdivisionSequence) == 'poly': print 'Warning: PRS model detects polyrhythms so returning None.' else: syncopation = 0 # retrieve the binary sequence in the next bar if bar.get_next_bar() != None: nextbarBinarySequence = bar.get_next_bar().get_binary_sequence() else: nextbarBinarySequence = None # numberOfSubSeqs is the number of sub-sequences at a certain metrical level, initialised to be 1 (at the bar level) numberOfSubSeqs = 1 for subdivisor in subdivisionSequence: # numberOfSubSeqs is product of all the subdivisors up to the current level numberOfSubSeqs = numberOfSubSeqs * subdivisor # recursion stops when the length of sub-sequence is less than 2 if len(binarySequence)/numberOfSubSeqs >= 2: # generate sub-sequences and append the next bar sequence subSequences = subdivide(ceiling(binarySequence), numberOfSubSeqs) subSequences.append(nextbarBinarySequence) # adding syncopation at each metrical level to the total syncopation #print 'per level', syncopation_perlevel(subSequences) syncopation += syncopation_perlevel(subSequences) else: break return syncopation