def prepare_harm_input(in_path, outfile): "Prepares and encodes a musicXML file containing a monophonic melody line as a Soprano voice to harmonize." txt_to_utf, utf_to_txt = build_vocabulary() txt_to_utf[ BLANK_MASK_TXT] = BLANK_MASK_UTF # don't add to `utf_to_txt` because samples should never contain BLANK_MASK sc = converter.parseFile(in_path) encoded_score = [] for note in sc.flat.notesAndRests: if note.isRest: encoded_score.extend( (int(note.quarterLength * FRAMES_PER_CROTCHET)) * [[]]) else: has_fermata = any( map(lambda e: e.isClassOrSubclass(('Fermata', )), note.expressions)) has_tie = note.tie is not None and note.tie.type != 'start' encoded_chord = [(note.pitch.midi, has_tie) ] + ([BLANK_MASK_TXT for _ in range(3)]) encoded_score.append((has_fermata, encoded_chord)) encoded_score.extend( (int(note.quarterLength * FRAMES_PER_CROTCHET) - 1) * [(has_fermata, map( lambda note: BLANK_MASK_TXT if note == BLANK_MASK_TXT else (note[0], True), encoded_chord))]) outfile.write(to_utf(txt_to_utf, to_text(encoded_score)))
def open_score(self, midi_file_to_open): # open midifile after manipulating duration data self.delta_change(midi_file_to_open) print("\n\n\nNow I'm going to print you the score\n\n\n") # convert to lily.png note_list = [] parts_stream = stream.Stream() parts_stream.insert(0, clef.TrebleClef()) # parts_stream.insert(0, meter.TimeSignature('8/4')) score_in = converter.parseFile( midi_file_to_open) # converts to a music21.stream.score # seperates out notes from rest of stream and makes notes_list for shuffle for n in score_in.recurse().notes: # print (f'Note: {n.pitch.name}, {n.pitch.octave}. {n.duration.quarterLength}') if n.duration.quarterLength != 0: # if note length is not 0 then add to list of notes note_list.append(n) for i, nt in enumerate(note_list): note_pop = note_list[i] parts_stream.append(note_pop) png_fp = 'data/output/png-' + self.current_time parts_stream.write('lily.png', fp=png_fp) return str(png_fp + '.png')
def parse_midi_files(midi_dir, args): notes = [] files = [] for file in glob.glob(midi_dir + "/*.mid"): files.append(os.path.dirname(os.path.realpath(__file__)) + "/" + file) k = 1 for file in glob.glob(midi_dir + "/*.mid"): print("Parse file {} {}/{}".format(file, k, len(files))) midi = converter.parseFile( os.path.dirname(os.path.realpath(__file__)) + "/" + file) midi = midi[0] notes_to_parse = None try: s2 = instrument.partitionByInstrument(midi) notes_to_parse = s2.parts[0].recurse() except: notes_to_parse = midi.flat.notes i = 1 for element in notes_to_parse: if isinstance(element, note.Note): notes.append(str(element.pitch)) elif isinstance(element, chord.Chord): # print('Akord {}'.format(element.pitchNames[0])) # notes.append(element.pitchNames[0]) notes.append(".".join(str(n) for n in element.pitchNames)) i += 1 k += 1 with open(args.out_file, 'wb') as fw: pickle.dump(notes, fw) return notes
def convertTrackNoInstruments(filepath): stream = converter.parseFile(filepath) notes_to_parse = None if stream: # file has instrument parts #stream.show("text") print(len(stream)) noteMat = getNoteMatrix(stream.recurse()) return noteMat if notes_to_parse is None: print("No instruments to parse") return
def elements(cls, midi_file): ''' Get the individual elements (notes, rests, etc) from the score ''' score = converter.parseFile(midi_file) assert len(score.elements) == 1, 'midi not in expected format: multiple Parts' part = score[0] assert type(part) == music21.stream.Part, 'midi not in expected format: score not composed of parts' return score[0].elements
def importMIDI(f): piece = converter.parseFile(f) all_parts = {} k = 0 for part in piece.parts: print(part) try: track_name = part[0].bestName() except AttributeError: track_name = str(k) cur_part = get_pianoroll_part(part, 16) if (cur_part.shape[1] > 0): all_parts[track_name] = cur_part k += 1 print('Returning') return piece, all_parts
def elements(cls, midi_file): ''' Get the individual elements (notes, rests, etc) from the score ''' # print midi_file try: score = converter.parseFile(midi_file) except: return False assert len(score.elements) == 1, 'midi not in expected format: multiple Parts' part = score[0] assert type(part) == music21.stream.Part, 'midi not in expected format: score not composed of parts' # for v in part[3]: # print v # return part[2].elements part.flattenUnnecessaryVoices(force=True) return part.elements
from music21.interval import Interval from music21.pitch import Pitch from music21.converter import parseFile from os.path import basename import re import sys import subprocess def get_key(filename): with open(filename, 'r') as f: lines = f.readlines() key_line = [l for l in lines if l.startswith('K:')] def get_interval(key): if key.mode == 'major': return Interval(key.tonic, Pitch('C')) if key.mode == 'minor': return Interval(key.tonic, Pitch('A')) return None for filename in sys.argv[1:]: score = parseFile(filename) key = score.analyze('key') interval = get_interval(key) score.transpose(interval) score.write('musicxml', basename(filename) + '_Cdur.xml') print('Transposed {0} from {1} to {2}'.format(filename, key, key.transpose(interval)))
'A#': 'B-', 'B#': 'C', 'C-': 'B', 'D-': 'C#', 'D#': 'E-', 'E#': 'F', 'F-': 'E', 'G-': 'F#' } for file in os.listdir(dir_): if file.split('.')[-1] != 'mid': continue try: midi = converter.parseFile(dir_ + '/' + file) except: print('Could not parse ' + file) continue offset = 0 stop = midi.highestTime song_melody = [] song_chords = [] while offset < stop: cur_melody = [] cur_chords = [] all_notes = midi.recurse().getElementsByOffsetInHierarchy( offset, offsetEnd=offset + sixteenth,
def append(self, corpus_path=None, corpus_str=None, d_score=None, header_path=None, header_str=None, as_xml=True, title=None): corpus_type = None if corpus_path: corpus_type = DCorpus.corpus_type(corpus_path=corpus_path) if corpus_type in [Constant.CORPUS_ABC, Constant.CORPUS_ABCD]: corpus_str = DCorpus.file_to_string(corpus_path) if header_path: header_str = DCorpus.file_to_string(header_path) abcd_header = None abc_body = '' if corpus_type == Constant.CORPUS_MIDI: score = converter.parseFile(corpus_path) score_title = title if score_title is None: score_title = os.path.basename(corpus_path) score_title = score_title.split(sep='.')[0] da_score = DScore(music21_stream=score, segmenter=self.segmenter(), abcd_header=abcd_header, title=score_title) self._d_scores.append(da_score) if d_score: self._d_scores.append(d_score) abc_handle = None staff_assignments = [] if corpus_str: corpus_type = DCorpus.corpus_type(corpus_str=corpus_str) if corpus_type == Constant.CORPUS_ABCD and not header_str: header_str = corpus_str if header_str: abcd_header = DCorpus.abcd_header(string=header_str) if corpus_type in [Constant.CORPUS_ABC, Constant.CORPUS_ABCD]: abc_body = DCorpus.abc_body_str(string=corpus_str) if as_xml: corpus_str = DCorpus.abc2xml(abc_content=corpus_str) corpus_type = DCorpus.corpus_type(corpus_str=corpus_str) if corpus_type in [Constant.CORPUS_ABC, Constant.CORPUS_ABCD]: # NOTE: We only do this if we are not using the XML transform. # THIS IS NOT RECOMMENDED. # The abc conversion does not manage the grouping of voices into # the appropriate part (staff), so we hack around this shortcoming. self._abc_strings.append(corpus_str) abc_file = abcFormat.ABCFile(abcVersion=(2, 1, 0)) staff_assignments = DCorpus._score_staff_assignments(abc_content=corpus_str) abc_handle = abc_file.readstr(corpus_str) else: # THIS IS WHERE WE SHOULD BE. corp = converter.parse(corpus_str) if isinstance(corp, stream.Opus): for score in corp: da_score = DScore(music21_stream=score, segmenter=self.segmenter()) self._d_scores.append(da_score) else: score = corp da_score = DScore(music21_stream=score, segmenter=self.segmenter(), abcd_header=abcd_header, abc_body=abc_body) self._d_scores.append(da_score) else: return False if corpus_type in [Constant.CORPUS_ABC, Constant.CORPUS_ABCD]: # WARNING: abc parsing is NOT recommended ah_for_id = abc_handle.splitByReferenceNumber() if len(staff_assignments) > 0 and len(staff_assignments) != len(ah_for_id): # We must know how to map all voices to a staff. Either all scores (tunes) # in corpus must have two or fewer voices, or we need a map. For simplicity, # we make this an all-or-nothing proposition. If any score in the corpus # needs a map, they all must provide one. For two voices, this would # look like this: # # %%score { ( 1 ) | ( 2 ) } raise Exception("All abc scores in corpus must have %%score staff assignments or none should.") score_index = 0 for score_id in ah_for_id: if len(staff_assignments) > 0: da_score = DScore(abc_handle=ah_for_id[score_id], abcd_header=abcd_header, abc_body=abc_body, voice_map=staff_assignments[score_index], segmenter=self.segmenter()) else: da_score = DScore(abc_handle=ah_for_id[score_id], abcd_header=abcd_header, abc_body=abc_body, segmenter=self.segmenter()) self._d_scores.append(da_score) score_index += 1
def loadScore(filename): return converter.parseFile(filename)
from music21 import converter, environment filepath = 'data/chpn_op66.mid' # fixing musescore path on my machine ''' us = environment.UserSettings() us['musescoreDirectPNGPath'] = '/Applications/MuseScore 3.app/Contents/MacOS/mscore' us['musicxmlPath'] = '/Applications/MuseScore 3.app/Contents/MacOS/mscore' for key in sorted(us.keys()): print(key, "is", us[key]) ''' #def map_notes(): score = converter.parseFile(filepath) # Returns Stream object score.show('text')