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 _feedbackOnScore(self, pitches: bool = True, metre: bool = True, bass: bool = True): ''' Inserts comments on the score for moments where there is feedback available. Like printFeedback, option to use any or all of: 'pitches' for pitch HarmonicRanges; 'metre' for metrical positions; and 'bass' for bass notes / inversions. ''' totalFeedback = [] if pitches: if not self.pitchFeedback: self.comparePitches() totalFeedback += [x for x in self.pitchFeedback] if metre: if not self.metricalPositionFeedback: self.metricalPositions() totalFeedback += [x for x in self.metricalPositionFeedback] if bass: if not self.bassFeedback: self.compareBass() totalFeedback += [x for x in self.bassFeedback] te = expressions.TextExpression('***') te.placement = 'above' for x in self.totalFeedback: self.score.parts[-1].startMeasure(x.startMeasure).insert(x.offset, te)
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 testGetRepeatExpression(self): from music21 import expressions te = expressions.TextExpression('lightly') # no repeat expression is possible self.assertEqual(te.getRepeatExpression(), None) te = expressions.TextExpression('d.c.') self.assertEqual(str(te.getRepeatExpression()), '<music21.repeat.DaCapo "d.c.">') re = te.getRepeatExpression() self.assertEqual(re.getTextExpression().content, 'd.c.') te = expressions.TextExpression('DC al coda') self.assertEqual(str(te.getRepeatExpression()), '<music21.repeat.DaCapoAlCoda "DC al coda">') re = te.getRepeatExpression() self.assertEqual(re.getTextExpression().content, 'DC al coda') te = expressions.TextExpression('DC al fine') self.assertEqual(str(te.getRepeatExpression()), '<music21.repeat.DaCapoAlFine "DC al fine">') re = te.getRepeatExpression() self.assertEqual(re.getTextExpression().content, 'DC al fine') te = expressions.TextExpression('ds al coda') self.assertEqual(str(te.getRepeatExpression()), '<music21.repeat.DalSegnoAlCoda "ds al coda">') re = te.getRepeatExpression() self.assertEqual(re.getTextExpression().content, 'ds al coda') te = expressions.TextExpression('d.s. al fine') self.assertEqual(str(te.getRepeatExpression()), '<music21.repeat.DalSegnoAlFine "d.s. al fine">') re = te.getRepeatExpression() self.assertEqual(re.getTextExpression().content, 'd.s. al fine')
def getTextExpression(self, prefix='', postfix='x'): ''' Return a configured :class:`~music21.expressions.TextExpressions` object describing the repeat times. Append this to the stream for annotation of repeat times. >>> rb = bar.Repeat(direction='end') >>> rb.times = 3 >>> rb.getTextExpression() <music21.expressions.TextExpression "3x"> >>> rb.getTextExpression(prefix='repeat ', postfix=' times') <music21.expressions.TextExpression "repeat 3 t..."> ''' value = '%s%s%s' % (prefix, self._times, postfix) return expressions.TextExpression(value)
def testTextExpressionsB(self): from music21 import expressions textSrc = ['loud', 'soft', 'with\nspirit', 'with\nless\nintensity'] sizeSrc = [8, 10, 12, 18, 24] positionVerticalSrc = [20, -80, 20] enclosureSrc = [None, None, None, 'rectangle', 'oval'] styleSrc = ['italic', 'bold', None, 'bolditalic'] p = stream.Part() for i in range(20): te = expressions.TextExpression(textSrc[i % len(textSrc)]) te.size = sizeSrc[i % len(sizeSrc)] te.justify = 'left' te.positionVertical = positionVerticalSrc[i % len(positionVerticalSrc)] te.enclosure = enclosureSrc[i % len(enclosureSrc)] te.style = styleSrc[i % len(styleSrc)] p.append(te) p.append(note.Note(type='quarter')) for i in range(4): p.append(note.Rest(type='16th')) s = stream.Score() s.insert(0, p) #s.show() musicxml = fromMusic21Object(s) #print musicxml match = """<direction> <direction-type> <words default-y="20.0" enclosure="rectangle" font-size="18.0" justify="left">with spirit</words> </direction-type> <offset>0</offset> </direction>""" self.assertEqual(match in musicxml, True)
def getTextExpression(self, prefix='', postfix='x'): '''Return a configured :class:`~music21.expressions.TextExpressions` object describing the repeat times. Append this to the stream for annotation of repeat times. ''' value = '%s%s%s' % (prefix, self._times, postfix) return expressions.TextExpression(value)
def asScore(self): ''' returns all snippets as a score chunk >>> deduto = trecento.cadencebook.BallataSheet().workByTitle('deduto') >>> deduto.title u'Deduto sey a quel' >>> dedutoScore = deduto.asScore() >>> dedutoScore <music21.stream.Score ...> >>> #_DOCS_HIDE dedutoScore.show() Changes made to a snippet are reflected in the asScore() score object: >>> deduto.snippets[0].parts[0].flat.notes[0].name = "C###" >>> deduto.asScore().parts[0].flat.notes[0].name 'C###' ''' s = stream.Score() md = metadata.Metadata() s.insert(0, md) s.metadata.composer = self.composer s.metadata.title = self.title for dummy in range(self.totalVoices): s.insert(0, stream.Part()) 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 for partNumber, snippetPart in enumerate(thisSnippet.getElementsByClass('TrecentoCadenceStream')): if thisSnippet.snippetName != "" and partNumber == self.totalVoices - 1: textEx = expressions.TextExpression(thisSnippet.snippetName) textEx.positionVertical = '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) return s
def testNoteheadSmorgasbord(self): # tests the of many different types of noteheads from music21 import expressions n = note.Note('c3') n.notehead = 'diamond' p = stream.Part() tn = expressions.TextExpression('diamond') m = note.Note('c3') m.notehead = 'cross' tm = expressions.TextExpression('cross') l = note.Note('c3') l.notehead = 'triangle' tl = expressions.TextExpression('triangle') k = note.Note('c3') k.notehead = 'circle-x' tk = expressions.TextExpression('circle-x') j = note.Note('c3') j.notehead = 'x' tj = expressions.TextExpression('x') i = note.Note('c3') i.notehead = 'slash' ti = expressions.TextExpression('slash') h = note.Note('c3') h.notehead = 'square' th = expressions.TextExpression('square') g = note.Note('c3') g.notehead = 'arrow down' tg = expressions.TextExpression('arrow down') f = note.Note('c3') f.notehead = 'inverted triangle' tf = expressions.TextExpression('inverted triangle') f.addLyric('inverted triangle') e = note.Note('c3') e.notehead = 'back slashed' te = expressions.TextExpression('back slashed') d = note.Note('c3') d.notehead = 'fa' td = expressions.TextExpression('fa') c = note.Note('c3') c.notehead = 'normal' tc = expressions.TextExpression('normal') noteList = [ tc, c, tn, n, th, h, tl, l, tf, f, tg, g, te, e, ti, i, tj, j, tm, m, tk, k, td, d ] for thisNote in noteList: p.append(thisNote) #p.show() raw = fromMusic21Object(p) self.assertEqual(raw.find('<notehead>diamond</notehead>') > 0, True) self.assertEqual(raw.find('<notehead>square</notehead>') > 0, True) self.assertEqual(raw.find('<notehead>triangle</notehead>') > 0, True) self.assertEqual( raw.find('<notehead>inverted triangle</notehead>') > 0, True) self.assertEqual(raw.find('<notehead>arrow down</notehead>') > 0, True) self.assertEqual( raw.find('<notehead>back slashed</notehead>') > 0, True) self.assertEqual(raw.find('<notehead>slash</notehead>') > 0, True) self.assertEqual(raw.find('<notehead>x</notehead>') > 0, True) self.assertEqual(raw.find('<notehead>cross</notehead>') > 0, True) self.assertEqual(raw.find('<notehead>circle-x</notehead>') > 0, True) self.assertEqual(raw.find('<notehead>fa</notehead>') > 0, True)