diff Syncopation models/music_objects.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/music_objects.py	Tue Apr 07 23:16:13 2015 +0100
+++ b/Syncopation models/music_objects.py	Thu Apr 09 23:49:16 2015 +0100
@@ -1,22 +1,37 @@
 
-from basic_functions import ceiling, string_to_sequence, calculate_time_span_ticks
-
+from basic_functions import ceiling, string_to_sequence, calculate_bar_ticks
 import parameter_setter 
 import rhythm_parser 
 
 class Note():
-	def __init__(self, argstring):
-		intlist = string_to_sequence(argstring)
-		self.startTime = intlist[0]
-		self.duration = intlist[1]
-		self.velocity = intlist[2]
-	
-	# toString()
+	def __init__(self, firstarg = None, duration = None, velocity = None):
+		self.startTime = 0
+		self.duration = 0
+		self.velocity = 0
+
+		if firstarg != None:
+			if isinstance(firstarg,basestring):
+				intlist = string_to_sequence(firstarg)
+				self.startTime = intlist[0]
+				self.duration = intlist[1]
+				self.velocity = intlist[2]
+			elif isinstance(firstarg,int):
+				self.startTime = firstarg
+
+		if duration != None:
+			self.duration = duration
+		if velocity != None:
+			self.velocity = velocity
+
+
+	def to_string(self):
+		return "(%d,%d,%f)" %(self.startTime, self.duration, self.velocity)
+
 
 # NoteSequence is a list of Note
 class NoteSequence(list):
-	def __init__(self, noteSequenceString=None):
-		if noteSequenceString!=None:
+	def __init__(self, noteSequenceString = None):
+		if noteSequenceString != None:
 			self.string_to_note_sequence(noteSequenceString)
 
 	def string_to_note_sequence(self, noteSequenceString):
@@ -27,17 +42,73 @@
 		for localString in listStrings:
 			self.append(Note(localString))
 
-	# toString()
+	def to_string(self):
+		noteSequenceString = ""
+		for note in self:
+			noteSequenceString += note.to_string() + ","
+		return noteSequenceString[:-1]
 
+# VelocitySequence is a list of float numbers
+class VelocitySequence(list):
+	def __init__(self, velocitySequenceString = None):
+		if velocitySequenceString != None:
+			self.string_to_velocity_sequence(velocitySequenceString)
 
-#print NoteSequence("(1,2,3),(4,5,6),(7,8,9)")
-class VelocitySequence(list):
-	def __init__(self, noteSequenceString=None):
-		if noteSequenceString!=None:
-			self.string_to_note_sequence(noteSequenceString)
+	def string_to_velocity_sequence(self,inputString):
+		self.extend(string_to_sequence(inputString))
 
-	def string_to_note_sequence(self,inputString):
-		self.extend(string_to_sequence(inputString))
+	def to_string(self):
+		return str(self)[1:-1].replace(" ","")
+
+
+def velocity_sequence_to_note_sequence(velocitySequence):
+	
+	noteSequence = NoteSequence()
+
+	for index in range(len(velocitySequence)):
+		if (velocitySequence[index]!= 0): # onset detected
+			startTime = index			
+			velocity = velocitySequence[index]
+
+			# if there are previous notes added
+			if( len(noteSequence) > 0):
+				previousNote = noteSequence[-1]
+				previousNote.duration = startTime - previousNote.startTime
+
+			# add the current note into note sequence
+			noteSequence.append( Note(startTime, 0, velocity) )
+
+	# to set the duration for the last note
+	if( len(noteSequence) > 0):
+		previousNote = noteSequence[-1]
+		previousNote.duration = len(velocitySequence) - previousNote.startTime
+
+	return noteSequence
+
+
+def note_sequence_to_velocity_sequence(noteSequence, timespanTicks = None):
+	
+	velocitySequence = VelocitySequence()
+	
+	previousNoteStartTime = -1
+
+	for note in noteSequence:
+		
+		interOnsetInterval = note.startTime - previousNoteStartTime	
+		velocitySequence += [0]*(interOnsetInterval-1)	
+		velocitySequence += [note.velocity]
+
+		previousNoteStartTime = note.startTime
+
+	if timespanTicks!=None:
+		velocitySequence += [0]*(timespanTicks - len(velocitySequence))
+	else:
+		velocitySequence += [0]*(noteSequence[-1].duration-1)
+
+	# normalising velocity sequence between 0-1
+	velocitySequence = [float(v)/max(velocitySequence) for v in velocitySequence]
+
+	return velocitySequence
 
 
 class BarList(list):
@@ -48,9 +119,6 @@
 		super(BarList, self).append(bar)
 
 
-
-
-
 class Bar:
 
 	def __init__(self, rhythmSequence, timeSignature, ticksPerQuarter=None, qpmTempo=None, nextBar=None, prevBar=None):
@@ -68,13 +136,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 = velocitySequence_to_noteSequence(self.velocitySequence)
 		return self.noteSequence
 
 	def get_velocity_sequence(self):
-		if self.velocitySequence==None:
-			self.velocitySequence = note_sequence_to_velocities(self.noteSequence)
+		if self.velocitySequence == None:
+			self.velocitySequence = noteSequence_to_velocitySequence(self.noteSequence)
 		return self.velocitySequence
 
 	def get_binary_sequence(self):
@@ -102,8 +170,9 @@
 		return self.timeSignature
 
 	# 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)
+	def get_bar_ticks(self):
+		return calculate_bar_ticks(self.timeSignature.get_numerator(),self.timeSignature.get_denominator(), self.ticksPerQuarter)
+
 
 class TimeSignature():
 	def __init__(self, inputString):