def notate_note(self, note): if note['pitch'] == 'rest': n = Rest() else: if isinstance(note['pitch'], list): pitches = [] for pitch_number in note['pitch']: p = Pitch(pitch_number) # Force all flats if p.accidental.name == 'sharp': p = p.getEnharmonic() pitches.append(p) n = Chord(notes=pitches) else: p = Pitch(note['pitch']) # Force all flats if p.accidental.name == 'sharp': p = p.getEnharmonic() n = Note(p) d = Duration() if note['duration'] == 0: d.quarterLength = .125 d = d.getGraceDuration() else: d.fill(note['durations']) n.duration = d return n
def notate_score(musician_names, instrument_names, music): score = Score() for musician_name, instrument_name in zip(musician_names, instrument_names): instrument = get_instrument(instrument_name) instrument.partName = instrument.instrumentName instrument.partAbbreviation = instrument.instrumentAbbreviation parts = [] part = Part() parts.append(part) part.insert(0, instrument) score.insert(0, part) score.insert(0, StaffGroup(parts)) notes = music[musician_name] for pitches in notes: if not pitches or pitches == 'stop': note = Rest() elif len(pitches) == 1: pitch = Pitch(pitches[0] + 60) note = Note(pitch) else: note = Chord(notes=[Pitch(p + 60) for p in pitches]) duration = Duration() duration.fill([4.0]) note.duration = duration part.append(note) score.show('musicxml', '/Applications/Sibelius 7.5.app')
def generate_notes_in_batch(note_params_df, output_dir, audio_format='flac', sample_rate=44100): """ Generates a batch of single note samples from the given table of parameters. `note_params_df` - a Pandas Dataframe with columns: `midi_number, midi_instrument, volume, duration, tempo`. Their meaning is the same as in generate_single_note. `output_dir` - output directory for the MIDI files Each sample goes to a single MIDI file named by the numeric index. Also each synthesized audio sample goes to a """ os.makedirs(output_dir, exist_ok=True) fs = FluidSynth(sample_rate=sample_rate) stream = Stream() for i, row in note_params_df.iterrows(): stream.append(MetronomeMark(number=row['tempo'])) stream.append(make_instrument(int(row['midi_instrument']))) duration = row['duration'] stream.append( chord_with_volume( Chord([ Note(midi=int(row['midi_number']), duration=Duration(duration)) ]), row['volume'])) stream.append(Rest(duration=Duration(2 * duration))) midi_file = '{0}/all_samples.midi'.format(output_dir) audio_file_stereo = '{0}/all_samples_stereo.{1}'.format( output_dir, audio_format) audio_file = '{0}/all_samples.{1}'.format(output_dir, audio_format) audio_index_file = '{0}/all_samples_index.csv'.format(output_dir) # TODO: We currently assume some fixed duration and tempo (1.0, 120)!!! # The parts should be split according to an index. audio_index = make_audio_index(note_params_df, 3.0, 0.5, sample_rate) audio_index.to_csv(audio_index_file) write_midi(stream, midi_file) fs.midi_to_audio(midi_file, audio_file_stereo) convert_to_mono(audio_file_stereo, audio_file) os.remove(audio_file_stereo) x, sample_rate = sf.read(audio_file) parts = split_audio_to_parts(x, sample_rate, audio_index) store_parts_to_files(parts, sample_rate, output_dir, audio_format)
def write_notation_cell(music, path, event_index): score = Score() metadata = Metadata() metadata.title = '' metadata.composer = '' score.insert(0, metadata) layout = ScoreLayout() layout.scalingMillimeters = 1.25 layout.scalingTenths = 40 score.insert(0, layout) for musician in music: instrument_name = musician['instrument'] instrument = get_instrument(instrument_name) instrument.partName = instrument.instrumentName if instrument.instrumentName is 'Violoncello': instrument.partName = 'Cello' instrument.partAbbreviation = instrument.instrumentAbbreviation parts = [] part = Part() parts.append(part) part.insert(0, instrument) score.insert(0, part) # score.insert(0, StaffGroup(parts)) for event in musician['music']: pitches = event['pitches'] dur = event['duration'] # if not pitches or pitches == 'stop': # note = Rest() if len(pitches) == 1: pitch = Pitch(pitches[0] + 60) note = Note(pitch) else: note = Chord(notes=[Pitch(p + 60) for p in pitches]) duration = Duration() duration.fill([dur]) note.duration = duration part.append(note) file_path = os.path.join(path, str(event_index).zfill(2)) musicxml_file_path = file_path + '.xml' png_output_file_path = file_path + '.png' score.write('musicxml', musicxml_file_path) write_png_with_musescore(musicxml_file_path, png_output_file_path, dpi=600)
def make_music21_note( pitch_number=None, duration=1.0, staccato=False, tenuto=False, accent=False, falloff=False, plop=False, scoop=False, doit=False, breath_mark=False, ): if pitch_number == None or pitch_number == 'rest': n = Rest() elif isinstance(pitch_number, list): pitches = [Pitch(p) for p in pitch_number] for p in pitches: if p.accidental.name is 'natural': p.accidental = None n = Chord(pitches) else: p = Pitch(pitch_number) if p.accidental.name is 'natural': p.accidental = None n = Note(p) d = Duration() d.quarterLength = duration n.duration = d if staccato: n.articulations.append(Staccato()) if tenuto: n.articulations.append(Tenuto()) if accent: n.articulations.append(Accent()) if falloff: n.articulations.append(Falloff()) if plop: n.articulations.append(Plop()) if scoop: n.articulations.append(Scoop()) if doit: n.articulations.append(Doit()) if breath_mark: n.articulations.append(BreathMark()) return n
def to_musicxml(sc_enc): "Converts Chord tuples (see chorales.prepare_poly) to musicXML" timestep = Duration(1. / FRAMES_PER_CROTCHET) musicxml_score = Stream() prev_chord = dict( ) # midi->(note instance from previous chord), used to determine tie type (start, continue, stop) for has_fermata, chord_notes in sc_enc: notes = [] if len(chord_notes) == 0: # no notes => rest for this frame r = Rest() r.duration = timestep musicxml_score.append(r) else: for note_tuple in chord_notes: note = Note() if has_fermata: note.expressions.append(expressions.Fermata()) note.midi = note_tuple[0] if note_tuple[1]: # current note is tied note.tie = Tie('stop') if prev_chord and note.pitch.midi in prev_chord: prev_note = prev_chord[note.pitch.midi] if prev_note.tie is None: prev_note.tie = Tie('start') else: prev_note.tie = Tie('continue') notes.append(note) prev_chord = {note.pitch.midi: note for note in notes} chord = Chord(notes=notes, duration=timestep) if has_fermata: chord.expressions.append(expressions.Fermata()) musicxml_score.append(chord) return musicxml_score
def generate(self, seq_len, a_par=0): pattern = self.model_inp[self.start] prediction_output = [] for note_index in range(seq_len): prediction_input = pattern.reshape(1, seq_len, 2, len(self.sorted_notes)) prediction_input = prediction_input / float(len(self.sorted_notes)) predictions = self.model.predict(prediction_input, verbose=0)[0] for prediction in predictions: index = np.argmax(prediction[0]) duration_i = np.argmax(prediction[1]) for name, value in self.sorted_notes.items(): if value == index: result = name break else: result = None for name, value in self.sorted_durations.items(): if value == duration_i: duration = name break else: duration = None prediction_output.append((result, Duration(duration))) result = np.zeros_like(prediction) result[0][index] = 1 result[1][duration_i] = 1 pattern = np.concatenate([pattern, [result]]) pattern = pattern[len(pattern) - seq_len:len(pattern)] offset = 0 output_notes = [] for pattern, duration in prediction_output: if pattern.isdigit() or ('.' in pattern): notes_in_chord = pattern.split('.') notes = [] for current_note in notes_in_chord: new_note = Note(int(current_note)) new_note.duration = duration new_note.storedInstrument = instrument.PanFlute() notes.append(new_note) new_chord = Chord(notes) new_chord.offset = offset output_notes.append(new_chord) else: new_note = Note(pattern) new_note.offset = offset new_note.storedInstrument = instrument.Flute() output_notes.append(new_note) offset += 0.6 midi_stream = stream.Stream(output_notes) midi_stream.write('midi', fp=f'my_music/{self.model.name}_{self.start}.mid')
def make_music21_score( part_names=('violin', 'flute', 'oboe', 'clarinet', 'alto_saxophone', 'trumpet', 'bass', 'percussion'), title='Title', composer='Jonathan Marmor', time_signature=None, starting_tempo_bpm=60, starting_tempo_quarter_duration=1.0, timestamp=None, ): if not timestamp: timestamp = datetime.datetime.utcnow() metadata = Metadata() metadata.title = title metadata.composer = composer metadata.date = timestamp.strftime('%Y/%m/%d') score = Score() score.insert(0, metadata) for part_name in part_names: instrument_name, instrument_number = parse_part_name(part_name) instrument = instrument_data[instrument_name] part = Part() metronome_mark = MetronomeMark( number=starting_tempo_bpm, referent=Duration(starting_tempo_quarter_duration)) part.append(metronome_mark) if time_signature: # Should be a string like '12/8' music21_time_signature = TimeSignature(time_signature) part.append(music21_time_signature) m21_instrument = instrument['class']() m21_instrument.partName = instrument['name'] m21_instrument.partAbbreviation = instrument['abbreviation'] if instrument_number > 1: m21_instrument.partName = '{} {}'.format(instrument['name'], instrument_number) m21_instrument.partAbbreviation = '{} {}'.format( instrument['abbreviation'], instrument_number) part.insert(0, m21_instrument) clef = instrument.get('clef') if clef: part.append(clef()) score.insert(0, part) return score
def notate_note(note): if note['pitch'] == 'rest': n = Rest() else: if isinstance(note['pitch'], list): pitches = [] for pitch_number in note['pitch']: p = Pitch(pitch_number) # Force all flats if p.accidental.name == 'sharp': p = p.getEnharmonic() pitches.append(p) n = Chord(notes=pitches) else: p = Pitch(note['pitch']) # Force all flats if p.accidental.name == 'sharp': p = p.getEnharmonic() n = Note(p) d = Duration() if note['duration'] == 0: d.quarterLength = .125 d = d.getGraceDuration() else: # music21 docs say `fill` is for testing. I can't remember why I chose # to use it originally. It works. But not for tuplets. Maybe this blog # post contains a better solution: # http://music21-mit.blogspot.com/2015/09/durations-and-durationtuples.html d.fill(note['durations']) n.duration = d return n
def test(): stream = Stream() n1 = Note('C4', duration=Duration(1.5)) n2 = Note('D4', duration=Duration(0.5)) n3 = Note('E4') n4 = Note('F4') n5 = Note('G4') n6 = Note('A4') n7 = Note('C4') n8 = Note('D4').getGrace() n9 = Note('E4').getGrace() n10 = Note('F4') n11 = Note('G4') n12 = Note('A4', duration=Duration(0.5)) n13 = Note('A4', duration=Duration(0.5)) gliss1 = Glissando([n2, n3]) gliss2 = Glissando([n5, n6]) gliss3 = Glissando([n6, n7]) gliss4 = Glissando([n8, n9]) slur1 = Slur([n2, n3]) slur2 = Slur([n6, n7]) slur3 = Slur([n9, n10]) stream.append([n1, n2, n3, n4, n5, n6, n7, n8, n9, n10, n11, n12, n13]) stream.insert(0, gliss1) stream.insert(0, gliss2) stream.insert(0, gliss3) stream.insert(0, gliss4) stream.insert(0, slur1) stream.insert(0, slur2) stream.insert(0, slur3) return stream
def generate_single_note(midi_number, midi_instrument=0, volume=1.0, duration=1.0, tempo=120): """ Generates a stream containing a single note with given parameters. midi_number - MIDI note number, 0 to 127 midi_instrument - MIDI intrument number, 0 to 127 duration - floating point number (in quarter note lengths) volume - 0.0 to 1.0 tempo - number of quarter notes per minute (eg. 120) Note that there's a quarter note rest at the beginning and at the end. """ return Stream([ MetronomeMark(number=tempo), make_instrument(int(midi_instrument)), chord_with_volume( Chord([Note(midi=int(midi_number), duration=Duration(duration))]), volume) ])
def append_chord(part, notes, duration, velocity): c = Chord(notes, duration=Duration(duration)) c.volume = Volume(velocity=velocity) part.append(c)
def __init__(self, ranges=False): score = self.score = Score() self.instruments = self.i = Instruments() self.parts = Parts(self.i) # Make Metadata timestamp = datetime.datetime.utcnow() metadata = Metadata() metadata.title = 'Early Montreal' metadata.composer = 'Jonathan Marmor' metadata.date = timestamp.strftime('%Y/%m/%d') score.insert(0, metadata) [score.insert(0, part) for part in self.parts.l] score.insert(0, StaffGroup(self.parts.l)) if ranges: # Don't make a piece, just show the instrument ranges for inst, part in zip(self.instruments.l, self.parts.l): measure = Measure() measure.timeSignature = TimeSignature('4/4') low = Note(inst.lowest_note) measure.append(low) high = Note(inst.highest_note) measure.append(high) part.append(measure) return # 18 to 21 minutes piece_duration_minutes = scale(random.random(), 0, 1, 18, 21) # Make the "songs" songs = [] total_minutes = 0 n = 1 while total_minutes < piece_duration_minutes: print 'Song {}'.format(n) n += 1 song = Song(self) songs.append(song) total_minutes += song.duration_minutes # Make notation previous_duration = None for song in songs: for bar in song.bars: for part in bar.parts: measure = Measure() if bar.tempo: measure.insert( 0, MetronomeMark(number=bar.tempo, referent=Duration(1))) measure.leftBarline = 'double' if bar.duration != previous_duration: ts = TimeSignature('{}/4'.format(bar.duration)) measure.timeSignature = ts # Fix Durations durations = [note['duration'] for note in part['notes']] components_list = split_at_beats(durations) components_list = [ join_quarters(note_components) for note_components in components_list ] for note, components in zip(part['notes'], components_list): note['durations'] = components for note in part['notes']: if note['pitch'] == 'rest': n = Rest() if isinstance(note['pitch'], list): pitches = [] for pitch_number in note['pitch']: p = Pitch(pitch_number) # Force all flats if p.accidental.name == 'sharp': p = p.getEnharmonic() pitches.append(p) n = Chord(notes=pitches) # TODO add slurs # TODO add glissandos # TODO add -50 cent marks else: p = Pitch(note['pitch']) # Force all flats if p.accidental.name == 'sharp': p = p.getEnharmonic() n = Note(p) # TODO add slurs # TODO add glissandos # TODO add -50 cent marks d = Duration() if note['duration'] == 0: d.quarterLength = .5 d = d.getGraceDuration() else: d.fill(note['durations']) n.duration = d measure.append(n) self.parts.d[part['instrument_name']].append(measure) previous_duration = bar.duration
def build_midi(harmony, melody): chords_dict = get_chord_dicts()[1] song = [] for i, eighth in enumerate(melody): # eighth = multi_hot_to_pianoroll(piano_roll[:midi_range]) # now make_music returns pianorolls already # chord = one_hot_to_index(piano_roll[-chord_classes:]) # TODO add chord to midi # print(f'EIGHTH: {eighth}') # DEBUG song_notes = [] for note_ in eighth: note_name = NOTES[note_%12] note_octave = start_octave + note_//12 # starting from C2 song_notes.append(note_name + str(note_octave)) song_chords = [] full_chord = chords_dict[harmony[i]] if full_chord != '<unk>': for chord_ in full_chord: chord_name = NOTES[chord_%12] song_chords.append(chord_name + str(start_octave-1)) song.append(("REST" if len(song_notes) == 0 else song_notes, "REST" if len(song_chords) == 0 else song_chords)) notes_score = Score() notes_score.append(instrument.Piano()) chords_score = Score() chords_score.append(instrument.KeyboardInstrument()) bass_score = Score() bass_score.append(instrument.ElectricBass()) current_note_length = 0 current_chord_length = 0 for i, _ in enumerate(song): current_note_length += 0.5 current_chord_length += 0.5 # print(f'NOTE: {song[i][0]}\t\t\t- CHORD: {song[i][1]}') if i < len(song)-1: # note if song[i][0] != song[i+1][0]: if song[i][0] == "REST": notes_score.append(note.Rest(duration=Duration(current_note_length))) else: notes_score.append(chord.Chord([note.Note(nameWithOctave=note_name) for note_name in song[i][0]], duration=Duration(current_note_length))) current_note_length = 0 # chord if song[i][1] != song[i+1][1] or current_chord_length == 4: if song[i][1] == "REST": chords_score.append(note.Rest(duration=Duration(current_chord_length))) bass_score.append(note.Rest(duration=Duration(current_chord_length/4))) bass_score.append(note.Rest(duration=Duration(current_chord_length/4))) bass_score.append(note.Rest(duration=Duration(current_chord_length/2))) else: chords_score.append(chord.Chord([note.Note(nameWithOctave=chord_name) for chord_name in song[i][1]], duration=Duration(current_chord_length))) bass_score.append(chord.Chord([note.Note(nameWithOctave=chord_name[:-1]+str(int(chord_name[-1])+1)) for chord_name in song[i][1]], duration=Duration(current_chord_length/4))) bass_score.append(chord.Chord([note.Note(nameWithOctave=chord_name[:-1]+str(int(chord_name[-1])+1)) for chord_name in song[i][1]], duration=Duration(current_chord_length/4))) bass_score.append(chord.Chord([note.Note(nameWithOctave=chord_name[:-1]+str(int(chord_name[-1])+1)) for chord_name in song[i][1]], duration=Duration(current_chord_length/2))) current_chord_length = 0 else: # note if song[i][0] == "REST": notes_score.append(note.Rest(duration=Duration(current_note_length))) else: notes_score.append(chord.Chord([note.Note(nameWithOctave=note_name) for note_name in song[i][0]], duration=Duration(current_note_length))) # chord if song[i][1] == "REST": chords_score.append(note.Rest(duration=Duration(current_chord_length))) bass_score.append(note.Rest(duration=Duration(current_chord_length/4))) bass_score.append(note.Rest(duration=Duration(current_chord_length/4))) bass_score.append(note.Rest(duration=Duration(current_chord_length/2))) else: chords_score.append(chord.Chord([note.Note(nameWithOctave=chord_name) for chord_name in song[i][1]], duration=Duration(current_chord_length))) bass_score.append(chord.Chord([note.Note(nameWithOctave=chord_name[:-1]+str(int(chord_name[-1])+1)) for chord_name in song[i][1]], duration=Duration(current_chord_length/4))) bass_score.append(chord.Chord([note.Note(nameWithOctave=chord_name[:-1]+str(int(chord_name[-1])+1)) for chord_name in song[i][1]], duration=Duration(current_chord_length/4))) bass_score.append(chord.Chord([note.Note(nameWithOctave=chord_name[:-1]+str(int(chord_name[-1])+1)) for chord_name in song[i][1]], duration=Duration(current_chord_length/2))) song_stream = Stream() song_stream.insert(0, notes_score) song_stream.insert(0, chords_score) song_stream.insert(0, bass_score) if not os.path.exists('melodies'): os.makedirs('melodies') dt = datetime.now().strftime("%Y-%m-%d_%H-%M-%S") song_stream.write('midi', fp=f'melodies/generated_{dt}.mid')
from collections import namedtuple import music21 from music21.chord import Chord from music21.note import Note from music21.duration import Duration from music21.interval import notesToChromatic # Cannot use name 'Chord', already taken HarmonyChord = namedtuple('HarmonyChord', ['name', 'notes']) WHOLE_NOTE = Duration(4.0) # How bad a interval sounds (given number of semitones) CHROMATIC_PENALTY = { 0: 0, 1: 2, 2: 1, 3: 0, 4: 0, 5: 0, 6: 2, } C_MAJ = HarmonyChord(name='C', notes=['c3', 'e3', 'g3', 'c4']) G_MAJ = HarmonyChord(name='G', notes=["g2", "b2", "d3", "g3"]) A_MIN = HarmonyChord(name='Am', notes=["a2", "c3", "e3", "a3"]) B_MIN = HarmonyChord(name='Bm', notes=["b2", "d3", "f#3", "b3"]) D_MAJ = HarmonyChord(name='D', notes=["d3", "f#3", "a3", "d4"]) E_MIN = HarmonyChord(name='Em', notes=["e3", "g3", "b3", "e4"]) F_MAJ = HarmonyChord(name='F', notes=["f2", "a2", "c3", "f3"])
def generate(tune, clef=m21.clef.TrebleClef()): # Load in the score score = m21utils.loadScoreForTune(tune) # Some basic preprocessing / cleanup score.parts[0].removeByClass('Instrument') score.parts[0].partName = None m21.harmony.realizeChordSymbolDurations(score) ## Argh!!! # Go measure by measure and build the study measures = score.parts[0].getElementsByClass("Measure") for measure in measures: # print measure # Remove any existing notes in the measure (we're about to add our own) measure.removeByClass('Note') # Grab the list of chord symbols in this measure chordSymbols = measure.getElementsByClass( 'ChordSymbol').matchingElements() # Remove the chord symbols so we can add them back interleaved with the notes # we're about to add measure.removeByClass('ChordSymbol') # Add notes for each chord symbol for symbol in chordSymbols: measure.append(symbol) # print symbol.duration.quarterLength n3 = Note(symbol.third) n3.duration = Duration(symbol.duration.quarterLength * 0.50) n3.octave = 5 n3.lyric = '3' measure.append(n3) if (symbol.containsSeventh()): n7 = m21.note.Note(symbol.seventh) n7.duration = Duration(symbol.duration.quarterLength * 0.50) n7.lyric = '7' n7.octave = 5 measure.append(n7) else: n5 = m21.note.Note(symbol.root()) n5.duration = Duration(symbol.duration.quarterLength * 0.50) n5.lyric = 'R' n5.octave = 5 measure.append(n5) # TODO: don't think this is needed # if measure.number % 4 == 0: # measure.append(m21.layout.SystemLayout(isNew=True)) # for x in range(len(c)): # MyMeasure = Measure() ## Make a measure and put everything inside it # MyMeasure.number = m.number ## give the measure a number # MyMeasure.rightBarline = m.rightBarline # MyMeasure.leftBarline = m.leftBarline # # print("_____________________") # # print("In measure "+ str(m.number) + "(" + str(m.id) + ")" +" of " + str(len(s)) ) #debug monitoring # c = m.getElementsByClass(ChordSymbol) # for x in range(len(c)): # # print(c[x].duration) # # print(c[x].beat) # # print (c[x].figure) # # print("--------------------") # TheFigure = c[x].figure # MyChord = Chord(c[x].pitches) # MySymbol = ChordSymbol() # ######## Fix XML chord symbols ############ # if (TheFigure.find(" alter b9") != -1): # MySymbol = m21utils.writeFlatNine(MyMeasure, c[x].pitches[0].name,c[x].duration,c[x].chordKind) # elif (TheFigure.find(" add b9") != -1): # MySymbol = m21utils.writeFlatNine(MyMeasure, c[x].pitches[0].name,c[x].duration,c[x].chordKind) # elif (TheFigure.find(" add #9") != -1): # MySymbol = m21utils.writeSharpNine(MyMeasure, c[x].pitches[0].name,c[x].duration,c[x].chordKind) # elif (TheFigure.find(" add #7") != -1): # MySymbol = m21utils.writeSharpSeven(MyMeasure, c[x].pitches[0].name,c[x].duration,c[x].chordKind) # elif (TheFigure.find(" add #11") != -1): # MySymbol = m21utils.writeSharpEleven(MyMeasure, c[x].pitches[0].name,c[x].duration,c[x].chordKind) # elif (TheFigure.find(" add b13") != -1): # MySymbol = m21utils.writeFlatThirteen(MyMeasure, c[x].pitches[0].name,c[x].duration,c[x].chordKind) # elif (TheFigure.find(" add b6") != -1): # MySymbol = m21utils.writeFlatSix(MyMeasure, c[x].pitches[0].name,c[x].duration,c[x].chordKind) # elif (TheFigure.find(" alter b5") != -1): # MySymbol = m21utils.writeHalfDim(MyMeasure, c[x].pitches[0].name,c[x].duration,c[x].chordKind) # elif (TheFigure.find(" alter #5") != -1): # MySymbol = m21utils.writeSharpFive(MyMeasure, c[x].pitches[0].name,c[x].duration,c[x].chordKind) # elif (TheFigure.find("pedal") != -1): # MySymbol = m21utils.writePedal(MyMeasure, c[x].pitches[0].name,c[x].duration,c[x].chordKind) # else: # if (c[x].duration.type != "zero"): # if (c[x].root().name != c[x].bass().name): # # print (c[x].root().name, c[x].bass().name) # MySymbol = ChordSymbol(root=c[x].root(), bass=c[x].bass(), kind=c[x].chordKind) # else: # MySymbol = ChordSymbol(root=c[x].root(), bass=c[x].root(), kind=c[x].chordKind) # MySymbol.duration = c[x].duration # MyMeasure.append(MySymbol) # # print("Wrote chord " + str(MySymbol.figure) + "...") # n3 = Note(MySymbol.third) # n3.duration = Duration(c[x].duration.quarterLength * 0.50) # # n3.lyric = '3rd' # n3.octave = 5 # MyMeasure.append(n3) # if (MySymbol.containsSeventh()): # n7 = m21.note.Note(MySymbol.seventh) # n7.duration = Duration(c[x].duration.quarterLength * 0.50) # # n7.lyric = '7th' # n7.octave = 5 # MyMeasure.append(n7) # else: # n5 = m21.note.Note(MySymbol.root()) # n5.duration = Duration(c[x].duration.quarterLength * 0.50) # # n5.lyric = 'R' # n5.octave = 5 # MyMeasure.append(n5) # if ((m.number)%4 == 0): # sl = m21.layout.SystemLayout(isNew=True) # MyMeasure.append(sl) # MyScore.append(MyMeasure) # Set metadata title = tune + ' - Guide Tone Study' score.metadata = m21.metadata.Metadata() score.metadata.title = title score.metadata.movementName = ' ' # For some reason this works, None and '' don't... score.metadata.composer = 'Greg Pascale' return score
def __init__(self, n, piece, movement, quadlet, couplet, lines): self.n = n self.piece = piece self.movement = movement self.quadlet = quadlet self.couplet = couplet self.lines = lines self.duration = quadlet.phrase_duration self.first = False if n == 1 and couplet.n == 1: self.first = True for line in lines: # print ('.' * int(line['rhythm'][0] * 2)) + ('-' * int(line['rhythm'][1] * 2)) + ('.' * int(line['rhythm'][2] * 2)) part = piece.parts.d[line['instrument']] measure = Measure() if self.first and quadlet.previous_phrase_duration != self.duration: ts = TimeSignature('{}/4'.format(self.duration), self.duration) # ts.beatSequence.partitionByList(subdivide(self.duration, 4)) # for i, b in enumerate(ts.beatSequence): # if b.duration.quarterLength == 4: # ts.beatSequence[i] = b.subdivide(2) # # ts.beatSequence[i][0] = b.subdivide(2) # # ts.beatSequence[i][1] = b.subdivide(2) # elif b.duration.quarterLength == 3: # ts.beatSequence[i] = b.subdivideByList([2, 1]) # # ts.beatSequence[i][0] = ts.beatSequence[i].subdivide(2) # elif b.duration.quarterLength == 2: # ts.beatSequence[i] = b.subdivide(2) measure.timeSignature = ts r1_dur, note_dur, r2_dur = line['rhythm'] line['notes'] = [] if r1_dur > 0: line['notes'].append({ 'duration': r1_dur, 'pitch': 'rest' }) line['notes'].append({ 'duration': note_dur, 'pitch': line['pitch'] }) if r2_dur > 0: line['notes'].append({ 'duration': r2_dur, 'pitch': 'rest' }) self.fix_durations(line['notes']) for note in line['notes']: if note['pitch'] == 'rest': n = Rest() else: p = Pitch(note['pitch']) # Force all flats if p.accidental.name == 'sharp': p = p.getEnharmonic() n = Note(p) # TODO add slurs # TODO add glissandos # TODO add -50 cent marks d = Duration() d.fill(note['durations']) n.duration = d measure.append(n) # if r1_dur > 0: # r1 = Rest() # r1.duration = Duration(r1_dur) # measure.append(r1) # p = Pitch(line['pitch']) # # Force all flats # if p.accidental.name == 'sharp': # p = p.getEnharmonic() # note = Note(p) # note.duration = Duration(note_dur) # measure.append(note) # if r2_dur > 0: # r2 = Rest() # r2.duration = Duration(r2_dur) # measure.append(r2) part.append(measure) # Put full measure rests in instruments that aren't playing playing = [line['instrument'] for line in lines] resting = [i for i in piece.instruments.names if i not in playing] for i in resting: # print '.' * self.duration * 2 part = piece.parts.d[i] measure = Measure() if self.first and quadlet.previous_phrase_duration != self.duration: ts = TimeSignature('{}/4'.format(self.duration), self.duration) # ts.beatSequence.subdivideNestedHierarchy(3) # ts.beatSequence.partitionByList(subdivide(self.duration, 4)) # for i, b in enumerate(ts.beatSequence): # if b.duration.quarterLength == 4: # ts.beatSequence[i] = b.subdivide(2) # # ts.beatSequence[i][0] = b.subdivide(2) # # ts.beatSequence[i][1] = b.subdivide(2) # elif b.duration.quarterLength == 3: # ts.beatSequence[i] = b.subdivideByList([2, 1]) # # ts.beatSequence[i][0] = ts.beatSequence[i].subdivide(2) # elif b.duration.quarterLength == 2: # ts.beatSequence[i] = b.subdivide(2) measure.timeSignature = ts r = Rest() r.duration = Duration(self.duration) measure.append(r) # fixed_measure = measure.sliceByBeat() # part.append(fixed_measure) part.append(measure)
def __init__(self, number, piece, movement): self.number = number self.piece = piece self.movement = movement instrument_opts = piece.instruments.names[:] self.note_opts = {} for name in instrument_opts: self.note_opts[name] = piece.i.d[name].all_notes form = self.form = song_forms.choose() self.duration = len(form) * 4 self.type = 'solo' if number % 2: self.type = 'ensemble' if self.type == 'solo': if len(movement.solo_ensemble_options) == 0: movement.solo_ensemble_options = piece.i.get_unison_ensembles(min_notes=6) print 'Hey, we ran out of unison ensembles! Cool!' solo_ensemble_hash = random.choice(movement.solo_ensemble_options.keys()) self.soloists = movement.solo_ensemble_options[solo_ensemble_hash]['instruments'] self.soloist_names = [s.nickname for s in self.soloists] self.soloists_shared_notes = movement.solo_ensemble_options[solo_ensemble_hash]['notes'] # Remove chosen ensemble from options del movement.solo_ensemble_options[solo_ensemble_hash] # remove chosen soloists from instrument options for the song for soloist in self.soloist_names: instrument_opts.remove(soloist) self.accompanist_names = instrument_opts len_accompanists = len(self.accompanist_names) if len_accompanists == 2: ensemble_size = 2 elif len_accompanists == 3: ensemble_size = random.choice([2, 3]) elif len_accompanists == 4: ensemble_size = random.choice([1, 2, 3, 4]) self.accompanist_names = random.sample(self.accompanist_names, ensemble_size) else: # who plays, who sits out? # ensemble_size = weighted_choice([3, 4, 5, 6], [1, 4, 5, 4]) # self.ensemble_names = random.sample(instrument_opts, ensemble_size) # Everyone plays self.ensemble_names = instrument_opts # make a phrase for each unique part of the form (eg, an `a` in `abacabac`) unique_phrases = [] for f in set(form): if self.type == 'solo': PhraseClass = SoloPhrase elif self.type == 'ensemble': PhraseClass = EnsemblePhrase unique_phrases.append(PhraseClass(piece, movement, self)) # Copy the phrases in the order specified by form phrases = [] for f in form: phrases.append(unique_phrases[f]) # Render phrases as music21 objects for phrase in phrases: for part in phrase.parts: measure = Measure() if movement.first_measure: ts = TimeSignature('4/4') # ts.beatSequence = ts.beatSequence.subdivide(4) ts.beamSequence = ts.beamSequence.subdivide(4) # ts.beatSequence.partitionByList(subdivide(self.duration, 4)) # for i, b in enumerate(ts.beatSequence): # if b.duration.quarterLength == 4: # ts.beatSequence[i] = b.subdivide(2) # # ts.beatSequence[i][0] = b.subdivide(2) # # ts.beatSequence[i][1] = b.subdivide(2) # elif b.duration.quarterLength == 3: # ts.beatSequence[i] = b.subdivideByList([2, 1]) # # ts.beatSequence[i][0] = ts.beatSequence[i].subdivide(2) # elif b.duration.quarterLength == 2: # ts.beatSequence[i] = b.subdivide(2) measure.timeSignature = ts # ts.getBeams() self.fix_durations(part['notes']) for note in part['notes']: if note['pitch'] == 'rest': n = Rest() else: p = Pitch(note['pitch']) # Force all flats if p.accidental.name == 'sharp': p = p.getEnharmonic() n = Note(p) # TODO add slurs # TODO add glissandos # TODO add -50 cent marks d = Duration() d.fill(note['durations']) n.duration = d measure.append(n) # if len(measure.notesAndRests) > 1: # measure.sliceByBeat(inPlace=True) # measure.makeBeams(inPlace=True) piece.parts.d[part['instrument_name']].append(measure) movement.first_measure = False
def melody_and_chords_streams(self) -> Tuple[Stream, Stream]: """ The chord stream contains realized chords and chord symbols and rests for NC :return: """ melody = Stream() chord_dict = defaultdict(list) measure_duration = None for measure_idx, measure in enumerate( self.ls.recurse().getElementsByClass(Measure)): if measure_duration is None: measure_duration = measure.duration.quarterLength else: if measure_duration != measure.duration.quarterLength: raise WrongBarDurationError() mel_measure = measure.cloneEmpty() if measure_idx == 0: anacrusis = measure.barDuration.quarterLength - measure.duration.quarterLength if anacrusis: mel_measure.append(Rest(duration=Duration(anacrusis))) for elt in measure: if elt.isClassOrSubclass((ChordSymbol, )): chord_dict[measure_idx].append(elt) else: mel_measure.append(deepcopy(elt)) melody.append(mel_measure) chords = deepcopy(melody) clef = None for _clef in chords.recurse().getElementsByClass(Clef): clef = _clef break if clef: clef.activeSite.insert(0, BassClef()) clef.activeSite.remove(clef) last_chord_symbol = None for measure_idx, measure in enumerate( chords.getElementsByClass(Measure)): original_measure_duration = measure.duration.quarterLength measure.removeByClass([Rest, Note]) if chord_dict[measure_idx]: beats = [floor(ch.beat) for ch in chord_dict[measure_idx]] \ + [1 + original_measure_duration] durations = [(beats[i + 1] - beats[i]) for i in range(len(beats) - 1)] if beats[0] > 1: if last_chord_symbol is None: measure.insert(0, Rest(duration=Duration(beats[0] - 1))) else: _cs = deepcopy(last_chord_symbol) _cs.duration = Duration(beats[0] - 1) measure.insert(0, _cs) for chord_symbol_idx, chord_symbol in enumerate( chord_dict[measure_idx]): chord_symbol.duration = Duration( durations[chord_symbol_idx]) measure.insert(beats[chord_symbol_idx] - 1, chord_symbol) last_chord_symbol = chord_symbol else: if last_chord_symbol is None: measure.insert( 0, Rest(duration=Duration(original_measure_duration))) else: _cs = deepcopy(last_chord_symbol) _cs.duration = Duration(original_measure_duration) measure.insert(0, _cs) return melody, chords
def __init__(self, ranges=False): score = self.score = Score() self.instruments = self.i = Instruments() self.parts = Parts(self.i) # Make Metadata timestamp = datetime.datetime.utcnow() metadata = Metadata() metadata.title = 'Early Montreal' metadata.composer = 'Jonathan Marmor' metadata.date = timestamp.strftime('%Y/%m/%d') score.insert(0, metadata) [score.insert(0, part) for part in self.parts.l] score.insert(0, StaffGroup(self.parts.l)) if ranges: # Don't make a piece, just show the instrument ranges for inst, part in zip(self.instruments.l, self.parts.l): measure = Measure() measure.timeSignature = TimeSignature('4/4') low = Note(inst.lowest_note) measure.append(low) high = Note(inst.highest_note) measure.append(high) part.append(measure) return # 18 to 21 minutes piece_duration_minutes = scale(random.random(), 0, 1, 18, 21) # Make the "songs" songs = [] total_minutes = 0 n = 1 while total_minutes < piece_duration_minutes: print 'Song {}'.format(n) n += 1 song = Song(self) songs.append(song) total_minutes += song.duration_minutes # Make notation previous_duration = None for song in songs: for bar in song.bars: for part in bar.parts: measure = Measure() if bar.tempo: measure.insert(0, MetronomeMark(number=bar.tempo, referent=Duration(1))) measure.leftBarline = 'double' if bar.duration != previous_duration: ts = TimeSignature('{}/4'.format(bar.duration)) measure.timeSignature = ts # Fix Durations durations = [note['duration'] for note in part['notes']] components_list = split_at_beats(durations) components_list = [join_quarters(note_components) for note_components in components_list] for note, components in zip(part['notes'], components_list): note['durations'] = components for note in part['notes']: if note['pitch'] == 'rest': n = Rest() if isinstance(note['pitch'], list): pitches = [] for pitch_number in note['pitch']: p = Pitch(pitch_number) # Force all flats if p.accidental.name == 'sharp': p = p.getEnharmonic() pitches.append(p) n = Chord(notes=pitches) # TODO add slurs # TODO add glissandos # TODO add -50 cent marks else: p = Pitch(note['pitch']) # Force all flats if p.accidental.name == 'sharp': p = p.getEnharmonic() n = Note(p) # TODO add slurs # TODO add glissandos # TODO add -50 cent marks d = Duration() if note['duration'] == 0: d.quarterLength = .5 d = d.getGraceDuration() else: d.fill(note['durations']) n.duration = d measure.append(n) self.parts.d[part['instrument_name']].append(measure) previous_duration = bar.duration
from music21.instrument import fromString as get_instrument from music21.clef import BassClef timestamp = datetime.datetime.utcnow() metadata = Metadata() metadata.title = 'The Title' metadata.composer = 'Jonathan Marmor' metadata.date = timestamp.strftime('%Y/%m/%d') score = Score() score.insert(0, metadata) part = Part() parts = [part] oboe = get_instrument('oboe') part.insert(0, oboe) score.insert(0, part) score.insert(0, StaffGroup(parts)) for dur in [[1, .5], [.25], [.25, 2]]: pitch = Pitch(60) note = Note(pitch) duration = Duration() duration.fill(dur) note.duration = duration part.append(note) score.show('musicxml', '/Applications/Sibelius 7.5.app')
def generate(tune, clef=m21.clef.TrebleClef()): score = m21utils.loadScoreForTune(tune) # print 'score', score s = score.parts[0].getElementsByClass("Measure") m21.harmony.realizeChordSymbolDurations(s) ## Needed to make this work! MyScore = m21.stream.Score() MyScore.append(s[0].keySignature) ## get key from document MyScore.append(clef) #add clef for m in s: MyMeasure = Measure() ## Make a measure and put everything inside it MyMeasure.number = m.number ## give the measure a number MyMeasure.rightBarline = m.rightBarline MyMeasure.leftBarline = m.leftBarline # print("_____________________") # print("In measure "+ str(m.number) + "(" + str(m.id) + ")" +" of " + str(len(s)) ) #debug monitoring c = m.getElementsByClass(ChordSymbol) for x in range(len(c)): # print(c[x].duration) # print(c[x].beat) # print (c[x].figure) # print("--------------------") TheFigure = c[x].figure MyChord = Chord(c[x].pitches) MySymbol = ChordSymbol() ######## Fix XML chord symbols ############ if (TheFigure.find(" alter b9") != -1): MySymbol = m21utils.writeFlatNine(MyMeasure, c[x].pitches[0].name, c[x].duration, c[x].chordKind) elif (TheFigure.find(" add b9") != -1): MySymbol = m21utils.writeFlatNine(MyMeasure, c[x].pitches[0].name, c[x].duration, c[x].chordKind) elif (TheFigure.find(" add #9") != -1): MySymbol = m21utils.writeSharpNine(MyMeasure, c[x].pitches[0].name, c[x].duration, c[x].chordKind) elif (TheFigure.find(" add #7") != -1): MySymbol = m21utils.writeSharpSeven(MyMeasure, c[x].pitches[0].name, c[x].duration, c[x].chordKind) elif (TheFigure.find(" add #11") != -1): MySymbol = m21utils.writeSharpEleven(MyMeasure, c[x].pitches[0].name, c[x].duration, c[x].chordKind) elif (TheFigure.find(" add b13") != -1): MySymbol = m21utils.writeFlatThirteen(MyMeasure, c[x].pitches[0].name, c[x].duration, c[x].chordKind) elif (TheFigure.find(" add b6") != -1): MySymbol = m21utils.writeFlatSix(MyMeasure, c[x].pitches[0].name, c[x].duration, c[x].chordKind) elif (TheFigure.find(" alter b5") != -1): MySymbol = m21utils.writeHalfDim(MyMeasure, c[x].pitches[0].name, c[x].duration, c[x].chordKind) elif (TheFigure.find(" alter #5") != -1): MySymbol = m21utils.writeSharpFive(MyMeasure, c[x].pitches[0].name, c[x].duration, c[x].chordKind) elif (TheFigure.find("pedal") != -1): MySymbol = m21utils.writePedal(MyMeasure, c[x].pitches[0].name, c[x].duration, c[x].chordKind) else: if (c[x].duration.type != "zero"): if (c[x].root().name != c[x].bass().name): # print (c[x].root().name, c[x].bass().name) MySymbol = ChordSymbol(root=c[x].root(), bass=c[x].bass(), kind=c[x].chordKind) else: MySymbol = ChordSymbol(root=c[x].root(), bass=c[x].root(), kind=c[x].chordKind) MySymbol.duration = c[x].duration MyMeasure.append(MySymbol) # print("Wrote chord " + str(MySymbol.figure) + "...") n3 = Note(MySymbol.third) n3.duration = Duration(c[x].duration.quarterLength * 0.50) # n3.lyric = '3rd' n3.octave = 5 MyMeasure.append(n3) if (MySymbol.containsSeventh()): n7 = m21.note.Note(MySymbol.seventh) n7.duration = Duration(c[x].duration.quarterLength * 0.50) # n7.lyric = '7th' n7.octave = 5 MyMeasure.append(n7) else: n5 = m21.note.Note(MySymbol.root()) n5.duration = Duration(c[x].duration.quarterLength * 0.50) # n5.lyric = 'R' n5.octave = 5 MyMeasure.append(n5) if ((m.number) % 4 == 0): sl = m21.layout.SystemLayout(isNew=True) MyMeasure.append(sl) MyScore.append(MyMeasure) # Set metadata title = tune + ' - Guide Tone Study' MyScore.metadata = m21.metadata.Metadata() MyScore.metadata.title = title MyScore.metadata.movementName = ' ' # For some reason this works, None and '' don't... MyScore.metadata.composer = 'Greg Pascale' return MyScore