def showChanges(self, show=False): ''' Visual and debugging feature to display which notes are changed. Will open in musescore, unless show is set to False ''' for (idx, (midiNoteRef, omrNoteRef, change)) in enumerate(self.changes): if change == ChangeOps.NoChange: pass else: # change is Insertion, Deletion, Substitution midiNoteRef.color = change.color midiNoteRef.addLyric(idx) omrNoteRef.color = change.color omrNoteRef.addLyric(idx) self.targetStream.metadata = metadata.Metadata() self.sourceStream.metadata = metadata.Metadata() self.targetStream.metadata.title = 'Target ' + str( self.targetStream.id) self.sourceStream.metadata.title = 'Source ' + str( self.targetStream.id) self.targetStream.metadata.movementName = self.targetStream.metadata.title self.sourceStream.metadata.movementName = self.sourceStream.metadata.title if show: self.targetStream.show() self.sourceStream.show()
def testJSONSerializationMetadata(self): from music21.musicxml import xmlHandler from music21.musicxml import fromMxObjects from music21.musicxml import testFiles from music21 import metadata md = metadata.Metadata( title='Concerto in F', date='2010', composer='Frank', ) #environLocal.printDebug([str(md.json)]) self.assertEqual(md.composer, 'Frank') #md.jsonPrint() mdNew = metadata.Metadata() jsonString = freezeThaw.JSONFreezer(md).json freezeThaw.JSONThawer(mdNew).json = jsonString self.assertEqual(mdNew.date, '2010/--/--') self.assertEqual(mdNew.composer, 'Frank') self.assertEqual(mdNew.title, 'Concerto in F') # test getting meta data from an imported source d = xmlHandler.Document() d.read(testFiles.mozartTrioK581Excerpt) # @UndefinedVariable mxScore = d.score # get the mx score directly md = fromMxObjects.mxScoreToMetadata(mxScore) self.assertEqual(md.movementNumber, '3') self.assertEqual(md.movementName, 'Menuetto (Excerpt from Second Trio)') self.assertEqual(md.title, 'Quintet for Clarinet and Strings') self.assertEqual(md.number, 'K. 581') self.assertEqual(md.composer, 'Wolfgang Amadeus Mozart') # convert to json and see if data is still there #md.jsonPrint() mdNew = metadata.Metadata() jsonString = freezeThaw.JSONFreezer(md).json freezeThaw.JSONThawer(mdNew).json = jsonString self.assertEqual(mdNew.movementNumber, '3') self.assertEqual(mdNew.movementName, 'Menuetto (Excerpt from Second Trio)') self.assertEqual(mdNew.title, 'Quintet for Clarinet and Strings') self.assertEqual(mdNew.number, 'K. 581') self.assertEqual(mdNew.composer, 'Wolfgang Amadeus Mozart')
def asOpus(self): ''' returns all snippets as a :class:`~music21.stream.Opus` object >>> deduto = alpha.trecento.cadencebook.BallataSheet().workByTitle('deduto') >>> deduto.title 'Deduto sey a quel' >>> dedutoScore = deduto.asOpus() >>> dedutoScore <music21.stream.Opus ...> >>> #_DOCS_SHOW dedutoScore.show('lily.png') ''' o = stream.Opus() md = metadata.Metadata() o.insert(0, md) o.metadata.composer = self.composer o.metadata.title = self.title bs = self.snippets for thisSnippet in bs: if thisSnippet is None: continue if (thisSnippet.tenor is None and thisSnippet.cantus is None and thisSnippet.contratenor is None): continue s = stream.Score() for dummy in range(self.totalVoices): s.insert(0, stream.Part()) for partNumber, snippetPart in enumerate( thisSnippet.getElementsByClass('TrecentoCadenceStream')): if thisSnippet.snippetName != "" and partNumber == self.totalVoices - 1: textEx = expressions.TextExpression( thisSnippet.snippetName) textEx.style.absoluteY = 'below' if 'FrontPaddedSnippet' in thisSnippet.classes: if snippetPart.hasMeasures(): snippetPart.getElementsByClass( 'Measure')[-1].insert(0, textEx) else: snippetPart.append(textEx) else: if snippetPart.hasMeasures(): snippetPart.getElementsByClass( 'Measure')[0].insert(0, textEx) else: snippetPart.insert(0, textEx) # if currentTs is None or timeSig != currentTs: # s.append(timeSig) # currentTs = timeSig try: currentScorePart = s.parts[partNumber] except IndexError: continue # error in coding for thisElement in snippetPart: if 'TimeSignature' in thisElement.classes: continue currentScorePart.append(thisElement) o.insert(0, s) return o
def print_music(converted_output): thisstream = stream.Stream() thisstream.timeSignature = meter.TimeSignature('4/4') thisstream.insert( 0, metadata.Metadata(title='vanilla ai', composer='sent from my ai')) for timestep in converted_output: t1, t2, t3, t4 = timestep # hm_elements = len(t1) # todo: also handle rests, as well as optimize for single notes thischord = chord.Chord() for tt1, tt2, tt3, tt4 in zip(t1, t2, t3, t4): tt1.replace('#', '+') # tt1 = 'R' thisnote = note.Note(tt1 + str(tt2 + 2)) thisnote.duration.quarterLength = tt3 thisnote.volume.velocity = tt4 thischord.add(thisnote) thisstream.append(thischord) thisstream.show() thisstream.plot(title='my musiplot')
def insert_musicxml_metadata(sheet: music21.stream.Stream): """ Insert various metadata into the provided XML document The timesignature in particular is required for proper MIDI conversion """ global timesignature from music21.clef import TrebleClef, BassClef, Treble8vbClef for part, name, clef in zip( sheet.parts, ['soprano', 'alto', 'tenor', 'bass'], [TrebleClef(), TrebleClef(), Treble8vbClef(), BassClef()]): # empty_part = part.template() part.insert(0, timesignature) part.insert(0, clef) part.id = name part.partName = name md = metadata.Metadata() sheet.insert(0, md) # required for proper musicXML formatting sheet.metadata.title = 'DeepBach' sheet.metadata.composer = 'DeepBach'
def audioVirelaiSearch(): #from music21 import audioSearch from music21.audioSearch import transcriber from music21 import search virelaisSheet = cadencebook.TrecentoSheet(sheetname='virelais') virelaiCantuses = [] for i in range(2, 54): thisVirelai = virelaisSheet.makeWork(i) if thisVirelai.title != "": try: vc = thisVirelai.incipit.getElementsByClass('Part')[0] vc.insert(0, metadata.Metadata(title=thisVirelai.title)) virelaiCantuses.append(vc) except IndexError: pass searchScore = transcriber.runTranscribe(show=False, plot=False, seconds=10.0, saveFile=False) #from music21 import converter #searchScore = converter.parse("c'4 a8 a4 g8 b4. d'4. c8 b a g f4", '6/8') #searchScore.show() l = search.approximateNoteSearch(searchScore, virelaiCantuses) for i in l: print(i.metadata.title, i.matchProbability) l[0].show()
def testJSONSerializationMetadata(self): from music21 import converter from music21.musicxml import testFiles as mTF from music21 import metadata md = metadata.Metadata( title='Concerto in F', date='2010', composer='Frank', ) # environLocal.printDebug([str(md.json)]) self.assertEqual(md.composer, 'Frank') self.assertEqual(md.date, '2010/--/--') self.assertEqual(md.composer, 'Frank') self.assertEqual(md.title, 'Concerto in F') # test getting meta data from an imported source c = converter.parse(mTF.mozartTrioK581Excerpt) # @UndefinedVariable md = c.metadata self.assertEqual(md.movementNumber, '3') self.assertEqual( md.movementName, 'Menuetto (Excerpt from Second Trio)') self.assertEqual(md.title, 'Quintet for Clarinet and Strings') self.assertEqual(md.number, 'K. 581') self.assertEqual(md.composer, 'Wolfgang Amadeus Mozart')
def toScore(self, labelRomanNumerals=True, labelSubsectionsOnScore=True): ''' creates Score object out of a from CTSong...also creates CTRule objects in the process, filling their .streamFromCTSong attribute with the corresponding smaller inner stream. Individual attributes of a rule are defined by the entire CTSong, such as meter and time signature, so creation of CTRule objects typically occurs only from this method and directly from the clercqTemperly text. >>> s = romanText.clercqTemperley.CTSong(romanText.clercqTemperley.BlitzkriegBopCT) >>> scoreObj = s.toScore() >>> scoreObj.highestOffset 380.0 ''' self.labelRomanNumerals = labelRomanNumerals self.labelSubsectionsOnScore = labelSubsectionsOnScore if self._scoreObj is not None: return self._scoreObj scoreObj = stream.Part() measures = self.rules['S'].expand() scoreObj.append(measures) scoreObj.insert(0, metadata.Metadata()) scoreObj.metadata.title = self.title self._scoreObj = scoreObj return scoreObj
def museDataWorkToStreamScore(museDataWork, inputM21=None): '''Given an museDataWork object, build into a multi-part :class:`~music21.stream.Score` with metadata. This assumes that this MuseDataHandler defines a single work (with 1 or fewer reference numbers). if the optional parameter inputM21 is given a music21 Stream subclass, it will use that object as the outermost object. However, inner parts will always be made :class:`~music21.stream.Part` objects. ''' from music21 import stream from music21 import metadata if inputM21 == None: s = stream.Score() else: s = inputM21 # each musedata part has complete metadata, so must get first mdpObjs = museDataWork.getParts() md = metadata.Metadata() s.insert(0, md) md.title = mdpObjs[0].getWorkTitle() md.movementNumber = mdpObjs[0].getMovementNumber() md.movementName = mdpObjs[0].getMovementTitle() # not obvious where composer is stored #md.composer = mdpObjs[0].getWorkNumber() #md.localeOfComposition = mdpObjs[0].getWorkNumber() md.number = mdpObjs[0].getWorkNumber() for mdPart in mdpObjs: musedataPartToStreamPart(mdPart, s) return s
def generate_examples(): output_dir = ".\\Examples\\" # Example 1 - cycle 2/7 for C major sc = scale.MajorScale('C') tonic_triad = chord.Chord(sc.pitchesFromScaleDegrees([1, 3, 5], 'C5', 'B5')) cycle = generate_cycle_pair(sc, tonic_triad, "2/7") cycle.insert(0, key.KeySignature(0)) cycle.metadata = metadata.Metadata() cycle.metadata.title = "Example 1 - Cycle 2/7 in C Major" cycle.write("MusicXML", output_dir + "Example 1") # Example 2 - cycle 4/5 for D major sc = scale.MajorScale('D') tonic_triad = chord.Chord(sc.pitchesFromScaleDegrees([1, 3, 5], 'D4', 'C5')) cycle = generate_cycle_pair(sc, tonic_triad, "4/5") cycle.insert(0, key.KeySignature(2)) cycle.metadata = metadata.Metadata() cycle.metadata.title = "Example 2 - Cycle 4/5 in D Major" cycle.write("MusicXML", output_dir + "Example 2") # Example 3 - cycle 3/6 for A harmonic minor sc = scale.HarmonicMinorScale('A') tonic_triad = chord.Chord(sc.pitchesFromScaleDegrees([1, 3, 5], 'A4', 'G5')) cycle = generate_cycle_pair(sc, tonic_triad, "3/6") cycle.insert(0, key.KeySignature(0)) cycle.metadata = metadata.Metadata() cycle.metadata.title = "Example 3 - Cycle 3/6 in A Harmonic Minor" cycle.write("MusicXML", output_dir + "Example 3") # Example 4 - cycle 3/6 for C major but with drop 2 chords tonic = 'C' sc = scale.MajorScale(tonic) root = sc.pitchFromDegree(1) tonic_triad = chord.Chord([root, root.transpose(7), root.transpose(16)]) cycle = generate_cycle_pair(sc, tonic_triad, "3/6", voicing_type=Voicing.Drop2_A_form) cycle.insert(0, key.KeySignature(0)) cycle.metadata = metadata.Metadata() cycle.metadata.title = "Example 4 - Cycle 3/6 in C Major\nDrop 2 voicings" cycle.write("MusicXML", output_dir + "Example 4")
def insert_metadata(output_chorale): for part, name in zip(output_chorale.parts, ['soprano']): part.id = name part.partName = name md = metadata.Metadata() output_chorale.insert(0, md) output_chorale.metadata.title = 'Anticipation-RNN' output_chorale.metadata.composer = 'GH'
def notesAndDurationsToStream(notesList, durationList, scNotes=None, removeRestsAtBeginning=True, qle=None): ''' take a list of :class:`~music21.note.Note` objects or rests and an equally long list of how long each ones lasts in terms of samples and returns a Stream using the information from quarterLengthEstimation and quantizeDurations. returns a :class:`~music21.stream.Score` object, containing a metadata object and a single :class:`~music21.stream.Part` object, which in turn contains the notes, etc. Does not run :meth:`~music21.stream.Stream.makeNotation` on the Score. >>> durationList = [20, 19, 10, 30, 6, 21] >>> n = note.Note >>> noteList = [n('C#4'), n('D5'), n('B4'), n('F#5'), n('C5'), note.Rest()] >>> s,lengthPart = audioSearch.notesAndDurationsToStream(noteList, durationList) >>> s.show('text') {0.0} <music21.metadata.Metadata object at ...> {0.0} <music21.stream.Part ...> {0.0} <music21.note.Note C#> {1.0} <music21.note.Note D> {2.0} <music21.note.Note B> {2.5} <music21.note.Note F#> {4.0} <music21.note.Note C> {4.25} <music21.note.Rest rest> ''' # rounding lengths p2 = stream.Part() # If the score is available, the quarter estimation is better: # It could take into account the changes of tempo during the song, but it # would take more processing time if scNotes != None: fe = features.native.MostCommonNoteQuarterLength(scNotes) mostCommon = fe.extract().vector[0] qle = quarterLengthEstimation(durationList, mostCommon) elif scNotes is None: # this is for the transcriber qle = quarterLengthEstimation(durationList) for i in range(len(durationList)): actualDuration = quantizeDuration(durationList[i] / qle) notesList[i].quarterLength = actualDuration if not (removeRestsAtBeginning and (notesList[i].name == "rest")): p2.append(notesList[i]) removeRestsAtBeginning = False sc = stream.Score() sc.metadata = metadata.Metadata() sc.metadata.title = 'Automatic Music21 Transcription' sc.insert(0, p2) if scNotes is None: # Case transcriber return sc, len(p2) else: #case follower return sc,qle
def cycle36_write_file_test(): tonic = 'C' sc = scale.MajorScale(tonic) tonic_triad = chord.Chord(sc.pitchesFromScaleDegrees([1, 3, 5], 'C5', 'B5')) cycle = generate_cycle_pair(sc, tonic_triad, "3/6") cycle.metadata = metadata.Metadata() cycle.metadata.title = "Cycle 3/6 progression in C Major" cycle.metadata.composer = "Chord Cycle Generation Software" cycle.write("MusicXML", "C:\\Temp\\Cycle36_progression")
def makeRowScore(data: Optional = None, write: bool = False, title: Optional[str] = 'Rows_in_the_Repertoire'): """ Makes a score setting out any number of rows in musical notation, annotated with labelled pitch classes and work metadata (title, composer etc). Note: unlike the rest of this repository, this requires an external music21: library """ from music21 import bar, expressions, layout, metadata, meter, serial, stream score = stream.Score() part = stream.Part() part.insert(0, meter.TimeSignature('12/4')) # Not essential count = 1 if not data: jsonPath = os.path.join('.', 'Repertoire_Anthology', 'rows_in_the_repertoire.json') with open(jsonPath) as jsonFile: data = json.load(jsonFile) for d in data: # dict entry = data[d] m = stream.Measure(number=count) count += 1 row = serial.pcToToneRow(entry['P0']) for x in row.notes: x.stemDirection = 'none' x.lyric = x.pitch.pitchClass m.insert(x.offset, x) text = f"{entry['Composer']}: {entry['Work']}, {entry['Year']}" # ", {entry['P0']}" m.insert(0, expressions.TextExpression(text)) part.append(m) score.append(part) # Layout for thisMeasure in score.parts[0].getElementsByClass('Measure'): thisMeasure.insert(bar.Barline(type='final', location='right')) thisMeasure.insert(layout.SystemLayout(isNew=True)) # Metadata score.insert(0, metadata.Metadata()) score.metadata.composer = 'Various composers and analysts, compiled by Mark Gotham' score.metadata.title = title if write: w = os.path.join('.', 'Repertoire_Anthology', title + '.mxl') score.write(fmt='mxl', fp=w) else: return score
def makeMetadata(self): self.insert(0, metadata.Metadata()) if self.hasEditorialInformation and 'metadata' in self.editorial: meta = self.editorial.metadata if 'title' in meta: self.metadata.title = meta.get('title') elif 'name' in meta: self.metadata.title = meta.get('name') if 'transcriber' in meta: c = metadata.Contributor() c.name = meta['transcriber'] c.role = 'transcriber' self.metadata.addContributor(c)
def leadsheetEx1(self): ''' Example realization of a lead sheet, "Jeanie With The Light Brown Hair" from music21 corpus ''' testFile1 = corpus.parse('leadSheet/fosterBrownHair.xml') testFile1.insert(metadata.Metadata()) testFile1.metadata.title = 'Jeanie With The Light Brown Hair' testFile = harmony.realizeChordSymbolDurations(testFile1) smoothBassCS = generateSmoothBassLine(testFile.flat.getElementsByClass(harmony.ChordSymbol)) output = generateContrapuntalBassLine(smoothBassCS, generatePopSongRules()) mergeLeadSheetAndBassLine(testFile1, output).show()
def transcript(self): self.stream.append(self.mm) electric_guitar = instrument.fromString('grand piano') electric_guitar.midiChannel = 0 electric_guitar.midiProgram = 1 self.stream.append(electric_guitar) self.stream.insert(0, metadata.Metadata()) self.stream.metadata.title = self.path.split('/')[-1] for note in self.note_info: self.stream.append(note) key = self.stream.analyze('key') print(key.name) # Insert Key to Stream self.stream.insert(0, key)
def realizeclercqTemperleyEx(self, testfile): ''' Example realization (using fbRealizer - romanNumerals flavor) of any clercqTemperley file. testfile must conform to the requirements of a class clercgTemperley file (must be a string) ''' s = clercqTemperley.CTSong(testfile) testFile1 = s.toScore() testFile = harmony.realizeChordSymbolDurations(testFile1) smoothBassRN = generateSmoothBassLine(testFile.flat.getElementsByClass(roman.RomanNumeral)) output = generateContrapuntalBassLine(smoothBassRN, generateBaroqueRules()) output.insert(metadata.Metadata()) output.metadata.title = s.title output.show()
def generate_cycle_pairs_for_all_string_sets(root_scale, tonic, pair_type, voicing=Voicing.Closed): cycle_pairs = [] for strings in iteration_function(voicing): string_set = (GuitarRange.get_string(strings[0]), GuitarRange.get_string(strings[1]), GuitarRange.get_string(strings[2])) tonic_triad = generate_tonic_triad(root_scale, tonic, string_set, voicing) cycle_pair = generate_cycle_pair(root_scale, tonic_triad, pair_type, string_set, voicing) # populate all the metadata to make the titling and everything automatic cycle_pair.metadata = metadata.Metadata() cycle_pair.metadata.title = "Cycle " + pair_type + " Progression in " + root_scale.name + "\nString Set: " + \ str(string_set[0].number.value) + "-" + str(string_set[1].number.value) + "-" + \ str(string_set[2].number.value) + "; " + Voicing.to_string(voicing) + " Triads" cycle_pair.metadata.composer = "Graham Smith" cycle_pair.metadata.date = "2020" # add system breaks at the end each measure to make it one measure per line cycle_pair.definesExplicitSystemBreaks = True for s in cycle_pair.getElementsByClass(stream.Stream): measures = s.getElementsByClass(stream.Measure) for m in measures: m.append(layout.SystemLayout(isNew=True)) cycle_pair.definesExplicitSystemBreaks = True # add notation to make the score easier to read cycle_pair[1][0][1].lyric = "First cycle starts" cycle_pair[2][0][0].lyric = "Second cycle starts" # add an ending measure to make the line breaks and formatting a bit cleaner/more consistent m = stream.Measure() last_chord_as_list = list(tonic_triad.pitches) check_note_ranges_and_transpose(last_chord_as_list, string_set) last_chord = chord.Chord(last_chord_as_list) last_chord.duration = duration.Duration(4.0) m.append(last_chord) r = note.Rest() r.duration = duration.Duration(2.0) m.append(r) cycle_pair[2].append(m) ensure_unique_chords(cycle_pair) # cycle_pair.show() cycle_pairs.append(cycle_pair) return cycle_pairs
def __init__(self, fiveExcelCells=None, parentPiece=None): stream.Score.__init__(self) if fiveExcelCells == None: fiveExcelCells = [] if fiveExcelCells != []: if len(fiveExcelCells) != 5: raise Exception( "Need five Excel Cells to make a PolyphonicSnippet object") for part in fiveExcelCells[0:3]: if part is not None and hasattr( part, 'isStream') and part.isStream == True: part.__class__ = stream.Part part.classes.insert(0, 'Part') self.cadenceType = fiveExcelCells[3] self.timeSig = meter.TimeSignature(fiveExcelCells[4]) self.parentPiece = parentPiece self.cantus = fiveExcelCells[0] self.tenor = fiveExcelCells[1] self.contratenor = fiveExcelCells[2] if self.contratenor == "" or self.contratenor is None: self.contratenor = None else: self.contratenor.id = 'Ct' if self.tenor == "" or self.tenor is None: self.tenor = None else: self.tenor.id = 'T' if self.cantus == "" or self.cantus is None: self.cantus = None else: self.cantus.id = 'C' md = metadata.Metadata() md.title = self.header() self.insert(0, md) self._appendParts() self._padParts()
def get(): piece = stream.Score() p1 = stream.Part() p1.id = 'part1' notes = [ note.Note('C4', type='quarter'), note.Note('D4', type='quarter'), note.Note('E4', type='quarter'), note.Note('F4', type='quarter'), note.Note('G4', type='half'), note.Note('G4', type='half'), note.Note('A4', type='quarter'), note.Note('A4', type='quarter'), note.Note('A4', type='quarter'), note.Note('A4', type='quarter'), note.Note('G4', type='half'), note.Note('A4', type='quarter'), note.Note('A4', type='quarter'), note.Note('A4', type='quarter'), note.Note('A4', type='quarter'), note.Note('G4', type='half'), note.Note('F4', type='quarter'), note.Note('F4', type='quarter'), note.Note('F4', type='quarter'), note.Note('F4', type='quarter'), note.Note('E4', type='half'), note.Note('E4', type='half'), note.Note('D4', type='quarter'), note.Note('D4', type='quarter'), note.Note('D4', type='quarter'), note.Note('D4', type='quarter'), note.Note('C4', type='half'), ] p1.append(notes) piece.insert(0, metadata.Metadata()) piece.metadata.title = 'Alle meine Entchen' piece.insert(0, p1) return piece, notes
def create_score_from_parts(self, parts=2, score_title="Piano concerto", composer="Anonymous COMP5030 student"): """ given list of stream.Parts return a stream.Score w/ each Part stacked together """ # create a score container s = stream.Score() # insert stacked parts for i in range(1, parts + 1): p = self.create_part_from_measures() p.id = f"Part{i}" s.insert(0, p) # set metadata s.insert(0, metadata.Metadata()) s.metadata.title = f"{score_title} in {str(self.key)}" s.metadata.composer = composer return s
def testSortorder(self): from music21 import stream, bar, clef, note, metadata m = stream.Measure() b = bar.Repeat() m.leftBarline = b c = clef.BassClef() m.append(c) n = note.Note() m.append(n) # check sort order self.assertEqual(m[0], b) self.assertEqual(m[1], c) self.assertEqual(m[2], n) # if we add metadata, it sorts ahead of bar md = metadata.Metadata() m.insert(0, md) self.assertEqual(m[0], md) self.assertEqual(m[1], b)
def mergeLeadSheetAndBassLine(leadsheet, bassLine): ''' method to combine the lead sheet (i.e. from the ex-wikifonia) with just the melody line and chord symbols with the newly realized bassLine (i.e. from fbRealizer) which consists of two parts, the treble line and bass line. ''' s = stream.Score() s.insert(metadata.Metadata()) s.metadata.title = leadsheet.metadata.title cs = leadsheet.flat.getElementsByClass(harmony.ChordSymbol) if cs[0].offset > 0: bassLine.parts[0].insertAndShift(0, note.Rest(quarterLength=cs[0].offset)) bassLine.parts[1].insertAndShift(0, note.Rest(quarterLength=cs[0].offset)) voicePart = leadsheet.parts[0] pianoTreble = bassLine.parts[0] pianoBass = bassLine.parts[1] s.insert(0, voicePart) s.insert(0, pianoTreble) s.insert(0, pianoBass) return s
def __init__(self, fiveExcelCells=None, parentPiece=None): super().__init__() if fiveExcelCells is None: fiveExcelCells = [] if fiveExcelCells != []: if len(fiveExcelCells) != 5: raise Exception( "Need five Excel Cells to make a PolyphonicSnippet object") self.cadenceType = fiveExcelCells[3] self.timeSig = meter.TimeSignature(fiveExcelCells[4]) self.parentPiece = parentPiece self.cantus = fiveExcelCells[0] self.tenor = fiveExcelCells[1] self.contratenor = fiveExcelCells[2] self.longestLineLength = 0 if self.contratenor == "" or self.contratenor is None: self.contratenor = None else: self.contratenor.id = 'Ct' if self.tenor == "" or self.tenor is None: self.tenor = None else: self.tenor.id = 'T' if self.cantus == "" or self.cantus is None: self.cantus = None else: self.cantus.id = 'C' md = metadata.Metadata() md.title = self.header() self.insert(0, md) self._appendParts() self._padParts()
def main(phrases=2): cMajScale = SourceSet(tonic='c', pitches=['c3', 'd3', 'e3', 'f3', 'g3', 'a3', 'b3', 'c4', \ 'd4', 'e4', 'f4', 'g4', 'a4', 'b4', 'c5', 'd5', 'e5', 'f5', 'g5']) composition = ComputerComposition(cMajScale) composition.tonic_chord_maj() composition.predominant_function_chord() composition.predominant_function_chord() composition.dominant_function_chord() composition.tonic_chord_maj() # for _i in range(phrases - 1): # TODO Eventually generate middle material # composition.predominant_function_chord() # composition.dominant_function_chord() # composition.tonic_chord_maj() # composition.predominant_function_chord() # composition.dominant_function_chord() # composition.dominant_function_chord() # composition.tonic_chord_maj() # composition.predominant_function_chord() composition.PACadence() # End on a perfect authentic cadence composition.realize() # Add metadata composition.insert(0, metadata.Metadata()) # Showy title composition.metadata.title = "Music Fragment " + b64encode( str(time()).encode("ascii")).decode("ascii") composition.metadata.composer = "Composed by Computer" composition.write("musicxml", "Composition.xml") print("done")
cello.remove(n) cello.makeMeasures(inPlace=True) # -------------------------------------------------------------------------------------------------- # Build final score # -------------------------------------------------------------------------------------------------- piano_right_hand = tools.convert_stream(piano_right_hand, stream.Part) piano_left_hand = tools.convert_stream(piano_left_hand, stream.Part) cello = tools.convert_stream(cello, stream.Part) cello.partName = "Vc." score = tools.merge_streams( cello, piano_right_hand, piano_left_hand, stream_class=stream.Score ) piano_staff_group = layout.StaffGroup( [piano_right_hand, piano_left_hand], name="Piano", abbreviation="Pno.", symbol="brace", ) score.insert(0, piano_staff_group) score.metadata = metadata.Metadata() score.metadata.title = "Liturgie de Cristal" score.metadata.composer = "Olivier Messiaen" # -------------------------------------------------------------------------------------------------- # Output xml file and show score in MuseScore # -------------------------------------------------------------------------------------------------- score.write(fp="olivier_messiaen_quatuor.xml") score.show()
# write to wav file file = wave.open("output/" + filename + "_sine.wav", "wb") file.setnchannels(1) file.setsampwidth(2) # 2 bytes = 16 bit file.setframerate(fs) file.writeframes(synth_audio_converted) file.close() # Get music21 notes note_info = list(music_info[:, 1]) # Create music21 stream s = Stream() s.append(mm) electricguitar = instrument.fromString('electric guitar') electricguitar.midiChannel = 0 electricguitar.midiProgram = 30 #Set program to Overdriven Guitar s.append(electricguitar) s.insert(0, metadata.Metadata()) for note in note_info: s.append(note) # Analyse music21 stream to get song Key key = s.analyze('key') print("Key: " + key.name) # Insert Key to Stream s.insert(0, key) # Save MIDI to file s.write('midi', "output/" + filename + "_music21.mid")
def testStreams01(self): ''' Basic stream issues ''' #from music21 import note, stream, clef, metadata, spanner #==== "fig-df02" # Storing, Ordering, and Timing Elements n1 = note.Note('g3', type='half') n2 = note.Note('d4', type='half') cf1 = clef.AltoClef() m1 = stream.Measure(number=1) m1.append([n1, n2]) m1.insert(0, cf1) # the measure has three elements assert len(m1) == 3 # the offset returned is the most-recently set assert n2.offset == 2.0 # automatic sorting positions Clef first assert m1[0] == cf1 # list-like indices follow sort order assert m1.index(n2) == 2 # can find an element based on a given offset assert m1.getElementAtOrBefore(3) == n2 n3 = note.Note('g#3', quarterLength=0.5) n4 = note.Note('d-4', quarterLength=3.5) m2 = stream.Measure(number=2) m2.append([n3, n4]) # appended position is after n3 assert n4.offset == .5 assert m2.highestOffset == .5 # can access objects on elements assert m2[1].duration.quarterLength == 3.5 # the Stream duration is the highest offset + duration assert m2.duration.quarterLength == 4 p1 = stream.Part() p1.append([m1, m2]) # the part has 2 components assert len(p1) == 2 # the Stream duration is the highest offset + durations assert p1.duration.quarterLength == 8 # can access Notes from Part using multiple indices assert p1[1][0].pitch.nameWithOctave == 'G#3' s1 = stream.Score() s1.append(p1) md1 = metadata.Metadata(title='The music21 Stream') s1.insert(0, md1) # calling show by default renders musicxml output #s1.show() #==== "fig-df02" end #==== "fig-df03" # Positioning the Same Element in Multiple Containers # show positioning the same element in multiple containers # do not yet use a flat representation s2 = stream.Stream() s3 = stream.Stream() s2.insert(10, n2) s3.insert(40, n2) # the offset attribute returns the last assigned assert n2.offset == 40 # we can provide a site to finde a location-specific offset assert n2.getOffsetBySite(m1) == 2.0 assert n2.getOffsetBySite(s2) == 10 # the None site provides a default offset assert set(n2.sites.get()) == set([None, m1, s2, s3]) # the same instance is found in all Streams assert m1.hasElement(n2) == True assert s2.hasElement(n2) == True assert s3.hasElement(n2) == True # only offset is independent to each location n2.pitch.transpose('-M2', inPlace=True) assert s2[s2.index(n2)].nameWithOctave == 'C4' assert s3[s3.index(n2)].nameWithOctave == 'C4' assert m1[m1.index(n2)].nameWithOctave == 'C4' # the transposition is maintained in the original context #s1.show() #==== "fig-df03" end #==== "fig-df04" # Simultaneous Access to Hierarchical and Flat Representations #s1.flat.show('t') # lengths show the number of elements; indices are sequential s1Flat = s1.flat assert len(s1) == 2 assert len(s1Flat) == 6 assert s1Flat[4] == n3 assert s1Flat[5] == n4 # adding another Part to the Score results in a different flat representation n5 = note.Note('a#1', quarterLength=2.5) n6 = note.Note('b2', quarterLength=1.5) m4 = stream.Measure(number=2) m4.append([n5, n6]) r1 = note.Rest(type='whole') cf2 = clef.bestClef(m4) # = BassClef m3 = stream.Measure(number=1) m3.append([cf2, r1]) p2 = stream.Part() p2.append([m3, m4]) s1.insert(0, p2) assert 'BassClef' in cf2.classes # objects are sorted by offset s1Flat = s1.flat assert len(s1) == 3 assert len(s1.flat) == 10 assert s1Flat[6] == n3 assert s1Flat[7] == n5 assert s1Flat[8] == n4 assert s1Flat[9] == n6 # the F-sharp in m. 2 now as offsets for both flat non-flat sites assert n3.getOffsetBySite(m2) == 0 assert n3.getOffsetBySite(s1Flat) == 4 # the B in m. 2 now as offsets for both flat non-flat sites assert n6.getOffsetBySite(m4) == 2.5 assert n6.getOffsetBySite(s1Flat) == 6.5 #s1.show() #==== "fig-df04" end #==== "fig-df05" # Iterating and Filtering Elements by Class # get the Clef object, and report its sign, from Measure 1 assert m1.getElementsByClass('Clef').stream()[0].sign == 'C' # collect into a list the sign of all clefs in the flat Score assert [cf.sign for cf in s1.flat.getElementsByClass('Clef')] == ['C', 'F'] # collect the offsets Measures in the first part assert [e.offset for e in p1.elements] == [0.0, 4.0] # collect the offsets of Note in the first part flattened assert [e.offset for e in p1.flat.notesAndRests] == [0.0, 2.0, 4.0, 4.5] # collect the offsets of Notes in all parts flattened assert [e.offset for e in s1.flat.notesAndRests ] == [0.0, 0.0, 2.0, 4.0, 4.0, 4.5, 6.5] # get all pitch names match = [] for e in s1.flat.getElementsByClass('Note').stream(): match.append(e.pitch.nameWithOctave) assert match == ['G3', 'C4', 'G#3', 'A#1', 'D-4', 'B2'] # collect all Notes and transpose up a perfect fifth for n in s1.flat.getElementsByClass('Note').stream(): n.transpose('P5', inPlace=True) # check that all pitches are correctly transposed match = [] for e in s1.flat.getElementsByClass('Note').stream(): match.append(e.pitch.nameWithOctave) assert match == ['D4', 'G4', 'D#4', 'E#2', 'A-4', 'F#3'] #s1.show() #==== "fig-df05" end #==== "fig-df06" # Searching by Locations and Contexts # a Note can always find a Clef self.assertIs(n4.getContextByClass('Clef'), cf1) # must search oldest sites first assert n6.getContextByClass('Clef', sortByCreationTime='reverse') == cf2 # # a Note can find their Measure number from a flat Part # match = [] # for e in p1.flat.getElementsByClass('Note'): # match.append(e.getContextByClass('Measure').number) # assert match == [1, 1, 2, 2] # all Notes can find their Measure number from a flat Score match = [] for e in s1.flat.notesAndRests: match.append([e.name, e.getContextByClass('Measure').number]) assert match == [['D', 1], ['rest', 1], ['G', 1], ['D#', 2], ['E#', 2], ['A-', 2], ['F#', 2]] #==== "fig-df06" end #==== "fig-df06" # Non-Hierarchical Object Associations #oldIds = [] #for idKey in n1.sites.siteDict: # print (idKey, n1.sites.siteDict[idKey].isDead) # oldIds.append(idKey) #print("-------") # Spanners can be positioned in Parts or Measures sp1 = spanner.Slur([n1, n4]) p1.append(sp1) sp2 = spanner.Slur([n5, n6]) m4.insert(0, sp2) #print(id(sp1), id(sp1.spannerStorage), n1.sites.siteDict[id(sp1.spannerStorage)].isDead) #if id(sp1.spannerStorage) in oldIds: # print ("******!!!!!!!!!*******") # Elements can report on what Spanner they belong to ss1 = n1.getSpannerSites() self.assertTrue(sp1 in ss1, (ss1, sp1)) ss6 = n6.getSpannerSites() assert sp2 in ss6 # p1Flat = p1.flat # assert sp1.getDurationSpanBySite(p1Flat) == [0.0, 8.0] # # p2Flat = p2.flat # assert sp2.getDurationSpanBySite(p2Flat) == [4.0, 8.0] #s1.show() #==== "fig-df06" end # additional tests self.assertEqual(m1.clef, cf1)
def abcToStreamScore(abcHandler, inputM21=None): '''Given an abcHandler object, build into a multi-part :class:`~music21.stream.Score` with metadata. This assumes that this ABCHandler defines a single work (with 1 or fewer reference numbers). if the optional parameter inputM21 is given a music21 Stream subclass, it will use that object as the outermost object. However, inner parts will always be made :class:`~music21.stream.Part` objects. ''' from music21 import abcFormat from music21 import metadata if inputM21 == None: s = stream.Score() else: s = inputM21 # meta data can be first md = metadata.Metadata() s.insert(0, md) # get title from large-scale metadata titleCount = 0 for t in abcHandler.tokens: if isinstance(t, abcFormat.ABCMetadata): if t.isTitle(): if titleCount == 0: # first md.title = t.data #environLocal.printDebug(['got metadata title', md.title]) titleCount += 1 # all other titles go in alternative field else: md.alternativeTitle = t.data #environLocal.printDebug(['got alternative title', md.alternativeTitle]) titleCount += 1 elif t.isComposer(): md.composer = t.data elif t.isOrigin(): md.localeOfComposition = t.data #environLocal.printDebug(['got local of composition', md.localOfComposition]) elif t.isReferenceNumber(): md.number = int(t.data) # convert to int? #environLocal.printDebug(['got work number', md.number]) partHandlers = [] tokenCollections = abcHandler.splitByVoice() if len(tokenCollections) == 1: partHandlers.append(tokenCollections[0]) else: # add metadata -- stored in tokenCollections[0] -- to each Part (stored in tokenCollections[i]) for i in range(1, len(tokenCollections)): # concatenate abc handler instances newABCHandler = tokenCollections[0] + tokenCollections[i] #dummy = [t.src for t in newABCHandler.tokens] #print dummy partHandlers.append(newABCHandler) # find if this token list defines measures # this should probably operate at the level of tunes, not the entire # token list partList = [] for partHandler in partHandlers: p = abcToStreamPart(partHandler) partList.append(p) for p in partList: s._insertCore(0, p) s.elementsChanged() return s