annotate synpy/PRS.py @ 76:90b68f259541 tip

updated parameter_setter to be able to find the TimeSignature.pkl file without putting it in the pwd
author christopherh <christopher.harte@eecs.qmul.ac.uk>
date Wed, 13 May 2015 09:27:36 +0100
parents ef891481231e
children
rev   line source
christopher@45 1 '''
christopher@45 2 Author: Chunyang Song
christopher@45 3 Institution: Centre for Digital Music, Queen Mary University of London
christopher@45 4 '''
christopher@45 5
christopher@45 6 from basic_functions import repeat, subdivide, ceiling, velocity_sequence_to_min_timespan, get_rhythm_category
christopher@45 7
christopher@45 8 def get_cost(sequence,nextSequence):
christopher@45 9 sequence = velocity_sequence_to_min_timespan(sequence) # converting to the minimum time-span format
christopher@45 10
christopher@45 11 if sequence[1:] == repeat([0],len(sequence)-1): # null prototype
christopher@45 12 cost = 0
christopher@45 13 elif sequence == repeat([1],len(sequence)): # filled prototype
christopher@45 14 cost = 1
christopher@45 15 elif sequence[0] == 1 and sequence[-1] == 0: # run1 prototype
christopher@45 16 cost = 2
christopher@45 17 elif sequence[0] == 1 and (nextSequence == None or nextSequence[0] == 0): # run2 prototype
christopher@45 18 cost = 2
christopher@45 19 elif sequence[-1] == 1 and nextSequence != None and nextSequence[0] == 1: # upbeat prototype
christopher@45 20 cost = 3
christopher@45 21 elif sequence[0] == 0: # syncopated prototype
christopher@45 22 cost = 5
christopher@45 23
christopher@45 24 return cost
christopher@45 25
christopher@45 26 # This function calculates the syncopation value (cost) for the sequence with the postbar_seq for a certain level.
christopher@45 27 def syncopation_perlevel(subSequences):
christopher@45 28 #print 'subSequences', subSequences
christopher@45 29 total = 0
christopher@45 30 for l in range(len(subSequences)-1):
christopher@45 31 #print 'cost', get_cost(subSequences[l], subSequences[l+1])
christopher@45 32 total = total + get_cost(subSequences[l], subSequences[l+1])
christopher@45 33 #print 'total this level', total
christopher@45 34 normalised = float(total)/(len(subSequences)-1)
christopher@45 35
christopher@45 36 return normalised
christopher@45 37
christopher@45 38 def get_syncopation(bar, parameters = None):
christopher@45 39 syncopation = None
christopher@45 40
christopher@50 41 binarySequence = velocity_sequence_to_min_timespan(bar.get_binary_sequence())
christopher@45 42 subdivisionSequence = bar.get_subdivision_sequence()
christopher@45 43
christopher@45 44 # PRS does not handle polyrhythms
christopher@45 45 if get_rhythm_category(binarySequence, subdivisionSequence) == 'poly':
christopher@45 46 print 'Warning: PRS model detects polyrhythms so returning None.'
christopher@50 47 elif bar.is_empty():
christopher@50 48 print 'Warning: PRS model detects empty bar so returning None.'
christopher@45 49 else:
christopher@45 50 syncopation = 0
christopher@45 51
christopher@45 52 # retrieve the binary sequence in the next bar
christopher@45 53 if bar.get_next_bar() != None:
christopher@45 54 nextbarBinarySequence = bar.get_next_bar().get_binary_sequence()
christopher@45 55 else:
christopher@45 56 nextbarBinarySequence = None
christopher@45 57
christopher@45 58 # numberOfSubSeqs is the number of sub-sequences at a certain metrical level, initialised to be 1 (at the bar level)
christopher@45 59 numberOfSubSeqs = 1
christopher@45 60 for subdivisor in subdivisionSequence:
christopher@45 61 # numberOfSubSeqs is product of all the subdivisors up to the current level
christopher@45 62 numberOfSubSeqs = numberOfSubSeqs * subdivisor
christopher@45 63
christopher@45 64 # recursion stops when the length of sub-sequence is less than 2
christopher@45 65 if len(binarySequence)/numberOfSubSeqs >= 2:
christopher@45 66 # generate sub-sequences and append the next bar sequence
christopher@45 67 subSequences = subdivide(ceiling(binarySequence), numberOfSubSeqs)
christopher@45 68 subSequences.append(nextbarBinarySequence)
christopher@45 69 # adding syncopation at each metrical level to the total syncopation
christopher@45 70 #print 'per level', syncopation_perlevel(subSequences)
christopher@45 71 syncopation += syncopation_perlevel(subSequences)
christopher@45 72 else:
christopher@45 73 break
christopher@45 74
christopher@45 75 return syncopation