def prepare_print_instruments(self, druminst=None): """build complete timeline for (drum & regular) instrument events """ if not druminst: druminst = [] self.druminst = druminst self.notes_data_dict = collections.defaultdict(dict) self.all_notes = collections.defaultdict(set) self.total_length = 0 for trackname in self.tracknames: is_drumtrack = trackname in self.druminst # bepaal max. lengte start, _, lng = self.patterndata[trackname][-1] for pattern in self.patterndata[trackname]: self.all_notes[trackname].update([x[0] for x in pattern[1]]) ## total_length = int((start + len) / shared.timing_unit) current_length = (start + lng) // shared.timing_unit self.total_length = max((current_length, self.total_length)) empty = shared.empty[is_drumtrack] for note in self.all_notes[trackname]: self.notes_data_dict[trackname][note] = [empty ] * self.total_length for start, pattern, lng in self.patterndata[trackname]: for note, timing in pattern: ## idx = int((start + timing) / shared.timing_unit) idx = (start + timing) // shared.timing_unit if is_drumtrack: notename = shared.get_inst_name(note + shared.octave_length + shared.note2drums) else: notename = shared.get_note_name(note + shared.octave_length) self.notes_data_dict[trackname][note][idx] = notename
def print_drumtrack(self, trackname, _out=sys.stdout): """collect the drumtrack events and print them pattern by pattern """ unlettered = set() for ix, pattdata in enumerate(self.patterndata_split[trackname]): pattern, pattlen = pattdata print(shared.patt_start.format(ix + 1), file=_out) events = collections.defaultdict(list) for pitch, ev in pattern: druminst = pitch + shared.octave_length + shared.note2drums notestr = shared.get_inst_name(druminst) if notestr == '?': unlettered.add('no letter yet for `{}`'.format( shared.gm_drums[druminst][1])) events[notestr].append(ev) for letter in shared.standard_printseq: printable = [shared.line_start] out = False for x in range(pattlen): if x in events[letter]: printable.append(letter) out = True else: printable.append(shared.empty_drums) if out: print(''.join(printable), file=_out) print('', file=_out) ## for x in unlettered: print(x, file=_out) return unlettered
def get_druminst_order(x): """helper function to determine order of drum instruments relies on standard sequence defined in settings """ y = shared.get_inst_name(x + shared.octave_length + shared.note2drums) return shared.standard_printseq.index(y)
def print_instrument(self, trackno, stream=sys.stdout): """print the events for an instrument as a piano roll trackno is the number of the midi track / sample to print data for stream is a file-like object to write the output to """ is_drumtrack = self.instruments[trackno][1] == shared.drum_channel for number, pattern in self.patterns[trackno]: print(shared.patt_start.format(number + 1), file=stream) unlettered = set() printables = [] for pitch in pattern: if not pattern[pitch]: continue if is_drumtrack: notestr = shared.get_inst_name(pitch + shared.note2drums) if notestr == '?': unlettered.add('no letter yet for `{}`'.format( shared.gm_drums[pitch - 35][1])) else: try: key = shared.standard_printseq.index(notestr) except ValueError: unlettered.add('{} not in standard printseq {}'.format( notestr, shared.standard_printseq)) else: notestr = shared.get_note_name(pitch) key = pitch printstr = [shared.line_start] index = 0 for event in pattern[pitch]: while index < event: printstr.append(shared.empty[is_drumtrack]) index += 1 printstr.append(notestr) index += 1 while index < shared.per_line: printstr.append(shared.empty[is_drumtrack]) index += 1 if not is_drumtrack: printstr[0] = printstr[0][:-1] printables.append((key, shared.sep[is_drumtrack].join(printstr))) printables.sort() if not is_drumtrack: printables.reverse() for key, line in printables: print(line, file=stream) print('', file=stream) for x in unlettered: print(x, file=stream) return unlettered
def prepare_print_instruments(self): """build complete timeline for (drum & regular) instrument events """ self.all_track_notes = collections.defaultdict( lambda: collections.defaultdict(list)) self.all_notevals = collections.defaultdict(set) self.total_length = 0 for trackno, trackdata in self.instruments.items(): is_drumtrack = trackdata[1] == shared.drum_channel patterns = dict(self.patterns[trackno]) for _, pattdict in self.patterns[trackno]: self.all_notevals[trackno].update([x for x in pattdict.keys()]) pattlist = [] seq = 0 for pattseq, pattnum in sorted(self.pattern_lists[trackno]): while pattseq > seq: pattlist.append((seq, -1)) seq += 1 pattlist.append((pattseq, pattnum)) seq += 1 for pattseq, pattnum in pattlist: if pattnum == -1: for note in self.all_notevals[trackno]: self.all_track_notes[trackno][note].extend( [shared.empty[is_drumtrack]] * shared.per_line) continue for note in self.all_notevals[trackno]: if note in patterns[pattnum]: events = patterns[pattnum][note] for tick in range(shared.per_line): if tick in events: if is_drumtrack: to_append = shared.get_inst_name(note + shared.note2drums) else: to_append = shared.get_note_name(note) else: to_append = shared.empty[is_drumtrack] self.all_track_notes[trackno][note].append(to_append) else: self.all_track_notes[trackno][note].extend( [shared.empty[is_drumtrack]] * shared.per_line) test = len(self.all_track_notes[trackno][note]) ## print(test) if test > self.total_length: self.total_length = test
def print_instrument(self, trackno, stream=sys.stdout): """print the events for an instrument as a piano roll trackno is the number of the track / sample to print data for stream is a file-like object to write the output to """ data = [] unlettered = set() for patt_no, props, patt_data in self.patterns[trackno]: data.append(shared.patt_start.format(patt_no)) is_drumtrack = props['drumtrack'] printables = collections.defaultdict(list) for key, note_events in patt_data.items(): seqnum = 0 events = [] if is_drumtrack: notestr = shared.get_inst_name(key + shared.note2drums) if notestr == '?': unlettered.add('no letter yet for `{}`'.format( shared.gm_drums[key + shared.note2drums][1])) else: key = shared.standard_printseq.index(notestr) else: notestr = shared.get_note_name(key) # (was - 12) factor = shared.tick_factor for i in range(factor * (note_events[-1] // factor + 1)): if i in note_events: events.append(notestr) else: events.append(shared.empty[is_drumtrack]) if (i + 1) % factor == 0: seqnum += 1 if events != factor * [shared.empty[is_drumtrack]]: delim = shared.sep[is_drumtrack] printables[seqnum].append( (key, delim.join(events))) events = [] for key, pattern_lines in sorted(printables.items()): printlines = sorted(pattern_lines) if not is_drumtrack: printlines = reversed(printlines) data.extend([shared.line_start + y for x, y in printlines]) data.append('') for line in data: print(line, file=stream) return unlettered
def print_all_instruments_full(self, instlist, opts, stream=sys.stdout): """output all instrument timelines to the "general" file instlist indicates the top-to-bottom sequence of instruments opts indicates how many events per line and whether to print "empty" lines """ interval, clear_empty = opts inst2sam = {y[0]: (x, y) for x, y in self.instruments.items()} for eventindex in range(0, self.total_length, interval): for instname in instlist: trackno, trackdata = inst2sam[instname] is_drumtrack = trackdata[1] == shared.drum_channel empty_line = shared.sep[is_drumtrack].join( interval * [shared.empty[is_drumtrack]]) if eventindex + interval > self.total_length: empty_line = shared.sep[is_drumtrack].join( (self.total_length - eventindex) * [shared.empty[is_drumtrack]]) all_track_notes = self.all_track_notes[trackno] all_notevals = self.all_notevals[trackno] if is_drumtrack: notes_to_show = [x for x in sorted( all_notevals, key=lambda x: shared.standard_printseq.index( shared.get_inst_name(x + shared.note2drums)))] print('drums:', file=stream) else: notes_to_show = [x for x in reversed(sorted(all_notevals))] print('{}:'.format(instname), file=stream) not_printed = True for note in notes_to_show: notes = all_track_notes[note] line = shared.sep[is_drumtrack].join( notes[eventindex:eventindex + interval]) if clear_empty and (line == empty_line or not line): pass else: print(' ', line, file=stream) not_printed = False if not_printed: print(' ', shared.empty[is_drumtrack], file=stream) print('', file=stream) print('', file=stream)
def print_instrument_full(self, trackno, opts, stream=sys.stdout): """output an instrument timeline to a separate file/stream trackno indicates the instrument to process opts indicates how many events per line and whether to print "empty" lines """ interval, clear_empty = opts is_drumtrack = self.instruments[trackno][1] == shared.drum_channel all_track_notes = self.all_track_notes[trackno] ## all_notevals = self.all_notevals[trackno] if is_drumtrack: interval *= 2 notes_to_show = [x for x in sorted( self.all_notevals[trackno], key=lambda x: shared.standard_printseq.index(shared.get_inst_name( x + shared.note2drums)))] else: notes_to_show = [x for x in reversed(sorted(self.all_notevals[trackno]))] empty_line = shared.sep[is_drumtrack].join( interval * [shared.empty[is_drumtrack]]) for eventindex in range(0, self.total_length, interval): if eventindex + interval > self.total_length: empty_line = shared.sep[is_drumtrack].join( (self.total_length - eventindex) * [shared.empty[is_drumtrack]]) not_printed = True for note in notes_to_show: notes = all_track_notes[note] line = shared.sep[is_drumtrack].join( notes[eventindex:eventindex + interval]) if clear_empty and (line == empty_line or not line): pass else: print(line, file=stream) not_printed = False if not_printed: print(shared.empty[is_drumtrack], file=stream) print('', file=stream)
def prepare_print_instruments(self): """build complete timeline for (drum and regular) instrument events """ self.all_note_tracks = collections.defaultdict( lambda: collections.defaultdict(list)) self.unlettered = set() self.all_notes = collections.defaultdict(set) # volgens mij moet ik hier weer uitgaan van de oldpatterns om daaruit een volledig track # op te bouwen # pattern lengtes zijn inmiddels toegevoegd in oldpatternlist, die kan ik gebruiken voor de # totale lengte self.total_length = 0 for trackno in self.instruments: pattno, pattstart, pattlen = self.old_pattern_list[trackno][-1] log('{}'.format(trackno, pattno, pattstart, pattlen)) if pattstart + pattlen > self.total_length: self.total_length = pattstart + pattlen log('self.total_length wordt {}'.format(self.total_length)) # determine highest event on track for events in self.old_patterns[trackno][-1][2].values(): last_event = events[-1] if pattstart + last_event == self.total_length: self.total_length += 1 log('self.total_length wordt {}'.format(self.total_length)) test = self.total_length // 32 if test * 32 != self.total_length: self.total_length = (test + 1) * 32 log('{} {}'.format(test, self.total_length)) for trackno in self.instruments: is_drumtrack = self.old_patterns[trackno][0][1]['drumtrack'] pattdict = {} # determine all notes used on this track and "buffer" the pattern data for pattnum, _, pattdata in self.old_patterns[trackno]: self.all_notes[trackno].update(pattdata.keys()) pattdict[pattnum] = pattdata # fill al the gaps between patterns beforehand for note in self.all_notes[trackno]: if is_drumtrack: notestr = shared.get_inst_name(note + shared.note2drums) self.all_note_tracks[trackno][ notestr] = self.total_length * [ shared.empty[is_drumtrack] ] else: self.all_note_tracks[trackno][note] = self.total_length * [ shared.empty[is_drumtrack] ] # fill in the separate events for item in self.old_pattern_list[trackno]: if len(item) == 2: # < 3 continue # no events found, so no length recorded pattnum, pattstart = item[:2] for note in self.all_notes[trackno]: if is_drumtrack: notestr = shared.get_inst_name(note + shared.note2drums) if notestr == '?': self.unlettered.add( 'no letter yet for `{}`'.format( shared.gm_drums[note + shared.note2drums][1])) else: notestr = shared.get_note_name(note) if note not in pattdict[pattnum]: continue for event in pattdict[pattnum][note]: ## log('track {} patt {} start {} note {} event {}'.format( ## trackno, pattnum, pattstart, note, event)) ix = notestr if is_drumtrack else note event += pattstart ## log('{} {} {}'.format( ## ix, len(self.all_note_tracks[trackno][ix]), event)) ## if evt == len(self.all_note_tracks[trackno][ix]): ## for ix2 in self.all_note_tracks[trackno] self.all_note_tracks[trackno][ix][event] = notestr