Mercurial > hg > syncopation-dataset
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):