diff 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
line wrap: on
line diff
--- a/Syncopation models/basic_functions.py	Tue Apr 07 23:16:13 2015 +0100
+++ b/Syncopation models/basic_functions.py	Thu Apr 09 23:49:16 2015 +0100
@@ -79,29 +79,51 @@
 				isPrime = False
 	return isPrime
 
-# The min_timeSpan function searches for the shortest possible time-span representation for a sequence.
-def get_min_timeSpan(seq):
-	minTimeSpan = [1]
-	for d in find_divisor(len(seq)):
-		segments = subdivide(seq,d)
+# convert a velocity sequence to its minimum time-span representation
+def velocity_sequence_to_min_timetpan(velocitySequence):
+	minTimeSpanVelocitySeq = [1]
+	for divisors in find_divisor(len(velocitySequence)):
+		segments = subdivide(velocitySequence,divisors)
 		if len(segments)!=0:
-			del minTimeSpan[:]
+			del minTimeSpanSequence[:]
 			for s in segments:
-				minTimeSpan.append(s[0])
-			if sum(minTimeSpan) == sum(seq):
+				minTimeSpanVelocitySeq.append(s[0])
+			if sum(minTimeSpanVelocitySeq) == sum(velocitySequence):
 				break
-	return minTimeSpan
+	return minTimeSpanVelocitySeq
 
-# get_note_indices returns all the indices of all the notes in this sequence
-def get_note_indices(sequence):
+# convert a note sequence to its minimum time-span representation
+def note_sequence_to_min_timespan(noteSequence, barTicks):
+	barBinaryArray = [0]*barTicks
+	for note in noteSequence:
+		# mark note_on event (i.e. startTime) and note_off event (i.e. endTime = startTime + duration) as 1 in the barBinaryArray
+		barBinaryArray[note[0]] = 1
+		barBinaryArray[note[0]+note[1]] = 1
+
+	# convert the barBinaryArray to its minimum time-span representation
+	minBarBinaryArray = velocitySequence_to_min_timeSpan(barBinaryArray)
+	delta_t = len(barBinaryArray)/len(minBarBinaryArray)
+
+	# scale the startTime and duration of each note by delta_t
+	for note in noteSequence:
+		note[0] = note[0]/delta_t
+		note[1] = note[1]/delta_t
+
+	return noteSequence
+
+
+
+# get_note_indices returns all the indices of all the notes in this velocity_sequence
+def get_note_indices(velocitySequence):
 	noteIndices = []
 
-	for index in range(len(sequence)):
-		if sequence[index] != 0:
+	for index in range(len(velocitySequence)):
+		if velocitySequence[index] != 0:
 			noteIndices.append(index)
 
 	return noteIndices
 
+
 # The get_H returns a sequence of metrical weight for a certain metrical level (horizontal),
 # given the sequence of metrical weights in a hierarchy (vertical) and a sequence of subdivisions.
 def get_H(weightSequence,subdivisionSequence, level):
@@ -118,9 +140,29 @@
 		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):
+
+def calculate_bar_ticks(numerator, denominator, ticksPerQuarter):
 	return (numerator * ticksPerQuarter *4) / denominator
 
+
+def get_rhythm_category(velocitySequence, subdivisionSequence):
+	'''
+	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 
+	'''
+	rhythmCategory = 'mono'
+	for f in find_prime_factors(len(get_min_timeSpan(velocitySequence))):
+		if not (f in subdivisionSequence): 
+			rhythmCategory = 'poly'
+			break
+	return rhythmCategory
+
+
+def string_to_sequence(inputString):
+	return map(int, inputString.split(','))
+
 # # 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):
@@ -156,24 +198,6 @@
 # 	return subdivision_seq
 
 
-def get_rhythm_category(velocitySequence, subdivisionSequence):
-	'''
-	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 
-	'''
-	rhythmCategory = 'mono'
-	for f in find_prime_factors(len(get_min_timeSpan(velocitySequence))):
-		if not (f in subdivisionSequence): 
-			rhythmCategory = 'poly'
-			break
-	return rhythmCategory
-
-def string_to_sequence(inputString):
-	return map(int, inputString.split(','))
-
-
  # The split_by_bar function seperates the score representation of rhythm by bar lines, 
  # resulting in a list representingbar-by-bar rhythm sequence,
  # e.g. rhythm = ['|',[ts1,td1,v1], [ts2,td2,v2], '|',[ts3,td3,v3],'|'...]