comparison 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
comparison
equal deleted inserted replaced
21:b6daddeefda9 22:2dbc09ca8013
1 1
2 from basic_functions import ceiling, string_to_sequence, calculate_time_span_ticks 2 from basic_functions import ceiling, string_to_sequence, calculate_bar_ticks
3
4 import parameter_setter 3 import parameter_setter
5 import rhythm_parser 4 import rhythm_parser
6 5
7 class Note(): 6 class Note():
8 def __init__(self, argstring): 7 def __init__(self, firstarg = None, duration = None, velocity = None):
9 intlist = string_to_sequence(argstring) 8 self.startTime = 0
10 self.startTime = intlist[0] 9 self.duration = 0
11 self.duration = intlist[1] 10 self.velocity = 0
12 self.velocity = intlist[2] 11
13 12 if firstarg != None:
14 # toString() 13 if isinstance(firstarg,basestring):
14 intlist = string_to_sequence(firstarg)
15 self.startTime = intlist[0]
16 self.duration = intlist[1]
17 self.velocity = intlist[2]
18 elif isinstance(firstarg,int):
19 self.startTime = firstarg
20
21 if duration != None:
22 self.duration = duration
23 if velocity != None:
24 self.velocity = velocity
25
26
27 def to_string(self):
28 return "(%d,%d,%f)" %(self.startTime, self.duration, self.velocity)
29
15 30
16 # NoteSequence is a list of Note 31 # NoteSequence is a list of Note
17 class NoteSequence(list): 32 class NoteSequence(list):
18 def __init__(self, noteSequenceString=None): 33 def __init__(self, noteSequenceString = None):
19 if noteSequenceString!=None: 34 if noteSequenceString != None:
20 self.string_to_note_sequence(noteSequenceString) 35 self.string_to_note_sequence(noteSequenceString)
21 36
22 def string_to_note_sequence(self, noteSequenceString): 37 def string_to_note_sequence(self, noteSequenceString):
23 noteSequenceString = rhythm_parser.discardSpaces(noteSequenceString) 38 noteSequenceString = rhythm_parser.discardSpaces(noteSequenceString)
24 # try: 39 # try:
25 # Turning "(1,2,3),(4,5,6),(7,8,9)" into ["1,2,3","4,5,6,","7,8,9"] 40 # Turning "(1,2,3),(4,5,6),(7,8,9)" into ["1,2,3","4,5,6,","7,8,9"]
26 listStrings = noteSequenceString[1:-1].split("),(") 41 listStrings = noteSequenceString[1:-1].split("),(")
27 for localString in listStrings: 42 for localString in listStrings:
28 self.append(Note(localString)) 43 self.append(Note(localString))
29 44
30 # toString() 45 def to_string(self):
46 noteSequenceString = ""
47 for note in self:
48 noteSequenceString += note.to_string() + ","
49 return noteSequenceString[:-1]
50
51 # VelocitySequence is a list of float numbers
52 class VelocitySequence(list):
53 def __init__(self, velocitySequenceString = None):
54 if velocitySequenceString != None:
55 self.string_to_velocity_sequence(velocitySequenceString)
56
57 def string_to_velocity_sequence(self,inputString):
58 self.extend(string_to_sequence(inputString))
59
60 def to_string(self):
61 return str(self)[1:-1].replace(" ","")
31 62
32 63
33 #print NoteSequence("(1,2,3),(4,5,6),(7,8,9)") 64 def velocity_sequence_to_note_sequence(velocitySequence):
34 class VelocitySequence(list): 65
35 def __init__(self, noteSequenceString=None): 66 noteSequence = NoteSequence()
36 if noteSequenceString!=None:
37 self.string_to_note_sequence(noteSequenceString)
38 67
39 def string_to_note_sequence(self,inputString): 68 for index in range(len(velocitySequence)):
40 self.extend(string_to_sequence(inputString)) 69 if (velocitySequence[index]!= 0): # onset detected
70 startTime = index
71 velocity = velocitySequence[index]
72
73 # if there are previous notes added
74 if( len(noteSequence) > 0):
75 previousNote = noteSequence[-1]
76 previousNote.duration = startTime - previousNote.startTime
77
78 # add the current note into note sequence
79 noteSequence.append( Note(startTime, 0, velocity) )
80
81 # to set the duration for the last note
82 if( len(noteSequence) > 0):
83 previousNote = noteSequence[-1]
84 previousNote.duration = len(velocitySequence) - previousNote.startTime
85
86 return noteSequence
87
88
89 def note_sequence_to_velocity_sequence(noteSequence, timespanTicks = None):
90
91 velocitySequence = VelocitySequence()
92
93 previousNoteStartTime = -1
94
95 for note in noteSequence:
96
97 interOnsetInterval = note.startTime - previousNoteStartTime
98 velocitySequence += [0]*(interOnsetInterval-1)
99 velocitySequence += [note.velocity]
100
101 previousNoteStartTime = note.startTime
102
103 if timespanTicks!=None:
104 velocitySequence += [0]*(timespanTicks - len(velocitySequence))
105 else:
106 velocitySequence += [0]*(noteSequence[-1].duration-1)
107
108 # normalising velocity sequence between 0-1
109 velocitySequence = [float(v)/max(velocitySequence) for v in velocitySequence]
110
111 return velocitySequence
41 112
42 113
43 class BarList(list): 114 class BarList(list):
44 def append(self,bar): 115 def append(self,bar):
45 if(len(self)>0): 116 if(len(self)>0):
46 bar.set_previous_bar(self[-1]) 117 bar.set_previous_bar(self[-1])
47 self[-1].set_next_bar(bar) 118 self[-1].set_next_bar(bar)
48 super(BarList, self).append(bar) 119 super(BarList, self).append(bar)
49
50
51
52 120
53 121
54 class Bar: 122 class Bar:
55 123
56 def __init__(self, rhythmSequence, timeSignature, ticksPerQuarter=None, qpmTempo=None, nextBar=None, prevBar=None): 124 def __init__(self, rhythmSequence, timeSignature, ticksPerQuarter=None, qpmTempo=None, nextBar=None, prevBar=None):
66 self.timeSignature = TimeSignature(timeSignature) 134 self.timeSignature = TimeSignature(timeSignature)
67 self.nextBar = nextBar 135 self.nextBar = nextBar
68 self.prevBar = prevBar 136 self.prevBar = prevBar
69 137
70 def get_note_sequence(self): 138 def get_note_sequence(self):
71 if self.noteSequence==None: 139 if self.noteSequence == None:
72 self.noteSequence = velocity_sequence_to_notes(self.velocitySequence) 140 self.noteSequence = velocitySequence_to_noteSequence(self.velocitySequence)
73 return self.noteSequence 141 return self.noteSequence
74 142
75 def get_velocity_sequence(self): 143 def get_velocity_sequence(self):
76 if self.velocitySequence==None: 144 if self.velocitySequence == None:
77 self.velocitySequence = note_sequence_to_velocities(self.noteSequence) 145 self.velocitySequence = noteSequence_to_velocitySequence(self.noteSequence)
78 return self.velocitySequence 146 return self.velocitySequence
79 147
80 def get_binary_sequence(self): 148 def get_binary_sequence(self):
81 return ceiling(self.get_velocity_sequence()) 149 return ceiling(self.get_velocity_sequence())
82 150
100 168
101 def get_time_signature(self): 169 def get_time_signature(self):
102 return self.timeSignature 170 return self.timeSignature
103 171
104 # return the length of a bar in time units (ticks) 172 # return the length of a bar in time units (ticks)
105 def get_time_span(self): 173 def get_bar_ticks(self):
106 return calculate_time_span_ticks(self.timeSignature.get_numerator(),self.timeSignature.get_denominator(), self.ticksPerQuarter) 174 return calculate_bar_ticks(self.timeSignature.get_numerator(),self.timeSignature.get_denominator(), self.ticksPerQuarter)
175
107 176
108 class TimeSignature(): 177 class TimeSignature():
109 def __init__(self, inputString): 178 def __init__(self, inputString):
110 if inputString in parameter_setter.read_time_signature(): 179 if inputString in parameter_setter.read_time_signature():
111 self.tsString = inputString 180 self.tsString = inputString