christopher@45: ''' christopher@45: Author: Chunyang Song christopher@45: Institution: Centre for Digital Music, Queen Mary University of London christopher@45: ''' christopher@45: christopher@45: # Set the parameters: time-signature, subdivision-sequence, strong-beat-level; Lmax; weight-sequence christopher@45: # Important condition: Lmax needs to be no less than the length of subdivision-sequence and the length of weight-sequence christopher@45: christopher@45: christopher@45: # {'key': time-signature} : christopher@45: # {'value': [subdivision-sequence, theoretical beat-level represented by index in the subdivision-sequence list]} christopher@45: timeSignatureBase = { christopher@45: '2/2': [[1,2,2,2,2,2],1], christopher@45: '3/2': [[1,3,2,2,2,2],1], christopher@45: '4/2': [[1,2,2,2,2,2],1], christopher@45: '2/4': [[1,2,2,2,2,2],1], christopher@45: '3/4': [[1,3,2,2,2,2],1], christopher@45: '4/4': [[1,2,2,2,2,2],2], christopher@45: '5/4': [[1,5,2,2,2,2],1], christopher@45: '7/4': [[1,7,2,2,2,2],1], christopher@45: '3/8': [[1,3,2,2,2,2],1], christopher@45: '5/8': [[1,5,2,2,2,2],1], christopher@45: '6/8': [[1,2,3,2,2,2],1], christopher@45: '9/8': [[1,3,3,2,2,2],1], christopher@45: '12/8':[[1,2,2,3,2,2],2], christopher@45: } christopher@45: christopher@45: christopher@45: def add_time_signature(timeSignature, subdivisionSequence, beatLevel): christopher@45: if is_time_signature_valid(timeSignature,subdivisionSequence,beatLevel): christopher@45: if timeSignature in timesigBase: christopher@45: print 'This time-signature is existed already.' christopher@45: else: christopher@45: timeSignatureBase[timeSignature] = [subdivisionSequence, beatLevel] christopher@45: write_time_signature() christopher@45: christopher@45: def update_time_signature(timeSignature, subdivisionSequence, beatLevel): christopher@45: if is_time_signature_valid(timeSignature,subdivisionSequence,beatLevel): christopher@45: if timeSignature in timeSignatureBase: christopher@45: print 'Original settings for ', timeSignature, ':',timeSignatureBase[timeSignature] christopher@45: timeSignatureBase[timeSignature] = [subdivisionSequence, beatLevel] christopher@45: print 'Changed into:',timeSignatureBase[timeSignature] christopher@45: write_time_signature() christopher@45: christopher@45: def is_time_signature_valid(timeSignature, subdivisionSequence, beatLevel): christopher@45: isValid = False christopher@45: if ('/' not in timeSignature) or (not timeSignature.split('/')[0].isdigit()) or (not timeSignature.split('/')[1].isdigit()): christopher@45: print 'Error: invalid time-signature. Please indicate in the form of fraction, e.g. 4/4, 6/8 or 3/4.' christopher@45: elif subdivisionSequence != [s for s in subdivisionSequence if isinstance(s,int)]: christopher@45: print 'Error: invalid subdivision sequence. Please indicate in the form of list of numbers, e.g [1,2,2,2,2].' christopher@45: elif beatLevel >= len(subdivisionSequence): christopher@45: print 'Error: beat-level exceeds the range of subdivision sequence list.' christopher@45: else: christopher@45: isValid = True christopher@45: return isValid christopher@45: christopher@45: def write_time_signature(): christopher@45: import cPickle as pickle christopher@45: timeSigFile = open('TimeSignature.pkl', 'wb') christopher@45: pickle.dump(timeSignatureBase, timeSigFile) christopher@45: timeSigFile.close() christopher@45: christopher@45: def read_time_signature(): christopher@45: import cPickle as pickle christopher@45: timeSigFile = open('TimeSignature.pkl','rb') christopher@45: data = pickle.load(timeSigFile) christopher@45: return data christopher@45: timeSigFile.close() christopher@45: christopher@45: def print_time_signature_base(): christopher@45: data = read_time_signature() christopher@45: for timeSignature, settings in data.items(): christopher@45: print timeSignature, settings christopher@45: christopher@45: christopher@45: def are_parameters_valid(Lmax, weightSequence, subdivisionSequence): christopher@45: christopher@45: # is_Lmax_valid() checks: christopher@45: # 1. if Lmax is a non-negative integer christopher@45: # 2. if Lmax is higher than the length of weightSequence and subdivisionSequence christopher@45: def is_Lmax_valid(): christopher@45: isValid = False christopher@45: if isinstance(Lmax,int) and Lmax > 0: christopher@45: if Lmax <= len(subdivisionSequence)-1: christopher@45: if Lmax <= len(weightSequence)-1: christopher@45: isValid = True christopher@45: else: christopher@45: print 'Error: Lmax exceeds the length of weight-sequence. Either reduce Lmax, or provide a new weight-sequence whose length is greater or equal to Lmax.' christopher@45: else: christopher@45: print 'Error: Lmax exceeds the length of subdivision-sequence. Either reduce Lmax, or extend subdivision-sequence through updating time-signature (refer to update_time_signature function).' christopher@45: else: christopher@45: print 'Error: Lmax needs to be a positive integer.' christopher@45: return isValid christopher@45: christopher@45: # is_weight_sequence_valid() checks: christopher@45: # 1. weightSequence is a list of numbers christopher@45: # 2. the length of weightSequence is no less than Lmax christopher@45: def is_weight_sequence_valid(): christopher@45: isValid = False christopher@45: if isinstance(weightSequence,list) and weightSequence == [i for i in weightSequence if isinstance(i,int)]: christopher@45: if len(weightSequence) >= Lmax: christopher@45: isValid = True christopher@45: else: christopher@45: print 'Error: the length of weight-sequence needs to be greater or equal to Lmax.' christopher@45: else: christopher@45: print 'Error: the weight-sequence needs to be a list of integers.' christopher@45: return isValid christopher@45: christopher@45: christopher@45: if is_weight_sequence_valid() and is_Lmax_valid(): christopher@45: return True christopher@45: else: christopher@45: return False