Mercurial > hg > syncopation-dataset
comparison Syncopation models/basic_functions.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 |
comparison
equal
deleted
inserted
replaced
21:b6daddeefda9 | 22:2dbc09ca8013 |
---|---|
77 for odd in range(3, int(math.sqrt(number) + 1), 2): | 77 for odd in range(3, int(math.sqrt(number) + 1), 2): |
78 if number % odd == 0: | 78 if number % odd == 0: |
79 isPrime = False | 79 isPrime = False |
80 return isPrime | 80 return isPrime |
81 | 81 |
82 # The min_timeSpan function searches for the shortest possible time-span representation for a sequence. | 82 # convert a velocity sequence to its minimum time-span representation |
83 def get_min_timeSpan(seq): | 83 def velocity_sequence_to_min_timetpan(velocitySequence): |
84 minTimeSpan = [1] | 84 minTimeSpanVelocitySeq = [1] |
85 for d in find_divisor(len(seq)): | 85 for divisors in find_divisor(len(velocitySequence)): |
86 segments = subdivide(seq,d) | 86 segments = subdivide(velocitySequence,divisors) |
87 if len(segments)!=0: | 87 if len(segments)!=0: |
88 del minTimeSpan[:] | 88 del minTimeSpanSequence[:] |
89 for s in segments: | 89 for s in segments: |
90 minTimeSpan.append(s[0]) | 90 minTimeSpanVelocitySeq.append(s[0]) |
91 if sum(minTimeSpan) == sum(seq): | 91 if sum(minTimeSpanVelocitySeq) == sum(velocitySequence): |
92 break | 92 break |
93 return minTimeSpan | 93 return minTimeSpanVelocitySeq |
94 | 94 |
95 # get_note_indices returns all the indices of all the notes in this sequence | 95 # convert a note sequence to its minimum time-span representation |
96 def get_note_indices(sequence): | 96 def note_sequence_to_min_timespan(noteSequence, barTicks): |
97 barBinaryArray = [0]*barTicks | |
98 for note in noteSequence: | |
99 # mark note_on event (i.e. startTime) and note_off event (i.e. endTime = startTime + duration) as 1 in the barBinaryArray | |
100 barBinaryArray[note[0]] = 1 | |
101 barBinaryArray[note[0]+note[1]] = 1 | |
102 | |
103 # convert the barBinaryArray to its minimum time-span representation | |
104 minBarBinaryArray = velocitySequence_to_min_timeSpan(barBinaryArray) | |
105 delta_t = len(barBinaryArray)/len(minBarBinaryArray) | |
106 | |
107 # scale the startTime and duration of each note by delta_t | |
108 for note in noteSequence: | |
109 note[0] = note[0]/delta_t | |
110 note[1] = note[1]/delta_t | |
111 | |
112 return noteSequence | |
113 | |
114 | |
115 | |
116 # get_note_indices returns all the indices of all the notes in this velocity_sequence | |
117 def get_note_indices(velocitySequence): | |
97 noteIndices = [] | 118 noteIndices = [] |
98 | 119 |
99 for index in range(len(sequence)): | 120 for index in range(len(velocitySequence)): |
100 if sequence[index] != 0: | 121 if velocitySequence[index] != 0: |
101 noteIndices.append(index) | 122 noteIndices.append(index) |
102 | 123 |
103 return noteIndices | 124 return noteIndices |
125 | |
104 | 126 |
105 # The get_H returns a sequence of metrical weight for a certain metrical level (horizontal), | 127 # The get_H returns a sequence of metrical weight for a certain metrical level (horizontal), |
106 # given the sequence of metrical weights in a hierarchy (vertical) and a sequence of subdivisions. | 128 # given the sequence of metrical weights in a hierarchy (vertical) and a sequence of subdivisions. |
107 def get_H(weightSequence,subdivisionSequence, level): | 129 def get_H(weightSequence,subdivisionSequence, level): |
108 H = [] | 130 H = [] |
116 H = concatenate(H, concatenate([h], repeat([weightSequence[level]],subdivisionSequence[level]-1))) | 138 H = concatenate(H, concatenate([h], repeat([weightSequence[level]],subdivisionSequence[level]-1))) |
117 else: | 139 else: |
118 print 'Error: a subdivision factor or metrical weight is not defined for the request metrical level.' | 140 print 'Error: a subdivision factor or metrical weight is not defined for the request metrical level.' |
119 return H | 141 return H |
120 | 142 |
121 def calculate_time_span_ticks(numerator, denominator, ticksPerQuarter): | 143 |
144 def calculate_bar_ticks(numerator, denominator, ticksPerQuarter): | |
122 return (numerator * ticksPerQuarter *4) / denominator | 145 return (numerator * ticksPerQuarter *4) / denominator |
146 | |
147 | |
148 def get_rhythm_category(velocitySequence, subdivisionSequence): | |
149 ''' | |
150 The get_rhythm_category function is used to detect rhythm category: monorhythm or polyrhythm. | |
151 For monorhythms, all prime factors of the length of minimum time-span representation of this sequence are | |
152 elements of its subdivision_seq, otherwise it is polyrhythm; | |
153 e.g. prime_factors of polyrhythm 100100101010 in 4/4 is [2,3] but subdivision_seq = [1,2,2] for 4/4 | |
154 ''' | |
155 rhythmCategory = 'mono' | |
156 for f in find_prime_factors(len(get_min_timeSpan(velocitySequence))): | |
157 if not (f in subdivisionSequence): | |
158 rhythmCategory = 'poly' | |
159 break | |
160 return rhythmCategory | |
161 | |
162 | |
163 def string_to_sequence(inputString): | |
164 return map(int, inputString.split(',')) | |
123 | 165 |
124 # # The get_subdivision_seq function returns the subdivision sequence of several common time-signatures defined by GTTM, | 166 # # The get_subdivision_seq function returns the subdivision sequence of several common time-signatures defined by GTTM, |
125 # # or ask for the top three level of subdivision_seq manually set by the user. | 167 # # or ask for the top three level of subdivision_seq manually set by the user. |
126 # def get_subdivision_seq(timesig, L_max): | 168 # def get_subdivision_seq(timesig, L_max): |
127 # subdivision_seq = [] | 169 # subdivision_seq = [] |
154 # subdivision_seq = subdivision_seq[0:L_max+1] | 196 # subdivision_seq = subdivision_seq[0:L_max+1] |
155 | 197 |
156 # return subdivision_seq | 198 # return subdivision_seq |
157 | 199 |
158 | 200 |
159 def get_rhythm_category(velocitySequence, subdivisionSequence): | |
160 ''' | |
161 The get_rhythm_category function is used to detect rhythm category: monorhythm or polyrhythm. | |
162 For monorhythms, all prime factors of the length of minimum time-span representation of this sequence are | |
163 elements of its subdivision_seq, otherwise it is polyrhythm; | |
164 e.g. prime_factors of polyrhythm 100100101010 in 4/4 is [2,3] but subdivision_seq = [1,2,2] for 4/4 | |
165 ''' | |
166 rhythmCategory = 'mono' | |
167 for f in find_prime_factors(len(get_min_timeSpan(velocitySequence))): | |
168 if not (f in subdivisionSequence): | |
169 rhythmCategory = 'poly' | |
170 break | |
171 return rhythmCategory | |
172 | |
173 def string_to_sequence(inputString): | |
174 return map(int, inputString.split(',')) | |
175 | |
176 | |
177 # The split_by_bar function seperates the score representation of rhythm by bar lines, | 201 # The split_by_bar function seperates the score representation of rhythm by bar lines, |
178 # resulting in a list representingbar-by-bar rhythm sequence, | 202 # resulting in a list representingbar-by-bar rhythm sequence, |
179 # e.g. rhythm = ['|',[ts1,td1,v1], [ts2,td2,v2], '|',[ts3,td3,v3],'|'...] | 203 # e.g. rhythm = ['|',[ts1,td1,v1], [ts2,td2,v2], '|',[ts3,td3,v3],'|'...] |
180 # rhythm_bybar = [ [ [ts1,td1,v1], [ts2,td2,v2] ], [ [ts3,td3,v3] ], [...]] | 204 # rhythm_bybar = [ [ [ts1,td1,v1], [ts2,td2,v2] ], [ [ts3,td3,v3] ], [...]] |
181 # def split_by_bar(rhythm): | 205 # def split_by_bar(rhythm): |