Пример #1
0
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()
Пример #2
0
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()
Пример #3
0
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()
Пример #4
0
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()
Пример #5
0
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
Пример #6
0
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()
Пример #7
0
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()
Пример #8
0
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()
Пример #9
0
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
Пример #10
0
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()
Пример #11
0
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()
Пример #12
0
        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)
Пример #13
0
    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)
Пример #16
0
    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
Пример #17
0
    # 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)
Пример #18
0
    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)