Mercurial > hg > syncopation-dataset
view Syncopation models/KTH.py @ 22:2dbc09ca8013
Refactored KTH, not tested yet. Added conversion functions between note sequence and velocity sequence, and tostring functions. Renamed get_min_timeSpan into velocity_sequence_to_min_timetpan, so need to refactor that.
author | Chunyang Song <csong@eecs.qmul.ac.uk> |
---|---|
date | Thu, 09 Apr 2015 23:49:16 +0100 |
parents | b6daddeefda9 |
children | df1e7c378ee0 |
line wrap: on
line source
''' Author: Chunyang Song Institution: Centre for Digital Music, Queen Mary University of London ''' from basic_functions import get_note_indices, repeat, note_sequence_to_min_timespan # To find the nearest power of 2 equal to or less than the given number def round_down_power_2(number): i = 0 if number > 0: while pow(2,i) > number or number >= pow(2,i+1): i = i+1 power2 = pow(2,i) else: print 'Error: numbers that are less than 1 cannot be rounded down to its nearest power of two.' power2 = None return power2 # To find the nearest power of 2 equal to or more than the given number def round_up_power_2(number): i = 0 while pow(2,i) < number: i = i + 1 return pow(2,i) # To examine whether start_time is 'off-beat' def start_time_offbeat_measure(startTime, c_n): measure = 0 if startTime % c_n != 0: measure = 2 return measure # To examine whether end_time is 'off-beat' def end_time_offbeat_measure(endTime, c_n): measure = 0 if endTime % c_n != 0: measure = 1 return measure def get_syncopation(bar, parameters = None): syncopation = None # KTH only deals with simple-duple meter where the number of beats per bar is a power of two. numerator = bar.get_time_signature().get_numerator() if numerator != round_down_power_2(numerator): print 'Warning: KTH model detects non simple-duple meter so returning None.' else: # retrieve note-sequence and next bar's note-sequence noteSequence = bar.get_note_sequence() nextbarNoteSequence = None if bar.get_next_bar() != None: nextbarNoteSequence = bar.get_next_bar().get_note_sequence() # convert note sequence to its minimum time-span representation so that the later calculation can be faster noteSequence = note_sequence_to_min_timespan(noteSequence) # calculate syncopation note by note syncopation = 0 for note in noteSequence: startTime = note[0] duration = note[1] endTime = startTime + duration c_n = round_down_power_2(duration) syncopation = syncopation + start_time_offbeat_measure(startTime,c_n) + end_time_offbeat_measure(endTime,c_n) # # To calculate syncopation value of the sequence in the given time-signature. # def get_syncopation(seq, timesig, postbar_seq): # syncopation = 0 # numerator = int(timesig.split("/")[0]) # if numerator == round_down_power_2(numerator): # if is a binary time-signature # # converting to minimum time-span format # seq = get_min_timeSpan(seq) # if postbar_seq != None: # postbar_seq = get_min_timeSpan(postbar_seq) # # 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 # sf = round_up_power_2(len(seq)) # # retrieve all the indices of all the notes in this sequence # note_indices = get_note_indices(seq) # for i in range(len(note_indices)): # # Assuming start_time is the index of this note, end_time is the index of the following note # start_time = note_indices[i]*sf/float(len(seq)) # 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 # if postbar_seq != None and postbar_seq != repeat([0],len(postbar_seq)): # next_index = get_note_indices(postbar_seq)[0]+len(seq) # end_time = next_index*sf/float(len(seq)) # else: # or if the next bar is none or full rest, end_time is the end of this sequence. # end_time = sf # else: # end_time = note_indices[i+1]*sf/float(len(seq)) # duration = end_time - start_time # c_n = round_down_power_2(duration) # syncopation = syncopation + start(start_time,c_n) + end(end_time,c_n) # else: # print 'Error: KTH model can only deal with binary time-signature, e.g. 2/4 and 4/4. ' # syncopation = None # return syncopation