annotate synpy/KTH.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
christopher@45 7 from basic_functions import get_note_indices, repeat, velocity_sequence_to_min_timespan
christopher@45 8
christopher@45 9 # To find the nearest power of 2 equal to or less than the given number
christopher@45 10 def round_down_power_2(number):
christopher@45 11 i = 0
christopher@45 12 if number > 0:
christopher@45 13 while pow(2,i) > number or number >= pow(2,i+1):
christopher@45 14 i = i+1
christopher@45 15 power2 = pow(2,i)
christopher@45 16 else:
christopher@45 17 print 'Error: numbers that are less than 1 cannot be rounded down to its nearest power of two.'
christopher@45 18 power2 = None
christopher@45 19 return power2
christopher@45 20
christopher@45 21 # To find the nearest power of 2 equal to or more than the given number
christopher@45 22 def round_up_power_2(number):
christopher@45 23 i = 0
christopher@45 24 while pow(2,i) < number:
christopher@45 25 i = i + 1
christopher@45 26 return pow(2,i)
christopher@45 27
christopher@45 28 # To examine whether start_time is 'off-beat'
christopher@45 29 def start_time_offbeat_measure(startTime, c_n):
christopher@45 30 measure = 0
christopher@45 31 if startTime % c_n != 0:
christopher@45 32 measure = 2
christopher@45 33 return measure
christopher@45 34
christopher@45 35 # To examine whether end_time is 'off-beat'
christopher@45 36 def end_time_offbeat_measure(endTime, c_n):
christopher@45 37 measure = 0
christopher@45 38 if endTime % c_n != 0:
christopher@45 39 measure = 1
christopher@45 40 return measure
christopher@45 41
christopher@45 42 def get_syncopation(bar, parameters = None):
christopher@45 43 syncopation = None
christopher@45 44
christopher@45 45 # KTH only deals with simple-duple meter where the number of beats per bar is a power of two.
christopher@45 46 numerator = bar.get_time_signature().get_numerator()
christopher@45 47 if numerator != round_down_power_2(numerator):
christopher@45 48 print 'Warning: KTH model detects non simple-duple meter so returning None.'
christopher@45 49 else:
christopher@45 50 # retrieve note-sequence and next bar's note-sequence
christopher@45 51 noteSequence = bar.get_note_sequence()
christopher@45 52 #for note in noteSequence:
christopher@45 53 # print note.to_string()
christopher@45 54 #print 'barlength',bar.get_bar_ticks()
christopher@45 55
christopher@45 56 nextbarNoteSequence = None
christopher@45 57 if bar.get_next_bar() != None:
christopher@45 58 nextbarNoteSequence = bar.get_next_bar().get_note_sequence()
christopher@45 59
christopher@45 60 # convert note sequence to its minimum time-span representation so that the later calculation can be faster
christopher@45 61 # noteSequence = note_sequence_to_min_timespan(noteSequence)
christopher@45 62 # find delta_t
christopher@45 63 Tmin = len(velocity_sequence_to_min_timespan(bar.get_velocity_sequence()))
christopher@45 64 #print 'Tmin',Tmin
christopher@45 65 T = round_up_power_2(Tmin)
christopher@45 66 #print 'T',T
christopher@45 67 deltaT = float(bar.get_bar_ticks())/T
christopher@45 68 #print 'delta',deltaT
christopher@45 69
christopher@45 70
christopher@45 71 # calculate syncopation note by note
christopher@45 72 syncopation = 0
christopher@45 73
christopher@45 74 for note in noteSequence:
christopher@45 75 c_n = round_down_power_2(note.duration/deltaT)
christopher@45 76 #print 'd', note.duration
christopher@45 77 #print 'c_n', c_n
christopher@45 78 endTime = note.startTime + note.duration
christopher@45 79 #print float(note.startTime)/deltaT, float(endTime)/deltaT
christopher@45 80 syncopation = syncopation + start_time_offbeat_measure(float(note.startTime)/deltaT,c_n) + end_time_offbeat_measure(float(endTime)/deltaT,c_n)
christopher@45 81
christopher@45 82
christopher@45 83 return syncopation
christopher@45 84
christopher@45 85 # # To calculate syncopation value of the sequence in the given time-signature.
christopher@45 86 # def get_syncopation(seq, timesig, postbar_seq):
christopher@45 87 # syncopation = 0
christopher@45 88
christopher@45 89 # numerator = int(timesig.split("/")[0])
christopher@45 90 # if numerator == round_down_power_2(numerator): # if is a binary time-signature
christopher@45 91 # # converting to minimum time-span format
christopher@45 92 # seq = get_min_timeSpan(seq)
christopher@45 93 # if postbar_seq != None:
christopher@45 94 # postbar_seq = get_min_timeSpan(postbar_seq)
christopher@45 95
christopher@45 96 # # sf is a stretching factor matching rhythm sequence and meter, as Keith defines the note duration as a multiple of 1/(2^d) beats where d is number of metrical level
christopher@45 97 # sf = round_up_power_2(len(seq))
christopher@45 98
christopher@45 99 # # retrieve all the indices of all the notes in this sequence
christopher@45 100 # note_indices = get_note_indices(seq)
christopher@45 101
christopher@45 102 # for i in range(len(note_indices)):
christopher@45 103 # # Assuming start_time is the index of this note, end_time is the index of the following note
christopher@45 104 # start_time = note_indices[i]*sf/float(len(seq))
christopher@45 105
christopher@45 106 # if i == len(note_indices)-1: # if this is the last note, end_time is the index of the following note in the next bar
christopher@45 107 # if postbar_seq != None and postbar_seq != repeat([0],len(postbar_seq)):
christopher@45 108 # next_index = get_note_indices(postbar_seq)[0]+len(seq)
christopher@45 109 # end_time = next_index*sf/float(len(seq))
christopher@45 110 # else: # or if the next bar is none or full rest, end_time is the end of this sequence.
christopher@45 111 # end_time = sf
christopher@45 112 # else:
christopher@45 113 # end_time = note_indices[i+1]*sf/float(len(seq))
christopher@45 114
christopher@45 115 # duration = end_time - start_time
christopher@45 116 # c_n = round_down_power_2(duration)
christopher@45 117 # syncopation = syncopation + start(start_time,c_n) + end(end_time,c_n)
christopher@45 118 # else:
christopher@45 119 # print 'Error: KTH model can only deal with binary time-signature, e.g. 2/4 and 4/4. '
christopher@45 120 # syncopation = None
christopher@45 121
christopher@45 122 # return syncopation