misnaej commited on
Commit
5a748f4
1 Parent(s): 6445b7a

decoder fixed: timing and same inst possible

Browse files
Files changed (1) hide show
  1. decoder.py +206 -57
decoder.py CHANGED
@@ -28,8 +28,12 @@ class TextDecoder:
28
  Dict{inst_id: List[Events]}: List of events of Notes with velocities, aggregated Timeshifts, for each instrument
29
  """
30
  piece_events = self.text_to_events(text)
 
 
31
  inst_events = self.piece_to_inst_events(piece_events)
32
- events = self.add_timeshifts_for_empty_bars(inst_events)
 
 
33
  events = self.aggregate_timeshifts(events)
34
  events = self.add_velocity(events)
35
  return events
@@ -43,8 +47,8 @@ class TextDecoder:
43
  List[List[Events]]: List of tokens for each instrument
44
  """
45
  tokens = []
46
- for inst in events.keys():
47
- tokens.append(self.tokenizer.events_to_tokens(events[inst]))
48
  return tokens
49
 
50
  def get_midi(self, text, filename=None):
@@ -67,15 +71,78 @@ class TextDecoder:
67
  return midi
68
 
69
  @staticmethod
70
- def text_to_events(text):
71
  events = []
 
 
 
 
 
 
72
  for word in text.split(" "):
73
- # TODO: Handle bar and track values with a counter
74
  _event = word.split("=")
75
  value = _event[1] if len(_event) > 1 else None
76
- event = get_event(_event[0], value)
77
- if event:
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
78
  events.append(event)
 
 
 
 
 
 
 
 
 
 
 
 
 
79
  return events
80
 
81
  @staticmethod
@@ -89,31 +156,112 @@ class TextDecoder:
89
  Dict{inst_id: List[Events]}: List of events for each instrument
90
 
91
  """
92
- inst_events = {}
93
- current_instrument = -1
94
  for event in piece_events:
 
 
 
 
 
 
 
 
 
 
 
95
  if event.type == "Instrument":
96
- current_instrument = event.value
97
- if current_instrument not in inst_events:
98
- inst_events[current_instrument] = []
99
- elif current_instrument != -1:
100
- inst_events[current_instrument].append(event)
101
  return inst_events
102
 
103
  @staticmethod
104
- def add_timeshifts_for_empty_bars(inst_events):
105
- """Adds time shift events instead of consecutive [BAR_START BAR_END] events"""
106
- new_inst_events = {}
107
- for inst, events in inst_events.items():
108
- new_inst_events[inst] = []
109
- for index, event in enumerate(events):
110
- if event.type == "Bar-End" or event.type == "Bar-Start":
111
- if events[index - 1].type == "Bar-Start":
112
- new_inst_events[inst].append(Event("Time-Shift", "4.0.8"))
113
- else:
114
- new_inst_events[inst].append(event)
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
115
  return new_inst_events
116
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
117
  @staticmethod
118
  def add_timeshifts(beat_values1, beat_values2):
119
  """Adds two beat values
@@ -125,9 +273,9 @@ class TextDecoder:
125
  Returns:
126
  beat_str (String): added beats like 2.2.8 for example values
127
  """
128
- value1 = to_base10(beat_values1)
129
- value2 = to_base10(beat_values2)
130
- return to_beat_str(value1 + value2)
131
 
132
  def aggregate_timeshifts(self, events):
133
  """Aggregates consecutive time shift events bigger than a bar
@@ -139,58 +287,59 @@ class TextDecoder:
139
  Returns:
140
  _type_: _description_
141
  """
142
- new_events = {}
143
- for inst, events in events.items():
144
- inst_events = []
145
- for i, event in enumerate(events):
146
  if (
147
  event.type == "Time-Shift"
148
- and len(inst_events) > 0
149
- and inst_events[-1].type == "Time-Shift"
150
  ):
151
- inst_events[-1].value = self.add_timeshifts(
152
- inst_events[-1].value, event.value
153
  )
154
  else:
155
- inst_events.append(event)
156
- new_events[inst] = inst_events
157
- return new_events
 
158
 
159
  @staticmethod
160
  def add_velocity(events):
161
  """Adds default velocity 99 to note events since they are removed from text, needed to generate midi"""
162
- new_events = {}
163
- for inst, events in events.items():
164
- inst_events = []
165
- for event in events:
166
- inst_events.append(event)
167
- if event.type == "Note-On":
168
- inst_events.append(Event("Velocity", 99))
169
- new_events[inst] = inst_events
170
- return new_events
171
 
172
  def get_instruments_tuple(self, events):
173
  """Returns instruments tuple for midi generation"""
174
  instruments = []
175
- for inst in events.keys():
176
  is_drum = 0
177
- if inst == "DRUMS":
178
- inst = 0
179
  is_drum = 1
180
- if self.familized:
181
- inst = Familizer(arbitrary=True).get_program_number(int(inst))
182
- instruments.append((int(inst), is_drum))
 
 
183
  return tuple(instruments)
184
 
185
 
186
  if __name__ == "__main__":
187
-
188
- filename = "midi/generated/misnaej/the-jam-machine-elec-famil/20221209_175750"
189
  encoded_json = readFromFile(
190
  f"{filename}.json",
191
  True,
192
  )
193
- encoded_text = encoded_json["sequence"]
194
  # encoded_text = "PIECE_START TRACK_START INST=25 DENSITY=2 BAR_START NOTE_ON=50 TIME_DELTA=1 NOTE_OFF=50 NOTE_ON=50 TIME_DELTA=1 NOTE_OFF=50 NOTE_ON=66 NOTE_ON=62 TIME_DELTA=1 NOTE_OFF=66 NOTE_OFF=62 NOTE_ON=66 NOTE_ON=62 TIME_DELTA=1 NOTE_OFF=66 NOTE_OFF=62 NOTE_ON=64 NOTE_ON=60 TIME_DELTA=1 NOTE_OFF=64 NOTE_OFF=60 NOTE_ON=50 TIME_DELTA=1 NOTE_OFF=50 NOTE_ON=50 TIME_DELTA=1 NOTE_OFF=50 NOTE_ON=64 NOTE_ON=60 TIME_DELTA=1 NOTE_OFF=64 NOTE_OFF=60 NOTE_ON=64 NOTE_ON=60 TIME_DELTA=1 NOTE_OFF=64 NOTE_OFF=60 NOTE_ON=66 NOTE_ON=62 TIME_DELTA=1 NOTE_OFF=66 NOTE_OFF=62 NOTE_ON=64 NOTE_ON=60 TIME_DELTA=1 NOTE_OFF=64 NOTE_OFF=60 NOTE_ON=50 TIME_DELTA=1 NOTE_OFF=50 NOTE_ON=50 TIME_DELTA=1 NOTE_OFF=50 NOTE_ON=66 NOTE_ON=62 TIME_DELTA=1 NOTE_OFF=66 NOTE_OFF=62 NOTE_ON=50 TIME_DELTA=1 NOTE_OFF=50 NOTE_ON=67 NOTE_ON=64 TIME_DELTA=1 NOTE_OFF=67 NOTE_OFF=64 BAR_END BAR_START NOTE_ON=50 TIME_DELTA=1 NOTE_OFF=50 NOTE_ON=66 NOTE_ON=62 TIME_DELTA=1 NOTE_OFF=66 NOTE_OFF=62 NOTE_ON=50 TIME_DELTA=1 NOTE_OFF=50 NOTE_ON=50 TIME_DELTA=1 NOTE_OFF=50 NOTE_ON=64 NOTE_ON=62 TIME_DELTA=1 NOTE_OFF=64 NOTE_OFF=62 NOTE_ON=50 TIME_DELTA=1 NOTE_OFF=50 NOTE_ON=64 NOTE_ON=60 TIME_DELTA=1 NOTE_OFF=64 NOTE_OFF=60 NOTE_ON=66 NOTE_ON=62 TIME_DELTA=1 NOTE_OFF=66 NOTE_OFF=62 NOTE_ON=64 NOTE_ON=60 TIME_DELTA=1 NOTE_OFF=64 NOTE_OFF=60 NOTE_ON=50 TIME_DELTA=1 NOTE_OFF=50 NOTE_ON=66 NOTE_ON=62 TIME_DELTA=1 NOTE_OFF=66 NOTE_OFF=62 NOTE_ON=64 NOTE_ON=60 TIME_DELTA=1 NOTE_OFF=64 NOTE_OFF=60 NOTE_ON=50 TIME_DELTA=1 NOTE_OFF=50 BAR_END BAR_START NOTE_ON=50 TIME_DELTA=1 NOTE_OFF=50 NOTE_ON=66 NOTE_ON=62 TIME_DELTA=1 NOTE_OFF=66 NOTE_OFF=62 NOTE_ON=50 TIME_DELTA=1 NOTE_OFF=50 NOTE_ON=50 TIME_DELTA=1 NOTE_OFF=50 NOTE_ON=64 NOTE_ON=60 TIME_DELTA=1 NOTE_OFF=64 NOTE_OFF=60 NOTE_ON=50 TIME_DELTA=1 NOTE_OFF=50 NOTE_ON=50 TIME_DELTA=1 NOTE_OFF=50 NOTE_ON=64 NOTE_ON=60 NOTE_ON=50 TIME_DELTA=1 NOTE_OFF=64 NOTE_OFF=60 NOTE_OFF=50 NOTE_ON=66 NOTE_ON=62 TIME_DELTA=1 NOTE_OFF=66 NOTE_OFF=62 NOTE_ON=64 NOTE_ON=60 NOTE_ON=50 TIME_DELTA=1 NOTE_OFF=64 NOTE_OFF=60 NOTE_OFF=50 NOTE_ON=50 TIME_DELTA=1 NOTE_OFF=50 NOTE_ON=64 NOTE_ON=60 NOTE_ON=50 TIME_DELTA=1 NOTE_OFF=64 NOTE_OFF=60 NOTE_OFF=50 NOTE_ON=66 NOTE_ON=62 NOTE_ON=50 TIME_DELTA=1 NOTE_OFF=66 NOTE_OFF=62 NOTE_OFF=50 NOTE_ON=67 NOTE_ON=64 TIME_DELTA=1 NOTE_OFF=67 NOTE_OFF=64 NOTE_ON=50 TIME_DELTA=1 NOTE_OFF=50 BAR_END BAR_START NOTE_ON=50 TIME_DELTA=1 NOTE_OFF=50 NOTE_ON=66 NOTE_ON=62 TIME_DELTA=1 NOTE_OFF=66 NOTE_OFF=62 NOTE_ON=50 TIME_DELTA=1 NOTE_OFF=50 NOTE_ON=50 TIME_DELTA=1 NOTE_OFF=50 NOTE_ON=64 NOTE_ON=60 NOTE_ON=50 TIME_DELTA=1 NOTE_OFF=64 NOTE_OFF=60 NOTE_OFF=50 NOTE_ON=66 NOTE_ON=62 NOTE_ON=50 TIME_DELTA=1 NOTE_OFF=66 NOTE_OFF=62 NOTE_OFF=50 NOTE_ON=50 TIME_DELTA=1 NOTE_OFF=50 NOTE_ON=50 TIME_DELTA=1 NOTE_OFF=50 NOTE_ON=64 NOTE_ON=60 NOTE_ON=50 TIME_DELTA=1 NOTE_OFF=64 NOTE_OFF=60 NOTE_OFF=50 NOTE_ON=66 NOTE_ON=62 TIME_DELTA=1 NOTE_OFF=66 NOTE_OFF=62 NOTE_ON=64 NOTE_ON=60 NOTE_ON=50 TIME_DELTA=1 NOTE_OFF=64 NOTE_OFF=60 NOTE_OFF=50 NOTE_ON=66 NOTE_ON=62 NOTE_ON=50 TIME_DELTA=1 NOTE_OFF=66 NOTE_OFF=62 NOTE_OFF=50 NOTE_ON=67 NOTE_ON=64 TIME_DELTA=1 NOTE_OFF=67 NOTE_ON=50 TIME_DELTA=1 NOTE_OFF=50 NOTE_ON=64 NOTE_ON=60 TIME_DELTA=1 NOTE_OFF=64 NOTE_OFF=60 NOTE_ON=64 NOTE_ON=60 TIME_DELTA=1 NOTE_OFF=64 NOTE_OFF=60 NOTE_ON=64 NOTE_ON=60 TIME_DELTA=1 NOTE_OFF=64 NOTE_OFF=60 BAR_END BAR_START NOTE_ON=50 TIME_DELTA=1 NOTE_OFF=50 NOTE_ON=66 NOTE_ON=62 NOTE_ON=50 TIME_DELTA=1 NOTE_OFF=66 NOTE_OFF=62 NOTE_OFF=50 NOTE_ON=50 TIME_DELTA=1 NOTE_OFF=50 NOTE_ON=50 TIME_DELTA=1 NOTE_OFF=50 NOTE_ON=50 TIME_DELTA=1 NOTE_OFF=50 NOTE_ON=66 NOTE_ON=62 TIME_DELTA=1 NOTE_OFF=66 NOTE_OFF=62 NOTE_ON=50 TIME_DELTA=1 NOTE_OFF=50 NOTE_ON=64 NOTE_ON=60 NOTE_ON=50 TIME_DELTA=1 NOTE_OFF=64 NOTE_OFF=60 NOTE_OFF=50 NOTE_ON=64 NOTE_ON=60 NOTE_ON=50 TIME_DELTA=1 NOTE_OFF=64 NOTE_OFF=60 NOTE_OFF=50 NOTE_ON=66 NOTE_ON=62 NOTE_ON=50 TIME_DELTA=1 NOTE_OFF=66 NOTE_OFF=62 NOTE_OFF=50 NOTE_ON=50 TIME_DELTA=1 NOTE_OFF=50 NOTE_ON=69 NOTE_ON=64 NOTE_ON=60 TIME_DELTA=1 NOTE_OFF=69 NOTE_OFF=64 NOTE_OFF=60 NOTE_ON=64 NOTE_ON=60 NOTE_ON=50 TIME_DELTA=1 NOTE_OFF=64 NOTE_OFF=60 NOTE_OFF=50 NOTE_ON=57 TIME_DELTA=1 NOTE_OFF=57 NOTE_ON=56 TIME_DELTA=1 NOTE_OFF=56 NOTE_ON=64 NOTE_ON=60 NOTE_ON=55 TIME_DELTA=1 NOTE_OFF=64 NOTE_OFF=60 NOTE_OFF=55 BAR_END BAR_START NOTE_ON=50 TIME_DELTA=1 NOTE_OFF=50 NOTE_ON=66 NOTE_ON=62 TIME_DELTA=1 NOTE_OFF=66 NOTE_OFF=62 NOTE_ON=50 TIME_DELTA=1 NOTE_OFF=50 NOTE_ON=50 TIME_DELTA=1 NOTE_OFF=50 NOTE_ON=64 NOTE_ON=60 TIME_DELTA=1 NOTE_OFF=64 NOTE_OFF=60 NOTE_ON=66 NOTE_ON=62 NOTE_ON=50 TIME_DELTA=1 NOTE_OFF=66 NOTE_OFF=62 NOTE_OFF=50 NOTE_ON=50 TIME_DELTA=1 NOTE_OFF=50 NOTE_ON=64 NOTE_ON=60 NOTE_ON=50 TIME_DELTA=1 NOTE_OFF=64 NOTE_OFF=60 NOTE_OFF=50 NOTE_ON=64 NOTE_ON=60 NOTE_ON=50 TIME_DELTA=1 NOTE_OFF=64 NOTE_OFF=60 NOTE_OFF=50 NOTE_ON=66 NOTE_ON=62 NOTE_ON=50 TIME_DELTA=1 NOTE_OFF=66 NOTE_OFF=62 NOTE_OFF=50 NOTE_ON=66 NOTE_ON=62 NOTE_ON=50 TIME_DELTA=1 NOTE_OFF=66 NOTE_OFF=62 NOTE_OFF=50 NOTE_ON=50 TIME_DELTA=1 NOTE_OFF=50 NOTE_ON=67 NOTE_ON=64 TIME_DELTA=1 NOTE_OFF=67 NOTE_OFF=64 NOTE_ON=50 TIME_DELTA=1 NOTE_OFF=50 NOTE_ON=64 NOTE_ON=60 NOTE_ON=50 TIME_DELTA=1 NOTE_OFF=64 NOTE_OFF=60 NOTE_OFF=50 NOTE_ON=59 NOTE_ON=55 NOTE_ON=50 TIME_DELTA=1 NOTE_OFF=59 NOTE_OFF=50 NOTE_OFF=55 NOTE_OFF=50 BAR_END BAR_START BAR_END TRACK_END"
195
 
196
  miditok = get_miditok()
 
28
  Dict{inst_id: List[Events]}: List of events of Notes with velocities, aggregated Timeshifts, for each instrument
29
  """
30
  piece_events = self.text_to_events(text)
31
+ piece_events = self.get_track_ids(piece_events)
32
+ self.check_for_duplicated_events(piece_events)
33
  inst_events = self.piece_to_inst_events(piece_events)
34
+ inst_events = self.get_bar_ids(inst_events)
35
+ events = self.add_missing_timeshifts_in_a_bar(inst_events)
36
+ events = self.remove_unwanted_tokens(events)
37
  events = self.aggregate_timeshifts(events)
38
  events = self.add_velocity(events)
39
  return events
 
47
  List[List[Events]]: List of tokens for each instrument
48
  """
49
  tokens = []
50
+ for inst in events:
51
+ tokens.append(self.tokenizer.events_to_tokens(inst["events"]))
52
  return tokens
53
 
54
  def get_midi(self, text, filename=None):
 
71
  return midi
72
 
73
  @staticmethod
74
+ def text_to_events(text, verbose=False):
75
  events = []
76
+ instrument = "drums"
77
+ track_index = -1
78
+ # bar_value = 0
79
+ cumul_time_delta = 0
80
+ max_cumul_time_delta = 0
81
+
82
  for word in text.split(" "):
 
83
  _event = word.split("=")
84
  value = _event[1] if len(_event) > 1 else None
85
+ beyond_quantization = False # needs to be reset for each event
86
+
87
+ if _event[0] == "INST":
88
+ track_index += 1
89
+ bar_value = 0
90
+ # get the instrument for passing in get_event when time_delta for proper quantization
91
+ instrument = get_event(_event[0], value).value
92
+
93
+ # how much delta can be added before over quantization
94
+ max_cumul_time_delta = (
95
+ DRUMS_BEAT_QUANTIZATION * 4
96
+ if instrument.lower() == "drums"
97
+ else NONE_DRUMS_BEAT_QUANTIZATION * 4
98
+ )
99
+
100
+ if _event[0] == "BAR_START":
101
+ bar_value += 1
102
+ value = bar_value
103
+ # reseting cumul_time_delta
104
+ cumul_time_delta = 0
105
+
106
+ # ----- hack to prevent over quantization -> NOT IDEAL - the model should not output these events
107
+ if _event[0] == "TIME_DELTA":
108
+ cumul_time_delta += int(_event[1])
109
+ if cumul_time_delta > max_cumul_time_delta:
110
+ beyond_quantization = True
111
+ cumul_time_delta -= int(_event[1])
112
+
113
+ if _event[0] == "NOTE_ON" and cumul_time_delta >= max_cumul_time_delta:
114
+ beyond_quantization = True
115
+
116
+ if beyond_quantization:
117
+ print(
118
+ f"instrument {instrument} - bar {bar_value} - skipping {_event[0]} because of over quantization"
119
+ ) if verbose else None
120
+ # ---------------------------------------------------------------------------------------------``
121
+
122
+ # getting event
123
+ event = get_event(_event[0], value, instrument)
124
+ if event and not beyond_quantization:
125
+ if event.type == "Bar-End":
126
+ print(
127
+ f"instrument {instrument} - bar {bar_value} - Cumulated TIME_DELTA = {cumul_time_delta}"
128
+ ) if verbose else None
129
+ cumul_time_delta = 0
130
+
131
+ # appending event
132
  events.append(event)
133
+
134
+ return events
135
+
136
+ @staticmethod
137
+ def get_track_ids(events):
138
+ """Adding tracking the track id for each track start and end event"""
139
+ track_id = 0
140
+ for i, event in enumerate(events):
141
+ if event.type == "Track-Start":
142
+ events[i].value = track_id
143
+ if event.type == "Track-End":
144
+ events[i].value = track_id
145
+ track_id += 1
146
  return events
147
 
148
  @staticmethod
 
156
  Dict{inst_id: List[Events]}: List of events for each instrument
157
 
158
  """
159
+ inst_events = []
160
+ current_track = -1 # so does not start before Track-Start is encountered
161
  for event in piece_events:
162
+ # creates a new entry in the dictionnary when "Track-Start" event is encountered
163
+ if event.type == "Track-Start":
164
+ current_track = event.value
165
+ if len(inst_events) == event.value:
166
+ inst_events.append({})
167
+ inst_events[current_track]["channel"] = current_track
168
+ inst_events[current_track]["events"] = []
169
+ # append event to the track
170
+ if current_track != -1:
171
+ inst_events[current_track]["events"].append(event)
172
+
173
  if event.type == "Instrument":
174
+ inst_events[current_track]["Instrument"] = event.value
175
+ # TODO: needs cleaning Track-start and track end
 
 
 
176
  return inst_events
177
 
178
  @staticmethod
179
+ def get_bar_ids(inst_events):
180
+ """tracking bar index for each instrument and saving them in the miditok Events"""
181
+ for inst_index, inst_event in enumerate(inst_events):
182
+ bar_idx = 0
183
+ for event_index, event in enumerate(inst_event["events"]):
184
+ if event.type == "Bar-Start" or event.type == "Bar-End":
185
+ inst_events[inst_index]["events"][event_index].value = bar_idx
186
+ if event.type == "Bar-End":
187
+ bar_idx += 1
188
+ return inst_events
189
+
190
+ @staticmethod
191
+ def add_missing_timeshifts_in_a_bar(inst_events, beat_per_bar=4, verbose=False):
192
+ """Add missing time shifts in bar to make sure that each bar has 4 beats
193
+ takes care of the problem of a missing time shift if notes do not last until the end of the bar
194
+ takes care of the problem of empty bars that are only defined by "BAR_START BAR END
195
+ """
196
+ new_inst_events = []
197
+ for index, inst_event in enumerate(inst_events):
198
+ new_inst_events.append({})
199
+ new_inst_events[index]["Instrument"] = inst_event["Instrument"]
200
+ new_inst_events[index]["channel"] = index
201
+ new_inst_events[index]["events"] = []
202
+
203
+ for event in inst_event["events"]:
204
+ if event.type == "Bar-Start":
205
+ beat_count = 0
206
+
207
+ if event.type == "Time-Shift":
208
+ beat_count += int_dec_base_to_beat(event.value)
209
+
210
+ if event.type == "Bar-End" and beat_count < beat_per_bar:
211
+ time_shift_to_add = beat_to_int_dec_base(beat_per_bar - beat_count)
212
+ new_inst_events[index]["events"].append(
213
+ Event("Time-Shift", time_shift_to_add)
214
+ )
215
+ beat_count += int_dec_base_to_beat(time_shift_to_add)
216
+
217
+ if event.type == "Bar-End" and verbose == True:
218
+ print(
219
+ f"Instrument {index} - {inst_event['Instrument']} - Bar {event.value} - beat_count = {beat_count}"
220
+ )
221
+ if event.type == "Bar-End" and beat_count > beat_per_bar:
222
+ print(
223
+ f"Instrument {index} - {inst_event['Instrument']} - Bar {event.value} - Beat count exceeded "
224
+ )
225
+ new_inst_events[index]["events"].append(event)
226
+
227
+ return new_inst_events
228
+
229
+ # TODO
230
+ @staticmethod
231
+ def check_bar_count_in_section(inst_events, bars_in_sections=8):
232
+ new_inst_events = []
233
+ for index, inst_event in enumerate(inst_events):
234
+ pass
235
  return new_inst_events
236
 
237
+ @staticmethod
238
+ def remove_unwanted_tokens(events):
239
+ for inst_index, inst_event in enumerate(events):
240
+ new_inst_event = []
241
+ for event in inst_event["events"]:
242
+ if not (
243
+ event.type == "Bar-Start"
244
+ or event.type == "Bar-End"
245
+ or event.type == "Track-Start"
246
+ or event.type == "Track-End"
247
+ or event.type == "Piece-Start"
248
+ or event.type == "Instrument"
249
+ ):
250
+ new_inst_event.append(event)
251
+ # replace the events list with the new one
252
+ events[inst_index]["events"] = new_inst_event
253
+ return events
254
+
255
+ @staticmethod
256
+ def check_for_duplicated_events(event_list):
257
+ for i, event in enumerate(event_list):
258
+ if (
259
+ i < len(event_list) - 1
260
+ and event.type == event_list[i + 1].type
261
+ and event.value == event_list[i + 1].value
262
+ ):
263
+ print(f"Duplicate event found at index {i} : {event}")
264
+
265
  @staticmethod
266
  def add_timeshifts(beat_values1, beat_values2):
267
  """Adds two beat values
 
273
  Returns:
274
  beat_str (String): added beats like 2.2.8 for example values
275
  """
276
+ value1 = int_dec_base_to_beat(beat_values1)
277
+ value2 = int_dec_base_to_beat(beat_values2)
278
+ return beat_to_int_dec_base(value1 + value2)
279
 
280
  def aggregate_timeshifts(self, events):
281
  """Aggregates consecutive time shift events bigger than a bar
 
287
  Returns:
288
  _type_: _description_
289
  """
290
+ for inst_index, inst_event in enumerate(events):
291
+ new_inst_event = []
292
+ for event in inst_event["events"]:
 
293
  if (
294
  event.type == "Time-Shift"
295
+ and len(new_inst_event) > 0
296
+ and new_inst_event[-1].type == "Time-Shift"
297
  ):
298
+ new_inst_event[-1].value = self.add_timeshifts(
299
+ new_inst_event[-1].value, event.value
300
  )
301
  else:
302
+ new_inst_event.append(event)
303
+
304
+ events[inst_index]["events"] = new_inst_event
305
+ return events
306
 
307
  @staticmethod
308
  def add_velocity(events):
309
  """Adds default velocity 99 to note events since they are removed from text, needed to generate midi"""
310
+ for inst_index, inst_event in enumerate(events):
311
+ new_inst_event = []
312
+ for inst_event in inst_event["events"]:
313
+ new_inst_event.append(inst_event)
314
+ if inst_event.type == "Note-On":
315
+ new_inst_event.append(Event("Velocity", 99))
316
+ events[inst_index]["events"] = new_inst_event
317
+ return events
 
318
 
319
  def get_instruments_tuple(self, events):
320
  """Returns instruments tuple for midi generation"""
321
  instruments = []
322
+ for track in events:
323
  is_drum = 0
324
+ if track["Instrument"].lower() == "drums":
325
+ track["Instrument"] = 0
326
  is_drum = 1
327
+ if self.familized and not is_drum:
328
+ track["Instrument"] = Familizer(arbitrary=True).get_program_number(
329
+ int(track["Instrument"])
330
+ )
331
+ instruments.append((int(track["Instrument"]), is_drum))
332
  return tuple(instruments)
333
 
334
 
335
  if __name__ == "__main__":
336
+ # filename = "midi/generated/JammyMachina/elec-gmusic-familized-model-13-12__17-35-53/20230221_235439"
337
+ filename = "source/tests/20230305_150554" # investigating the duplicates issues
338
  encoded_json = readFromFile(
339
  f"{filename}.json",
340
  True,
341
  )
342
+ encoded_text = encoded_json["generated_midi"]
343
  # encoded_text = "PIECE_START TRACK_START INST=25 DENSITY=2 BAR_START NOTE_ON=50 TIME_DELTA=1 NOTE_OFF=50 NOTE_ON=50 TIME_DELTA=1 NOTE_OFF=50 NOTE_ON=66 NOTE_ON=62 TIME_DELTA=1 NOTE_OFF=66 NOTE_OFF=62 NOTE_ON=66 NOTE_ON=62 TIME_DELTA=1 NOTE_OFF=66 NOTE_OFF=62 NOTE_ON=64 NOTE_ON=60 TIME_DELTA=1 NOTE_OFF=64 NOTE_OFF=60 NOTE_ON=50 TIME_DELTA=1 NOTE_OFF=50 NOTE_ON=50 TIME_DELTA=1 NOTE_OFF=50 NOTE_ON=64 NOTE_ON=60 TIME_DELTA=1 NOTE_OFF=64 NOTE_OFF=60 NOTE_ON=64 NOTE_ON=60 TIME_DELTA=1 NOTE_OFF=64 NOTE_OFF=60 NOTE_ON=66 NOTE_ON=62 TIME_DELTA=1 NOTE_OFF=66 NOTE_OFF=62 NOTE_ON=64 NOTE_ON=60 TIME_DELTA=1 NOTE_OFF=64 NOTE_OFF=60 NOTE_ON=50 TIME_DELTA=1 NOTE_OFF=50 NOTE_ON=50 TIME_DELTA=1 NOTE_OFF=50 NOTE_ON=66 NOTE_ON=62 TIME_DELTA=1 NOTE_OFF=66 NOTE_OFF=62 NOTE_ON=50 TIME_DELTA=1 NOTE_OFF=50 NOTE_ON=67 NOTE_ON=64 TIME_DELTA=1 NOTE_OFF=67 NOTE_OFF=64 BAR_END BAR_START NOTE_ON=50 TIME_DELTA=1 NOTE_OFF=50 NOTE_ON=66 NOTE_ON=62 TIME_DELTA=1 NOTE_OFF=66 NOTE_OFF=62 NOTE_ON=50 TIME_DELTA=1 NOTE_OFF=50 NOTE_ON=50 TIME_DELTA=1 NOTE_OFF=50 NOTE_ON=64 NOTE_ON=62 TIME_DELTA=1 NOTE_OFF=64 NOTE_OFF=62 NOTE_ON=50 TIME_DELTA=1 NOTE_OFF=50 NOTE_ON=64 NOTE_ON=60 TIME_DELTA=1 NOTE_OFF=64 NOTE_OFF=60 NOTE_ON=66 NOTE_ON=62 TIME_DELTA=1 NOTE_OFF=66 NOTE_OFF=62 NOTE_ON=64 NOTE_ON=60 TIME_DELTA=1 NOTE_OFF=64 NOTE_OFF=60 NOTE_ON=50 TIME_DELTA=1 NOTE_OFF=50 NOTE_ON=66 NOTE_ON=62 TIME_DELTA=1 NOTE_OFF=66 NOTE_OFF=62 NOTE_ON=64 NOTE_ON=60 TIME_DELTA=1 NOTE_OFF=64 NOTE_OFF=60 NOTE_ON=50 TIME_DELTA=1 NOTE_OFF=50 BAR_END BAR_START NOTE_ON=50 TIME_DELTA=1 NOTE_OFF=50 NOTE_ON=66 NOTE_ON=62 TIME_DELTA=1 NOTE_OFF=66 NOTE_OFF=62 NOTE_ON=50 TIME_DELTA=1 NOTE_OFF=50 NOTE_ON=50 TIME_DELTA=1 NOTE_OFF=50 NOTE_ON=64 NOTE_ON=60 TIME_DELTA=1 NOTE_OFF=64 NOTE_OFF=60 NOTE_ON=50 TIME_DELTA=1 NOTE_OFF=50 NOTE_ON=50 TIME_DELTA=1 NOTE_OFF=50 NOTE_ON=64 NOTE_ON=60 NOTE_ON=50 TIME_DELTA=1 NOTE_OFF=64 NOTE_OFF=60 NOTE_OFF=50 NOTE_ON=66 NOTE_ON=62 TIME_DELTA=1 NOTE_OFF=66 NOTE_OFF=62 NOTE_ON=64 NOTE_ON=60 NOTE_ON=50 TIME_DELTA=1 NOTE_OFF=64 NOTE_OFF=60 NOTE_OFF=50 NOTE_ON=50 TIME_DELTA=1 NOTE_OFF=50 NOTE_ON=64 NOTE_ON=60 NOTE_ON=50 TIME_DELTA=1 NOTE_OFF=64 NOTE_OFF=60 NOTE_OFF=50 NOTE_ON=66 NOTE_ON=62 NOTE_ON=50 TIME_DELTA=1 NOTE_OFF=66 NOTE_OFF=62 NOTE_OFF=50 NOTE_ON=67 NOTE_ON=64 TIME_DELTA=1 NOTE_OFF=67 NOTE_OFF=64 NOTE_ON=50 TIME_DELTA=1 NOTE_OFF=50 BAR_END BAR_START NOTE_ON=50 TIME_DELTA=1 NOTE_OFF=50 NOTE_ON=66 NOTE_ON=62 TIME_DELTA=1 NOTE_OFF=66 NOTE_OFF=62 NOTE_ON=50 TIME_DELTA=1 NOTE_OFF=50 NOTE_ON=50 TIME_DELTA=1 NOTE_OFF=50 NOTE_ON=64 NOTE_ON=60 NOTE_ON=50 TIME_DELTA=1 NOTE_OFF=64 NOTE_OFF=60 NOTE_OFF=50 NOTE_ON=66 NOTE_ON=62 NOTE_ON=50 TIME_DELTA=1 NOTE_OFF=66 NOTE_OFF=62 NOTE_OFF=50 NOTE_ON=50 TIME_DELTA=1 NOTE_OFF=50 NOTE_ON=50 TIME_DELTA=1 NOTE_OFF=50 NOTE_ON=64 NOTE_ON=60 NOTE_ON=50 TIME_DELTA=1 NOTE_OFF=64 NOTE_OFF=60 NOTE_OFF=50 NOTE_ON=66 NOTE_ON=62 TIME_DELTA=1 NOTE_OFF=66 NOTE_OFF=62 NOTE_ON=64 NOTE_ON=60 NOTE_ON=50 TIME_DELTA=1 NOTE_OFF=64 NOTE_OFF=60 NOTE_OFF=50 NOTE_ON=66 NOTE_ON=62 NOTE_ON=50 TIME_DELTA=1 NOTE_OFF=66 NOTE_OFF=62 NOTE_OFF=50 NOTE_ON=67 NOTE_ON=64 TIME_DELTA=1 NOTE_OFF=67 NOTE_ON=50 TIME_DELTA=1 NOTE_OFF=50 NOTE_ON=64 NOTE_ON=60 TIME_DELTA=1 NOTE_OFF=64 NOTE_OFF=60 NOTE_ON=64 NOTE_ON=60 TIME_DELTA=1 NOTE_OFF=64 NOTE_OFF=60 NOTE_ON=64 NOTE_ON=60 TIME_DELTA=1 NOTE_OFF=64 NOTE_OFF=60 BAR_END BAR_START NOTE_ON=50 TIME_DELTA=1 NOTE_OFF=50 NOTE_ON=66 NOTE_ON=62 NOTE_ON=50 TIME_DELTA=1 NOTE_OFF=66 NOTE_OFF=62 NOTE_OFF=50 NOTE_ON=50 TIME_DELTA=1 NOTE_OFF=50 NOTE_ON=50 TIME_DELTA=1 NOTE_OFF=50 NOTE_ON=50 TIME_DELTA=1 NOTE_OFF=50 NOTE_ON=66 NOTE_ON=62 TIME_DELTA=1 NOTE_OFF=66 NOTE_OFF=62 NOTE_ON=50 TIME_DELTA=1 NOTE_OFF=50 NOTE_ON=64 NOTE_ON=60 NOTE_ON=50 TIME_DELTA=1 NOTE_OFF=64 NOTE_OFF=60 NOTE_OFF=50 NOTE_ON=64 NOTE_ON=60 NOTE_ON=50 TIME_DELTA=1 NOTE_OFF=64 NOTE_OFF=60 NOTE_OFF=50 NOTE_ON=66 NOTE_ON=62 NOTE_ON=50 TIME_DELTA=1 NOTE_OFF=66 NOTE_OFF=62 NOTE_OFF=50 NOTE_ON=50 TIME_DELTA=1 NOTE_OFF=50 NOTE_ON=69 NOTE_ON=64 NOTE_ON=60 TIME_DELTA=1 NOTE_OFF=69 NOTE_OFF=64 NOTE_OFF=60 NOTE_ON=64 NOTE_ON=60 NOTE_ON=50 TIME_DELTA=1 NOTE_OFF=64 NOTE_OFF=60 NOTE_OFF=50 NOTE_ON=57 TIME_DELTA=1 NOTE_OFF=57 NOTE_ON=56 TIME_DELTA=1 NOTE_OFF=56 NOTE_ON=64 NOTE_ON=60 NOTE_ON=55 TIME_DELTA=1 NOTE_OFF=64 NOTE_OFF=60 NOTE_OFF=55 BAR_END BAR_START NOTE_ON=50 TIME_DELTA=1 NOTE_OFF=50 NOTE_ON=66 NOTE_ON=62 TIME_DELTA=1 NOTE_OFF=66 NOTE_OFF=62 NOTE_ON=50 TIME_DELTA=1 NOTE_OFF=50 NOTE_ON=50 TIME_DELTA=1 NOTE_OFF=50 NOTE_ON=64 NOTE_ON=60 TIME_DELTA=1 NOTE_OFF=64 NOTE_OFF=60 NOTE_ON=66 NOTE_ON=62 NOTE_ON=50 TIME_DELTA=1 NOTE_OFF=66 NOTE_OFF=62 NOTE_OFF=50 NOTE_ON=50 TIME_DELTA=1 NOTE_OFF=50 NOTE_ON=64 NOTE_ON=60 NOTE_ON=50 TIME_DELTA=1 NOTE_OFF=64 NOTE_OFF=60 NOTE_OFF=50 NOTE_ON=64 NOTE_ON=60 NOTE_ON=50 TIME_DELTA=1 NOTE_OFF=64 NOTE_OFF=60 NOTE_OFF=50 NOTE_ON=66 NOTE_ON=62 NOTE_ON=50 TIME_DELTA=1 NOTE_OFF=66 NOTE_OFF=62 NOTE_OFF=50 NOTE_ON=66 NOTE_ON=62 NOTE_ON=50 TIME_DELTA=1 NOTE_OFF=66 NOTE_OFF=62 NOTE_OFF=50 NOTE_ON=50 TIME_DELTA=1 NOTE_OFF=50 NOTE_ON=67 NOTE_ON=64 TIME_DELTA=1 NOTE_OFF=67 NOTE_OFF=64 NOTE_ON=50 TIME_DELTA=1 NOTE_OFF=50 NOTE_ON=64 NOTE_ON=60 NOTE_ON=50 TIME_DELTA=1 NOTE_OFF=64 NOTE_OFF=60 NOTE_OFF=50 NOTE_ON=59 NOTE_ON=55 NOTE_ON=50 TIME_DELTA=1 NOTE_OFF=59 NOTE_OFF=50 NOTE_OFF=55 NOTE_OFF=50 BAR_END BAR_START BAR_END TRACK_END"
344
 
345
  miditok = get_miditok()