def ch1_basic_II_A_2(show=True, *arguments, **keywords): ''' p3. Write letter names and octave designations for the pitches written in the treble and bass clefs below. ''' humdata = ''' **kern 1BBD 1C## 1B 1DD- 1f# 1FF 1D- 1d 1CC# 1AA- 1c 1F *- ''' exercise = converter.parseData(humdata) for n in exercise.flat.notes: # have to use flat here n.lyric = n.nameWithOctave exercise.insert(0, clef.BassClef()) exercise = exercise.sorted # need sorted to get clef if show: exercise.show()
def ch1_basic_II_A_1(show=True, *arguments, **keywords): ''' p3. Write letter names and octave designations for the pitches written in the treble and bass clefs below. (Data in Finale/musicxml format) ''' humdata = ''' **kern 1gg# 1B 1a## 1ddd- 1c# 1dd 1G 1b- 1ccc 1f- 1aa- 1e-- *- ''' exercise = converter.parseData(humdata) #exercise = music21.parseData("ch1_basic_II_A_1.xml") for n in exercise.flat.notes: # have to use flat here n.lyric = n.nameWithOctave if show: exercise.show()
def ch1_writing_I_A_1(show=True, *arguments, **keywords): ''' p. 5 Rewrite these melodies from music literature, placing the pitches one octave higher or lower as specified, by using ledger lines. Do not change to a new clef. Rewrite one active higher ''' from music21 import converter, clef # Purcell, "Music for a While" humdata = ''' **kern 8C 8D 8E 8EE 8AA 8E 8F 8AA 8BB 8F# 8G 8BB 8C 8G# 8A 8C# *- ''' ex = converter.parseData(humdata) ex = ex.transpose('p8') ex.insert(0, clef.BassClef()) # maintain clef if show: ex.show()
def ch1_basic_II_B_2(show=True, *arguments, **keywords): ''' p4. For each of the five bass clef pitches on the left, write the tenor-clef equivalent on the right. Then label each pitch with the correct name and octave designation. ''' humdata = '**kern\n1F#1e-\n1B\n1D-\n1c\n*-' exercise = converter.parseData(humdata) for n in exercise.flat.notes: # have to use flat here n.lyric = n.nameWithOctave exercise.insert(0, clef.TenorClef()) if show: exercise.show()
def ch1_writing_I_B_3(show=True, *arguments, **keywords): ''' p. 7. Transcribe Purcell, "Music for a While" for bassoon in tenor clef >>> a = True ''' from music21 import converter, clef, parse # Purcell, "Music for a While" humdata = ''' **kern *clefF4 8C 8D 8E 8EE 8AA 8E 8F 8AA 8BB 8F# 8G 8BB 8C 8G# 8A 8C# *- ''' ex = converter.parseData(humdata) clefOld = ex.flat.getElementsByClass(clef.Clef)[0] # replace the old clef ex.flat.replace(clefOld, clef.TenorClef()) ex.insert(0, instrument.Bassoon()) if show: ex.show() else: post = ex.musicxml
def ch1_basic_II_B_1(show=True, *arguments, **keywords): ''' p4. For each of the five trebleclef pitches on the left, write the alto-clef equivalent on the right. Then label each pitch with the correct name and octave designation. ''' humdata = ''' **kern 1B- 1f# 1a- 1c 1G# *- ''' exercise = converter.parseData(humdata) for n in exercise.flat.notes: # have to use flat here n.lyric = n.nameWithOctave exercise.insert(0, clef.AltoClef()) if show: exercise.show()
def ch1_writing_I_B_2(show=True, *arguments, **keywords): ''' Transcribe the melody into treble clef ''' # Mozart no. 41, 4th movement humdata = ''' **kern *clefC3 4g 4g 4G 4G *- ''' # this notation excerpt is incomplete ex = converter.parseData(humdata) clefOld = ex.flat.getElementsByClass(clef.Clef)[0] ex.flat.replace(clefOld, clef.TrebleClef()) if show: ex.show()
def ch1_writing_I_A_2(show=True, *arguments, **keywords): ''' p. 5 Rewrite one octave higher ''' humdata = ''' **kern 6e 6e 6e 6e 6f 6g *- ''' # this notation excerpt is incomplete ex = converter.parseData(humdata) ex = ex.transpose('p8') ex.insert(0, clef.TrebleClef()) # maintain clef if show: ex.show()
def harmonizations( inputFile, closePosition=False, tonic=None, firstVoicing=None, lastVoicing=None, allowedUnisons=0, ): """Yields harmonizations for a RomanText input.""" if tonic: transposedRntxt = transposeRomanText(inputFile, tonic) romantext = parseData(transposedRntxt, format="rntext") else: romantext = parse(inputFile, format="rntext") romanNumerals = normalizeRomanNumerals(romantext) costTable = solveProgression(romanNumerals, closePosition, firstVoicing, lastVoicing, allowedUnisons) for progression, cost in generateHarmonization(costTable): romantextcopy = copy.deepcopy(romantext) score = decorateScore(romantextcopy, progression) yield score return
def ch1_writing_I_B_3(show=True, *arguments, **keywords): ''' p. 7. Transcribe Purcell, "Music for a While" for bassoon in tenor clef >>> a = True ''' # Purcell, "Music for a While" humdata = ''' **kern *clefF4 8C 8D 8E 8EE 8AA 8E 8F 8AA 8BB 8F# 8G 8BB 8C 8G# 8A 8C# *- ''' ex = converter.parseData(humdata) clefOld = ex.flat.getElementsByClass(clef.Clef)[0] # replace the old clef ex.flat.replace(clefOld, clef.TenorClef()) ex.insert(0, instrument.Bassoon()) if show: ex.show()
def ch1_writing_I_A_1(show=True, *arguments, **keywords): ''' p. 5 Rewrite these melodies from music literature, placing the pitches one octave higher or lower as specified, by using ledger lines. Do not change to a new clef. Rewrite one active higher ''' # Purcell, "Music for a While" humdata = ''' **kern 8C 8D 8E 8EE 8AA 8E 8F 8AA 8BB 8F# 8G 8BB 8C 8G# 8A 8C# *- ''' ex = converter.parseData(humdata) ex = ex.transpose('p8') ex.insert(0, clef.BassClef()) # maintain clef if show: ex.show()
chain(*[feature().getAttributeLabels() for feature in feature_list])) writer = csv.DictWriter(open(args.output, 'wb'), fieldnames=fieldnames) # A little progress checking progressbar = ProgressBar(tune_count * len(feature_list)) # Store a count by feature name of all the errors, so that if one feature is particularly # troublesome, we can skip it when computing the singular value decomposition errors = 0 print('Extracting {} features from {} tunes'.format( len(feature_list), tunes.count())) for i, tune in enumerate(tunes.values('id', 'title', 'raw_abc')): try: score = converter.parseData(tune['raw_abc'], format='abc') row = {'id': tune['id']} for j, feature in enumerate(feature_list): try: fe = feature(score) f = fe.extract() row.update(izip(fe.getAttributeLabels(), f.vector)) except: errors += 1 row = None break progressbar.update_time((i * feature_count) + j + 1)
def _parseData(self): ''' Parses data specified as strings in self.dataDict into objects in self.parsedDataDict ''' for (name, dataDictElement) in self.dataDict.iteritems(): if 'data' not in dataDictElement: self.addError("no data specified for data element " + unicode(dataDictElement)) continue dataStr = dataDictElement['data'] if 'fmt' in dataDictElement: fmt = dataDictElement['fmt'] if name in self.parsedDataDict: self.addError("duplicate definition for data named " + str(name) + " " + str(dataDictElement)) continue if fmt not in availableDataFormats: self.addError("invalid data format for data element " + str(dataDictElement)) continue if fmt == 'string' or fmt == 'str': if dataStr.count("'") == 2: # Single Quoted String data = dataStr.replace("'", "") # remove excess quotes elif dataStr.count("\"") == 2: # Double Quoted String data = dataStr.replace("\"", "") # remove excess quotes else: self.addError( "invalid string (not in quotes...) for data element " + str(dataDictElement)) continue elif fmt == 'int': try: data = int(dataStr) except: self.addError("invalid integer for data element " + str(dataDictElement)) continue elif fmt in ['bool', 'boolean']: if dataStr in ['true', 'True']: data = True elif dataStr in ['false', 'False']: data = False else: self.addError("invalid boolean for data element " + str(dataDictElement)) continue elif fmt == 'list': # in this case dataStr should actually be an list object. if not common.isListLike(dataStr): self.addError( "list format must actually be a list structure " + str(dataDictElement)) continue data = [] for elementStr in dataStr: if common.isStr(elementStr): (matchFound, dataElement ) = self.parseStringToPrimitive(elementStr) if not matchFound: self.addError( "format could not be detected for data element " + str(elementStr)) continue else: dataElement = elementStr data.append(dataElement) else: if fmt in ['xml', 'musicxml']: if dataStr.find("<!DOCTYPE") == -1: dataStr = """<!DOCTYPE score-partwise PUBLIC "-//Recordare//DTD MusicXML 1.1 Partwise//EN" "http://www.musicxml.org/dtds/partwise.dtd">""" + dataStr if dataStr.find("<?xml") == -1: dataStr = """<?xml version="1.0" encoding="UTF-8"?>""" + dataStr try: data = converter.parseData(dataStr) except converter.ConverterException as e: #self.addError("Error parsing data variable "+name+": "+str(e)+"\n\n"+dataStr) self.addError( "Error parsing data variable " + name + ": " + unicode(e) + "\n\n" + dataStr, e) continue else: # No format specified (matchFound, data) = self.parseStringToPrimitive(dataStr) if not matchFound: self.addError( "format could not be detected for data element " + str(dataDictElement)) continue self.parsedDataDict[name] = data
tune_count = tunes.count() progress = ProgressBar(tune_count) progress.width = 60 errors = 0 print progress, "{: >5,d} / {: <5,d}".format(0, tune_count), chr(27) + "[A" byOffset = {} byBeat = {} for i, tune in enumerate(tunes.values_list("raw_abc", flat=True)): progress.update_time(i) print progress, "{: >5,d} / {: <5,d}".format(i, tune_count), "Errors: {}".format(errors), chr(27) + "[A" try: score = parseData(tune, format="abc") key = score.analyze("key") for note in score.flat.notesAndRests: degree = -1 if note.isNote: degree = key.getScaleDegreeFromPitch(note.pitch.name) byOffset.setdefault(note.offset, []).append(degree) byBeat.setdefault(note.beat, []).append(degree) except: errors += 1 print progress, "{: >5,d} / {: <5,d}".format(i, tune_count), "Errors: {}".format(errors)
c.execute(TUNE_COUNT_SQL) tune_count = c.fetchone()[0] progress = ProgressBar(tune_count) progress.width = 80 with file(args.output, 'wb') as output: writer = csv.writer(output) for i, (tuneId, abc) in enumerate(c.execute(TUNE_SQL)): progress.update_time(i) print progress, chr(27) + '[A' try: score = converter.parseData(abc, format='abc') row = [tuneId] for note in score.flat.notesAndRests: duration = note.quarterLength ps = -1 if note.isNote: ps = note.ps row.append('|'.join(map(str, (duration, ps)))) except: pass finally: writer.writerow(row)
def handle_item(self, item, *args, **options): data = {} output_dir = options['output_dir'] if options['corpus'] == 'Essen Folksong Collection': humdrum = HumdrumFile.objects.get(corpus_item=item) data['path'] = humdrum.path data['properties'] = dict([(p.type.name, p.value) for p in item.properties.all()]) if output_dir is not None: os.system('cp %s %s.krn' % (humdrum.path, os.path.join(output_dir, str(humdrum.id)))) humdrum_file = open(humdrum.path) try: score = converter.parse(humdrum.path) except UnicodeDecodeError: humdrum_bin = open(humdrum.path, 'rb') encoding_info = chardet.detect(humdrum_bin.read()) if encoding_info['encoding'] != 'windows-1252' or encoding_info['confidence'] < 0.6: print(encoding_info) humdrum_file = open(humdrum.path, encoding=encoding_info['encoding']) score = converter.parseData(humdrum_file.read(), format='humdrum') if options['fixed_meter']: meter = Meter(2, 2, 2, 2) units = 1/16.0 data['lhl_grid'] = Grid.from_m21_score(score, units=units, meter=meter) else: try: data['lhl_grid'] = Grid.from_m21_score(score) except Exception as e: if data['properties']['AMT'] == 'irregular': print('Skipping irregular meter') else: print('FIXME: %s' % e) elif options['corpus'] == 'JazzR': ... elif options['corpus'] == 'Witek et al. 2014': onsets = JSONAnnotation.objects.get(corpus_item=item) pleasure = NumericAnnotation.objects.get(corpus_item=item, type__name='Average rating of pleasure') move = NumericAnnotation.objects.get(corpus_item=item, type__name='Average rating of wanting to move') syncopation = NumericAnnotation.objects.get(corpus_item=item, type__name='Degree of syncopation') meter = TimeSignature(4, 4) meter.divisions = (2, 2, 2, 2) # The annotation contains onsets measured in quarternotes # For the metrical grid to work we need to convert it # to whole notes bass_and_snare_onsets = [onset * (meter.grid_length / 4.0) for onset in onsets.json['bassdrum'] + onsets.json['snaredrum']] bass_and_snare = Grid(bass_and_snare_onsets, meter) hi_hat = Grid([onset * (meter.grid_length / 4.0) for onset in onsets.json['hihat']], meter) bass_drum = Grid([onset * (meter.grid_length / 4.0) for onset in onsets.json['bassdrum']], meter) snare_drum = Grid([onset * (meter.grid_length / 4.0) for onset in onsets.json['snaredrum']], meter) data['lhl_grid'] = bass_and_snare data['bass_drum'] = bass_drum data['snare_drum'] = snare_drum data['hi_hat'] = hi_hat data['move'] = move.value data['pleasure'] = pleasure.value data['syncopation'] = syncopation.value return data
# Set up a CSV writer fieldnames = ['id'] + list(chain(*[feature().getAttributeLabels() for feature in feature_list])) writer = csv.DictWriter(open(args.output, 'wb'), fieldnames=fieldnames) # A little progress checking progressbar = ProgressBar(tune_count * len(feature_list)) # Store a count by feature name of all the errors, so that if one feature is particularly # troublesome, we can skip it when computing the singular value decomposition errors = 0 print('Extracting {} features from {} tunes'.format(len(feature_list), tunes.count())) for i, tune in enumerate(tunes.values('id', 'title', 'raw_abc')): try: score = converter.parseData(tune['raw_abc'], format='abc') row = {'id': tune['id']} for j, feature in enumerate(feature_list): try: fe = feature(score) f = fe.extract() row.update(izip(fe.getAttributeLabels(), f.vector)) except: errors += 1 row = None break progressbar.update_time((i * feature_count) + j + 1)
def _parseData(self): """ Parses data specified as strings in self.dataDict into objects in self.parsedDataDict """ for (name, dataDictElement) in self.rawDataDict.iteritems(): if "data" not in dataDictElement: self.recordError("no data specified for data element " + unicode(dataDictElement)) continue dataStr = dataDictElement["data"] if "fmt" in dataDictElement: fmt = dataDictElement["fmt"] if name in self.parsedDataDict: self.recordError("duplicate definition for data named " + str(name) + " " + str(dataDictElement)) continue if fmt not in availableDataFormats: self.recordError("invalid data format for data element " + str(dataDictElement)) continue if fmt == "string" or fmt == "str": if dataStr.count("'") == 2: # Single Quoted String data = dataStr.replace("'", "") # remove excess quotes elif dataStr.count('"') == 2: # Double Quoted String data = dataStr.replace('"', "") # remove excess quotes else: self.recordError("invalid string (not in quotes...) for data element " + str(dataDictElement)) continue elif fmt == "int": try: data = int(dataStr) except: self.recordError("invalid integer for data element " + str(dataDictElement)) continue elif fmt in ["bool", "boolean"]: if dataStr in ["true", "True"]: data = True elif dataStr in ["false", "False"]: data = False else: self.recordError("invalid boolean for data element " + str(dataDictElement)) continue elif fmt == "list": # in this case dataStr should actually be an list object. if not common.isListLike(dataStr): self.recordError("list format must actually be a list structure " + str(dataDictElement)) continue data = [] for elementStr in dataStr: if common.isStr(elementStr): dataElement = self.parseInputToPrimitive(elementStr) else: dataElement = elementStr data.append(dataElement) elif fmt == "file": data = dataStr else: if fmt in ["xml", "musicxml"]: if dataStr.find("<!DOCTYPE") == -1: dataStr = ( """<!DOCTYPE score-partwise PUBLIC "-//Recordare//DTD MusicXML 1.1 Partwise//EN" "http://www.musicxml.org/dtds/partwise.dtd">""" + dataStr ) if dataStr.find("<?xml") == -1: dataStr = """<?xml version="1.0" encoding="UTF-8"?>""" + dataStr try: data = converter.parseData(dataStr) except converter.ConverterException as e: # self.recordError("Error parsing data variable "+name+": "+str(e)+"\n\n"+dataStr) self.recordError( "Error parsing data variable " + name + ": " + unicode(e) + "\n\n" + dataStr, e ) continue else: # No format specified dataStr = str(dataStr) data = self.parseInputToPrimitive(dataStr) self.parsedDataDict[name] = data
progress = ProgressBar(tune_count) progress.width = 60 errors = 0 print progress, '{: >5,d} / {: <5,d}'.format(0, tune_count), chr(27) + '[A' byOffset = {} byBeat = {} for i, tune in enumerate(tunes.values_list('raw_abc', flat=True)): progress.update_time(i) print progress, '{: >5,d} / {: <5,d}'.format( i, tune_count), 'Errors: {}'.format(errors), chr(27) + '[A' try: score = parseData(tune, format='abc') key = score.analyze('key') for note in score.flat.notesAndRests: degree = -1 if note.isNote: degree = key.getScaleDegreeFromPitch(note.pitch.name) byOffset.setdefault(note.offset, []).append(degree) byBeat.setdefault(note.beat, []).append(degree) except: errors += 1 print progress, '{: >5,d} / {: <5,d}'.format( i, tune_count), 'Errors: {}'.format(errors)