Esempio n. 1
0
    def parseData(self, dataString, number=None):
        '''Create HumdrumFile object from a string, and create a music21 Stream from it.

        >>> humData = ('**kern\\n*M2/4\\n=1\\n24r\\n24g#\\n24f#\\n24e\\n24c#\\n' +
        ...     '24f\\n24r\\n24dn\\n24e-\\n24gn\\n24e-\\n24dn\\n*-')
        >>> c = converter.subConverters.HumdrumConverter()
        >>> s = c.parseData(humData)
        >>> c.stream.show('text')
        {0.0} <music21.metadata.Metadata object at 0x7f33545027b8>
        {0.0} <music21.stream.Part spine_0>
            {0.0} <music21.stream.Measure 1 offset=0.0>
                {0.0} <music21.meter.TimeSignature 2/4>
                {0.0} <music21.note.Rest rest>
                {0.1667} <music21.note.Note G#>
                {0.3333} <music21.note.Note F#>
                {0.5} <music21.note.Note E>
                {0.6667} <music21.note.Note C#>
                {0.8333} <music21.note.Note F>
                {1.0} <music21.note.Rest rest>
                {1.1667} <music21.note.Note D>
                {1.3333} <music21.note.Note E->
                {1.5} <music21.note.Note G>
                {1.6667} <music21.note.Note E->
                {1.8333} <music21.note.Note D>
        '''
        print("parsing krn string", file=sys.stderr)
        hf = HumdrumFile()
        hf.readString(dataString)
        self.stream = hf.createMusic21Stream()
        self.humdrumFile = hf
        return self.stream
Esempio n. 2
0
 def parseFile(self, filePath, number=None):
     '''
     Create HumdrumFile object from a file path, and create a music21 Stream from it.
     Note that normally, implementing parseData is sufficient, but Humdrum files
     may be utf-8 or latin-1, so we need to handle various text encodings ourselves.
     '''
     print("parsing krn file", file=sys.stderr)
     hf = HumdrumFile(filePath)
     self.stream = hf.createMusic21Stream()
     self.humdrumFile = hf
     return self.stream
Esempio n. 3
0
def runTheFullTest(krnPath: Path):
    print(f'krn file: {krnPath}')

    # resultsFileName = krnPath.stem + '.json'
    # resultsPath = krnPath.parent / resultsFileName

    # import into HumdrumFile
    hfb = HumdrumFile(str(krnPath))
    assert hfb.isValid

    # test against known good results
    # results = HumdrumFileTestResults.fromFiles(str(krnPath), str(resultsPath))
    # CheckHumdrumFile(hfb, results)

    # import HumdrumFile into music21 stream
    score1 = hfb.createMusic21Stream()
    assert score1 is not None
    assert score1.isWellFormedNotation() or not score1.elements

    # now import via music21's Humdrum parser

    score2 = m21.converter.parse(krnPath, format='humdrum', forceSource=True)
    #     if score2 is None or not score2.isWellFormedNotation():
    #         score1.show('musicxml.pdf')
    assert score2 is not None
    assert score2.isWellFormedNotation()

    #     score2.show('musicxml.pdf')

    # compare the two music21 scores with musicdiff
    print('comparing the two m21 scores')
    score_lin1 = AnnScore(score1)
    print('loaded first score')
    score_lin2 = AnnScore(score2)
    print('loaded second score')
    diffList, _cost = Comparison.annotated_scores_diff(score_lin1, score_lin2)
    print('diffed the two scores:')
    numDiffs = len(diffList)
    print(f'\tnumber of differences = {numDiffs}')
    if numDiffs > 0:
        print('now we will mark and display the two scores')
        Visualization.mark_diffs(score1, score2, diffList)
        print('marked the scores to show differences')
        Visualization.show_diffs(score1, score2)
        print('displayed both annotated scores')
def ReadAllTestFilesInFolder(folder: str):
    krnPaths: [Path] = sorted(list(Path(folder).glob('**/*.krn')), key=str)
    print('numTestFiles in', folder, ' =', len(krnPaths))
    assert len(krnPaths) > 0

    numCrashes = 0
    crashIdxes = []
    for i, krnPath in enumerate(krnPaths):
        print('krn file {}: {}'.format(i, krnPath))

        # use this to skip files in folder (i.e. start with n, which is 0-based)
        # n = 78
        # if i < n:
        #     print(f'\tskipping any files before {n}th file in folder')
        #     continue
#
#         if krnPath.name == 'sonata07-1.krn':
#             print('hi')

        resultsFileName = krnPath.stem + '.json'
        resultsPath = krnPath.parent / resultsFileName
#         try:

        if 'tasso-scores' in str(krnPath) and krnPath.name in (
                'Tam2031034a-Vorro_veder_cio_che_Tirsi_avra_fatto--Balsamino_1594.krn',
                                                            ):
            print('skipping test because krnFile contains more than one score (not yet supported)')
            continue

        hfb = HumdrumFile(str(krnPath))
        assert(hfb.isValid)

        results = HumdrumFileTestResults.fromFiles(str(krnPath), str(resultsPath))
        CheckHumdrumFile(hfb, results)

        # import humdrum into music21 stream

        score = hfb.createMusic21Stream()
        assert(score is not None)
        assert(score.isWellFormedNotation() or not score.elements)

        # export score back to humdrum (without any makeNotation fixups)

        # if the score is empty, exporting from it will not produce anything interesting
        if not score.elements:
            print('\tskipping export of empty score')
            continue

        # The following are worth working on, but I am skipping for now so I can run
        # all the tests to see where we are.

        # these are cases that cause extendTokenDuration to fail because it ran out
        # of room before the next note (music21 has overlapping notes, most likely)
        if krnPath.name in (
                'test-manipulators.krn',
                            ):
            print('\tskipping export due to overlapping note durations (caused perhaps by *+)')
            continue

        hdw: HumdrumWriter = HumdrumWriter(score)
        hdw.makeNotation = False
        hdw.addRecipSpine = krnPath.name == 'test-rhythms.krn'

        success: bool = True
        fp = Path(tempfile.gettempdir()) / krnPath.name
        with open(fp, 'w') as f:
            success = hdw.write(f)

        assert(success)

        # and then try to parse the exported humdrum file

        # These are cases where export produced an unparseable humdrum file.
        # The exported test-spine-float.krn is unparseable because it has duration differences
        # between spines (it gets really confused either during export or maybe during original
        # import)

        if krnPath.name in (
                'test-spine-float.krn',
                            ):
            print('\tskipping parse of export due to *+ issues')
            continue

        # this is a weird one...
        if 'rds-scores' in str(krnPath) and krnPath.name in (
                'R262x_Ive-w33b4p26.krn',
                'R443_Ber-w10p321m593-595.krn',
                ): # rds-scores
            print('\tskipping parse of export due to missing fields')
            continue

        if 'rds-scores' in str(krnPath) and krnPath.name in (
                'R258_Ive-w30p9m55-57.krn',
                                                            ):
            print('\tskipping parse of export due to unparseable manipulators (original is even weirder, but parseable)')
            continue

        hfb = HumdrumFile(str(fp))
        assert(hfb.isValid)

        score2 = hfb.createMusic21Stream()
        assert(score2 is not None)
        assert(score2.isWellFormedNotation())
def runTheDiff(krnPath: Path, results) -> bool:
    print(f'{krnPath}: ', end='')
    print(f'{krnPath}: ', end='', file=results)
    results.flush()

    # import into HumdrumFile
    hfb = HumdrumFile(str(krnPath))
    if not hfb.isValid:
        print('HumdrumFile1 parse failure')
        print('HumdrumFile1 parse failure', file=results)
        results.flush()
        return False

    # import HumdrumFile into music21 stream
    score1 = hfb.createMusic21Stream()
    if score1 is None:
        print('score1 creation failure')
        print('score1 creation failure', file=results)
        results.flush()
        return False

    if not score1.elements:
        # empty score is valid result, but assume diff will be exact
        # (export of empty score fails miserably)
        print('numDiffs = 0 (empty score1)')
        print('numDiffs = 0 (empty score1)', file=results)
        results.flush()
        return True

    if not score1.isWellFormedNotation():
        print('score1 not well formed')
        print('score1 not well formed', file=results)
        results.flush()
        return False

    # export score back to humdrum (without any makeNotation fixups)

    hdw: HumdrumWriter = HumdrumWriter(score1)
    hdw.makeNotation = False
    hdw.addRecipSpine = krnPath.name == 'test-rhythms.krn'
    # hdw.expandTremolos = False

    success: bool = True
    fp = Path(tempfile.gettempdir()) / krnPath.name
    with open(fp, 'w', encoding='utf-8') as f:
        success = hdw.write(f)
    if not success:
        print('export failed')
        print('export failed', file=results)
        results.flush()
        return False

    # and then try to parse the exported humdrum file
    hfb2 = HumdrumFile(str(fp))
    if not hfb2.isValid:
        print('HumdrumFile2 parse failure')
        print('HumdrumFile2 parse failure', file=results)
        results.flush()
        return False

    score2 = hfb2.createMusic21Stream()
    if score2 is None:
        print('score2 creation failure')
        print('score2 creation failure', file=results)
        results.flush()
        return False

    if not score2.elements:
        print('score2 was empty')
        print('score2 was empty', file=results)
        results.flush()
        return False  # empty score2 is bad, because score1 was not empty

    if not score2.isWellFormedNotation():
        print('score2 not well formed')
        print('score2 not well formed', file=results)
        results.flush()
        return False

    # use music-score-diff to compare the two music21 scores,
    # and return whether or not they were identical
    annotatedScore1 = AnnScore(score1, DetailLevel.AllObjectsWithStyle)
    annotatedScore2 = AnnScore(score2, DetailLevel.AllObjectsWithStyle)
    op_list, _cost = Comparison.annotated_scores_diff(annotatedScore1,
                                                      annotatedScore2)
    numDiffs = len(op_list)
    print(f'numDiffs = {numDiffs}')
    print(f'numDiffs = {numDiffs}', file=results)
    results.flush()
    if numDiffs > 0:
        summ: str = '\t' + oplistSummary(op_list, score1, score2)
        print(summ)
        print(summ, file=results)
        results.flush()
        return False
    return True
Esempio n. 6
0
def runTheDiff(krnPath: Path, results) -> bool:
    print(f'{krnPath}: ', end='')
    print(f'{krnPath}: ', end='', file=results)
    results.flush()

    # import into HumdrumFile
    try:
        hfb = HumdrumFile(str(krnPath))
        if not hfb.isValid:
            print('HumdrumFile1 parse failure')
            print('HumdrumFile1 parse failure', file=results)
            results.flush()
            return False
    except KeyboardInterrupt:
        sys.exit(0)
    except:
        print('HumdrumFile1 parse crash')
        print('HumdrumFile1 parse crash', file=results)
        results.flush()
        return False

    # import HumdrumFile into music21 stream
    try:
        score1 = hfb.createMusic21Stream()
        if score1 is None:
            print('score1 creation failure')
            print('score1 creation failure', file=results)
            results.flush()
            return False
    except KeyboardInterrupt:
        sys.exit(0)
    except:
        print('score1 creation crash')
        print('score1 creation crash', file=results)
        results.flush()
        return False

    if not score1.elements:
        # empty score is valid result, but assume diff will be exact
        # (export of empty score fails miserably)
        print('numDiffs = 0 (empty score1)')
        print('numDiffs = 0 (empty score1)', file=results)
        results.flush()
        return True

    if not score1.isWellFormedNotation():
        print('score1 not well formed')
        print('score1 not well formed', file=results)
        results.flush()
        return False

    # now import via music21's Humdrum parser
    try:
        score2 = m21.converter.parse(krnPath,
                                     format='humdrum',
                                     forceSource=True)
        if score2 is None:
            print('score2 creation failure')
            print('score2 creation failure', file=results)
            results.flush()
            return False
    except KeyboardInterrupt:
        sys.exit(0)
    except:
        print('score2 creation crash')
        print('score2 creation crash', file=results)
        results.flush()
        return False

    if not score2.elements:
        print('score2 was empty')
        print('score2 was empty', file=results)
        results.flush()
        return False  # empty score2 is bad, because score1 was not empty

    if not score2.isWellFormedNotation():
        print('score2 not well formed')
        print('score2 not well formed', file=results)
        results.flush()
        return False

    # use music-score-diff to compare the two music21 scores,
    # and return whether or not they were identical
    try:
        annotatedScore1 = AnnScore(score1, DetailLevel.AllObjectsWithStyle)
        annotatedScore2 = AnnScore(score2, DetailLevel.AllObjectsWithStyle)
        op_list, _cost = Comparison.annotated_scores_diff(
            annotatedScore1, annotatedScore2)
        numDiffs = len(op_list)
        print(f'numDiffs = {numDiffs}')
        print(f'numDiffs = {numDiffs}', file=results)
        results.flush()
        if numDiffs > 0:
            summ: str = '\t' + oplistSummary(op_list, score1, score2)
            print(summ)
            print(summ, file=results)
            results.flush()
            return False
        return True
    except KeyboardInterrupt:
        sys.exit(0)
    except:
        print('musicdiff crashed')
        print('musicdiff crashed', file=results)
        results.flush()
        return False
    return True
Esempio n. 7
0
def runTheFullTest(krnPath: Path):
    print(f'krn file: {krnPath}')

    # resultsFileName = krnPath.stem + '.json'
    # resultsPath = krnPath.parent / resultsFileName

    # import into HumdrumFile
    hfb = HumdrumFile(str(krnPath))
    assert hfb.isValid

    # test against known good results
    # results = HumdrumFileTestResults.fromFiles(str(krnPath), str(resultsPath))
    # CheckHumdrumFile(hfb, results)

    # import HumdrumFile into music21 stream
    score1 = hfb.createMusic21Stream()
    assert score1 is not None
    assert score1.isWellFormedNotation() or not score1.elements

    # export score back to humdrum (without any makeNotation fixups)

    # if the score is empty, exporting from it will not produce anything interesting
    if not score1.elements:
        print('\tskipping export of empty score')
        return

#    score1.show('musicxml.pdf')

    hdw: HumdrumWriter = HumdrumWriter(score1)
    hdw.makeNotation = False
    hdw.addRecipSpine = krnPath.name == 'test-rhythms.krn'
    # hdw.expandTremolos = False

    success: bool = True
    fp = Path(tempfile.gettempdir()) / krnPath.name
    with open(fp, 'w', encoding='utf-8') as f:
        success = hdw.write(f)

#     if not success:
#         score1.show('musicxml.pdf')
    assert success

    # and then try to parse the exported humdrum file

    hfb = HumdrumFile(str(fp))
    #     if not hfb.isValid:
    #         score1.show('musicxml.pdf')
    assert hfb.isValid

    score2 = hfb.createMusic21Stream()
    #     if score2 is None or not score2.isWellFormedNotation():
    #         score1.show('musicxml.pdf')
    assert score2 is not None
    assert score2.isWellFormedNotation()

    # compare the two music21 scores

    # first with bbdiff:
    subprocess.run(['bbdiff', str(krnPath), str(fp)], check=False)

    # next with music-score-diff:
    print('comparing the two m21 scores')
    score_lin1 = AnnScore(score1)
    print('loaded first score')
    score_lin2 = AnnScore(score2)
    print('loaded second score')
    diffList, _cost = Comparison.annotated_scores_diff(score_lin1, score_lin2)
    print('diffed the two scores:')
    numDiffs = len(diffList)
    print(f'\tnumber of differences = {numDiffs}')
    if numDiffs > 0:
        print('now we will mark and display the two scores')
        Visualization.mark_diffs(score1, score2, diffList)
        print('marked the scores to show differences')
        Visualization.show_diffs(score1, score2)
        print('displayed both annotated scores')
Esempio n. 8
0
def ReadAllTestFilesInFolder(folder: str):
    krnPaths: [Path] = sorted(list(Path(folder).glob('**/*.krn')), key=str)
    print('numTestFiles in', folder, ' =', len(krnPaths))
    assert len(krnPaths) > 0

    numCrashes = 0
    crashIdxes = []
    for i, krnPath in enumerate(krnPaths):
        print('krn file {}: {}'.format(i, krnPath))

        # use this to skip files in folder (i.e. start with n, which is 0-based)
        # n = 78
        # if i < n:
        #     print(f'\tskipping any files before {n}th file in folder')
        #     continue
        #
        #         if krnPath.name == 'sonata07-1.krn':
        #             print('hi')

        resultsFileName = krnPath.stem + '.json'
        resultsPath = krnPath.parent / resultsFileName
        #         try:

        if 'tasso-scores' in str(krnPath) and krnPath.name in (
                'Tam2031034a-Vorro_veder_cio_che_Tirsi_avra_fatto--Balsamino_1594.krn',
        ):
            print(
                'skipping test because krnFile contains more than one score (not yet supported)'
            )
            continue

#         if 'rds-scores' in str(krnPath) and krnPath.name in (
#                 'R408_Web-w13p1-2m1-12.krn',
#                                                             ):
#             print('\tskipping import due to no note/chord/rest at end of tuplet')
#             continue

        if 'jrp-scores' in str(krnPath) and krnPath.name in (
                'Agr1001c-Missa_In_myne_zin-Sanctus.krn',
                'Agr1001d-Missa_In_myne_zin-Agnus.krn',
                'Mar2085-Salve_regina.krn',
        ):
            print(
                'skipping test because krnFile does not parse (inexpressible duration in tuplet)'
            )
            continue

        hfb = HumdrumFile(str(krnPath))
        assert (hfb.isValid)

        results = HumdrumFileTestResults.fromFiles(str(krnPath),
                                                   str(resultsPath))
        CheckHumdrumFile(hfb, results)

        # import humdrum into music21 stream

        score = hfb.createMusic21Stream()
        assert (score is not None)
        assert (score.isWellFormedNotation() or not score.elements)

        # export score back to humdrum (without any makeNotation fixups)

        # if the score is empty, exporting from it will not produce anything interesting
        if not score.elements:
            print('\tskipping export of empty score')
            continue

        # The following are worth working on, but I am skipping for now so I can run
        # all the tests to see where we are.

        # these are cases that cause extendTokenDuration to fail because it ran out
        # of room before the next note (music21 has overlapping notes, most likely)
        if krnPath.name in (
                'Tam2010724a-Picciola_e_lape_e_fa_col_picciol_morso--Balsamino_1594.krn',  # tasso-scores
        ):
            print(
                '\tskipping export due to overlapping note durations (unknown reason)'
            )
            continue

        if 'rds-scores' in str(krnPath) and krnPath.name in (
                'R319_Fal-w6p178-179h44m1-5.krn'):
            print(
                '\tskipping export due to unexported *tremolo causing overlapping note durations'
            )
            continue

        hdw: HumdrumWriter = HumdrumWriter(score)
        hdw.makeNotation = False
        hdw.addRecipSpine = krnPath.name == 'test-rhythms.krn'

        success: bool = True
        fp = Path(tempfile.gettempdir()) / krnPath.name
        with open(fp, 'w') as f:
            success = hdw.write(f)

        assert (success)

        # and then try to parse the exported humdrum file

        # These are cases where export produced an unparseable humdrum file.
        # The exported test-spine-float.krn is unparseable because it has duration differences
        # between spines (it gets really confused either during export or maybe during original
        # import)

        if krnPath.name in ('test-spine-float.krn', ):
            print('\tskipping parse of export due to *+ issues')
            continue

        # this is a weird one...
        if 'rds-scores' in str(krnPath) and krnPath.name in (
                'R262x_Ive-w33b4p26.krn', ):  # rds-scores
            print(
                '\tskipping parse of export due to two missing instrument abbreviation spines'
            )
            continue

        if 'tasso-scores' in str(krnPath) and krnPath.name in (
                'Trm0247a-Io_vidi_gia_sotto_lardente_sole--Marenzio_1584.krn',
        ):
            print(
                '\tskipping parse of export due to missing note weirdness (perhaps because of [whole]->[whole-dot)'
            )
            continue

        if 'rds-scores' in str(krnPath) and krnPath.name in (
                'R258_Ive-w30p9m55-57.krn', ):
            print(
                '\tskipping parse of export due to unparseable manipulators (original is even weirder, but parseable)'
            )
            continue

        if 'jrp-scores' in str(krnPath) and krnPath.name in (
                'Ock1013e-Requiem-Offertory_Domine_Jesu_Christe.krn', ):
            print(
                'skipping parse of export due to unparseable duration in tuplet'
            )
            continue

        hfb = HumdrumFile(str(fp))
        assert (hfb.isValid)

        score2 = hfb.createMusic21Stream()
        assert (score2 is not None)
        assert (score2.isWellFormedNotation())