# HG changeset patch # User csong # Date 1428444973 -3600 # Node ID b6daddeefda95ede046707422b9a1784215165f5 # Parent b959c2acb927f38c2beff9a5da6864c767086d95 working on KTH diff -r b959c2acb927 -r b6daddeefda9 Syncopation models/KTH.py --- a/Syncopation models/KTH.py Tue Apr 07 19:05:07 2015 +0100 +++ b/Syncopation models/KTH.py Tue Apr 07 23:16:13 2015 +0100 @@ -3,7 +3,6 @@ Institution: Centre for Digital Music, Queen Mary University of London ''' -## Problems! Note indices, post bar from basic_functions import get_min_timeSpan, get_note_indices, repeat @@ -40,42 +39,61 @@ s = 1 return s -# To calculate syncopation value of the sequence in the given time-signature. -#def get_syncopation(seq, timesig, postbar_seq): -def get_syncopation(bar, parameter = None): - syncopation = 0 +def get_syncopation(bar, parameters): + syncopation = None - 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) + # 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() - # 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)) + # find the delta_t so that the time-span (in ticks) is minimized and the note durations are represented by possible smallest numbers + # delta_t is the greatest common divisor of all the note durations + + + + +# # 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) +# # 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)) +# 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)) +# 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 +# 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 +# return syncopation diff -r b959c2acb927 -r b6daddeefda9 Syncopation models/basic_functions.py --- a/Syncopation models/basic_functions.py Tue Apr 07 19:05:07 2015 +0100 +++ b/Syncopation models/basic_functions.py Tue Apr 07 23:16:13 2015 +0100 @@ -118,6 +118,9 @@ print 'Error: a subdivision factor or metrical weight is not defined for the request metrical level.' return H +def calculate_time_span_ticks(numerator, denominator, ticksPerQuarter): + return (numerator * ticksPerQuarter *4) / denominator + # # The get_subdivision_seq function returns the subdivision sequence of several common time-signatures defined by GTTM, # # or ask for the top three level of subdivision_seq manually set by the user. # def get_subdivision_seq(timesig, L_max): diff -r b959c2acb927 -r b6daddeefda9 Syncopation models/music_objects.py --- a/Syncopation models/music_objects.py Tue Apr 07 19:05:07 2015 +0100 +++ b/Syncopation models/music_objects.py Tue Apr 07 23:16:13 2015 +0100 @@ -1,5 +1,5 @@ -from basic_functions import ceiling, string_to_sequence +from basic_functions import ceiling, string_to_sequence, calculate_time_span_ticks import parameter_setter import rhythm_parser @@ -68,13 +68,13 @@ self.prevBar = prevBar def get_note_sequence(self): - #if self.noteSequence==None: - # self.noteSequence = velocity_sequence_to_notes(self.velocitySequence) + if self.noteSequence==None: + self.noteSequence = velocity_sequence_to_notes(self.velocitySequence) return self.noteSequence def get_velocity_sequence(self): if self.velocitySequence==None: - self.velocitySequence = note_sequence_to_velocities(self.velocitySequence) + self.velocitySequence = note_sequence_to_velocities(self.noteSequence) return self.velocitySequence def get_binary_sequence(self): @@ -101,9 +101,9 @@ def get_time_signature(self): return self.timeSignature - def get_t_span(self): - # return the length of a bar in time units - return None # NEED TO IMPLEMENT + # return the length of a bar in time units (ticks) + def get_time_span(self): + return calculate_time_span_ticks(self.timeSignature.get_numerator(),self.timeSignature.get_denominator(), self.ticksPerQuarter) class TimeSignature(): def __init__(self, inputString): diff -r b959c2acb927 -r b6daddeefda9 Syncopation models/syncopation.py --- a/Syncopation models/syncopation.py Tue Apr 07 19:05:07 2015 +0100 +++ b/Syncopation models/syncopation.py Tue Apr 07 23:16:13 2015 +0100 @@ -4,73 +4,77 @@ ''' +def sync_perbar_permodel (model, bar, parameters): + return model.get_syncopation(bar, parameters) -def sync_perbar_permodel(seq, model, timesig = None, subdivision_seq = None, weight_seq = None, L_max = 5, prebar_seq = None, postbar_seq = None, strong_beat_level = None): - syncopation = None +# def syncopation_barlist_permodel(model, barlist, parameters): - if seq == None or model == None: - print 'Error: please indicate rhythm sequence and syncopation model.' +# def sync_perbar_permodel(seq, model, timesig = None, subdivision_seq = None, weight_seq = None, L_max = 5, prebar_seq = None, postbar_seq = None, strong_beat_level = None): +# syncopation = None - elif timesig == None and subdivision_seq == None: - print 'Error: please indicate either time signature or subdivision sequence.' +# if seq == None or model == None: +# print 'Error: please indicate rhythm sequence and syncopation model.' + +# elif timesig == None and subdivision_seq == None: +# print 'Error: please indicate either time signature or subdivision sequence.' - else: - while subdivision_seq == None: - from basic_functions import get_subdivision_seq - subdivision_seq = get_subdivision_seq(timesig, L_max) +# else: +# while subdivision_seq == None: +# from basic_functions import get_subdivision_seq +# subdivision_seq = get_subdivision_seq(timesig, L_max) - # The get_rhythm_category function is used to detect rhythm category: monorhythm or polyrhythm. - # For monorhythms, all prime factors of the length of minimum time-span representation of this sequence are - # elements of its subdivision_seq, otherwise it is polyrhythm; - # e.g. prime_factors of polyrhythm 100100101010 in 4/4 is [2,3] but subdivision_seq = [1,2,2] for 4/4 - def get_rhythm_category(): - rhythm_category = 'mono' - from basic_functions import get_min_timeSpan, find_prime_factors - for f in find_prime_factors(len(get_min_timeSpan(seq))): - if not (f in subdivision_seq): - rhythm_category = 'poly' - break - return rhythm_category +# # The get_rhythm_category function is used to detect rhythm category: monorhythm or polyrhythm. +# # For monorhythms, all prime factors of the length of minimum time-span representation of this sequence are +# # elements of its subdivision_seq, otherwise it is polyrhythm; +# # e.g. prime_factors of polyrhythm 100100101010 in 4/4 is [2,3] but subdivision_seq = [1,2,2] for 4/4 +# def get_rhythm_category(): +# rhythm_category = 'mono' +# from basic_functions import get_min_timeSpan, find_prime_factors +# for f in find_prime_factors(len(get_min_timeSpan(seq))): +# if not (f in subdivision_seq): +# rhythm_category = 'poly' +# break +# return rhythm_category - rhythm_category = get_rhythm_category() +# rhythm_category = get_rhythm_category() - if model == 'LHL': - import LHL - if weight_seq == None: - weight_seq = range(0,-L_max,-1) - syncopation = LHL.get_syncopation(seq, subdivision_seq, weight_seq, prebar_seq, rhythm_category) - elif model == 'PRS': - import PRS - syncopation = PRS.get_syncopation(seq, subdivision_seq, postbar_seq, rhythm_category) - elif model == 'TMC': - import TMC - if weight_seq == None: - weight_seq = range(L_max+1,0,-1) - syncopation = TMC.get_syncopation(seq, subdivision_seq, weight_seq, L_max, rhythm_category) - elif model == 'SG': - import SG - if weight_seq == None: - weight_seq = range(L_max+1) - syncopation = SG.get_syncopation(seq, subdivision_seq, weight_seq, L_max, rhythm_category) - elif model == 'KTH': - import KTH - syncopation = KTH.get_syncopation(seq, timesig, postbar_seq) - elif model == 'TOB': - import TOB - syncopation = TOB.get_syncopation(seq) - elif model == 'WNBD': - import WNBD - if strong_beat_level == None: - if timesig == '4/4': - strong_beat_level = 2 - else: - strong_beat_level = 1 - syncopation = WNBD.get_syncopation(seq, subdivision_seq, strong_beat_level, postbar_seq) +# if model == 'LHL': +# import LHL +# if weight_seq == None: +# weight_seq = range(0,-L_max,-1) +# syncopation = LHL.get_syncopation(seq, subdivision_seq, weight_seq, prebar_seq, rhythm_category) +# elif model == 'PRS': +# import PRS +# syncopation = PRS.get_syncopation(seq, subdivision_seq, postbar_seq, rhythm_category) +# elif model == 'TMC': +# import TMC +# if weight_seq == None: +# weight_seq = range(L_max+1,0,-1) +# syncopation = TMC.get_syncopation(seq, subdivision_seq, weight_seq, L_max, rhythm_category) +# elif model == 'SG': +# import SG +# if weight_seq == None: +# weight_seq = range(L_max+1) +# syncopation = SG.get_syncopation(seq, subdivision_seq, weight_seq, L_max, rhythm_category) +# elif model == 'KTH': +# import KTH +# syncopation = KTH.get_syncopation(seq, timesig, postbar_seq) +# elif model == 'TOB': +# import TOB +# syncopation = TOB.get_syncopation(seq) +# elif model == 'WNBD': +# import WNBD +# if strong_beat_level == None: +# if timesig == '4/4': +# strong_beat_level = 2 +# else: +# strong_beat_level = 1 +# syncopation = WNBD.get_syncopation(seq, subdivision_seq, strong_beat_level, postbar_seq) - else: - print 'Error: undefined syncopation model.' +# else: +# print 'Error: undefined syncopation model.' - return syncopation +# return syncopation # def syncopation_all(rhythm, model, timesig, subdivision_seq = None, weight_seq = None, L_max = 5, strong_beat_level = None): # syncopation = 0