Giter Club home page Giter Club logo

partitura's Introduction

Latest Release Pypi Package Unittest Status CodeCov Status Contributor Covenant

Partitura is a Python package for handling symbolic musical information. It supports loading from and exporting to MusicXML and MIDI files. It also supports loading from Humdrum kern and MEI.

The full documentation for partitura is available online at readthedocs.org.

User Installation

The easiest way to install the package is via pip from the PyPI (Python Package Index):

pip install partitura

This will install the latest release of the package and will install all dependencies automatically.

Quickstart

A detailed tutorial with some hands-on MIR applications is available here.

The following code loads the contents of an example MusicXML file included in the package:

import partitura as pt
my_xml_file = pt.EXAMPLE_MUSICXML
score = pt.load_score(my_xml_file)

The partitura load_score function will import any score format, i.e. (Musicxml, Kern, MIDI or MEI) to a partitura.Score object. The score object will contain all the information in the score, including the score parts. The following shows the contents of the first part of the score:

part = score.parts[0]
print(part.pretty())

Output:

Part id="P1" name="Piano"
 │
 ├─ TimePoint t=0 quarter=12
 │   │
 │   └─ starting objects
 │       │
 │       ├─ 0--48 Measure number=1
 │       ├─ 0--48 Note id=n01 voice=1 staff=2 type=whole pitch=A4
 │       ├─ 0--48 Page number=1
 │       ├─ 0--24 Rest id=r01 voice=2 staff=1 type=half
 │       ├─ 0--48 System number=1
 │       └─ 0-- TimeSignature 4/4
 │
 ├─ TimePoint t=24 quarter=12
 │   │
 │   ├─ ending objects
 │   │   │
 │   │   └─ 0--24 Rest id=r01 voice=2 staff=1 type=half
 │   │
 │   └─ starting objects
 │       │
 │       ├─ 24--48 Note id=n02 voice=2 staff=1 type=half pitch=C5
 │       └─ 24--48 Note id=n03 voice=2 staff=1 type=half pitch=E5
 │
 └─ TimePoint t=48 quarter=12
     │
     └─ ending objects
         │
         ├─ 0--48 Measure number=1
         ├─ 0--48 Note id=n01 voice=1 staff=2 type=whole pitch=A4
         ├─ 24--48 Note id=n02 voice=2 staff=1 type=half pitch=C5
         ├─ 24--48 Note id=n03 voice=2 staff=1 type=half pitch=E5
         ├─ 0--48 Page number=1
         └─ 0--48 System number=1
  

If lilypond or MuseScore are installed on the system, the following command renders the part to an image and displays it:

pt.render(part)

Score example

The notes in this part can be accessed through the property part.notes:

part.notes
> [<partitura.score.Note object at 0x...>, <partitura.score.Note object at 0x...>, 
> <partitura.score.Note object at 0x...>]

The following code stores the start, end, and midi pitch of the notes in a numpy array:

import numpy as np
pianoroll = np.array([(n.start.t, n.end.t, n.midi_pitch) for n in part.notes])
print(pianoroll)
> [[ 0 48 69]
>  [24 48 72]
>  [24 48 76]]

The note start and end times are in the units specified by the divisions element of the MusicXML file. This element specifies the duration of a quarter note. The divisions value can vary within an MusicXML file, so it is generally better to work with musical time in beats.

The part object has a property :part.beat_map that converts timeline times into beat times:

beat_map = part.beat_map
print(beat_map(pianoroll[:, 0]))
> [0. 2. 2.]
print(beat_map(pianoroll[:, 1]))
> [4. 4. 4.]

The following commands save the part to MIDI and MusicXML, or export it as a WAV file (using additive synthesis), respectively:

# Save Score MIDI to file.
pt.save_score_midi(part, 'mypart.mid')

# Save Score MusicXML to file.
pt.save_musicxml(part, 'mypart.musicxml')

# Save as audio file using additive synthesis
pt.save_wav(part, 'mypart.wav')

More elaborate examples can be found in the documentation <https://partitura.readthedocs.io/en/latest/index.html>_.

Import other formats

For MusicXML files do:

import partitura as pt
my_xml_file = pt.EXAMPLE_MUSICXML
score = pt.load_musicxml(my_xml_file)

For Kern files do:

import partitura as pt
my_kern_file = pt.EXAMPLE_KERN
score = pt.load_kern(my_kern_file)

For MEI files do:

import partitura as pt
my_mei_file = pt.EXAMPLE_MEI
score = pt.load_mei(my_mei_file)

One can also import any of the above formats by just using:

import partitura as pt
any_score_format_path = pt.EXAMPLE_MUSICXML
score = pt.load_score(any_score_format_path)

License

The code in this package is licensed under the Apache 2.0 License. For details, please see the LICENSE file.

Citing Partitura

If you find Partitura useful, we would appreciate if you could cite us!

@inproceedings{partitura_mec,
  title={{Partitura: A Python Package for Symbolic Music Processing}},
  author={Cancino-Chac\'{o}n, Carlos Eduardo and Peter, Silvan David and Karystinaios, Emmanouil and Foscarin, Francesco and Grachten, Maarten and Widmer, Gerhard},
  booktitle={{Proceedings of the Music Encoding Conference (MEC2022)}},
  address={Halifax, Canada},
  year={2022}
}

Acknowledgments

This project receives funding from the European Research Council (ERC) under the European Union's Horizon 2020 research and innovation programme under grant agreement No 101019375 "Whither Music?".

This work has received support from the European Research Council (ERC) under the European Union’s Horizon 2020 research and innovation programme under grant agreement No. 670035 project "Con Espressione" and the Austrian Science Fund (FWF) under grant P 29840-G26 (project "Computer-assisted Analysis of Herbert von Karajan's Musical Conducting Style")

partitura's People

Contributors

anusfoil avatar fosfrancesco avatar huispaty avatar ivnsp avatar manoskary avatar mgrachten avatar neosatrapahereje avatar nimrodvarga avatar sildater avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

partitura's Issues

pianoroll column index exceed matrix dimension

An exception is raised when generating a pianoroll with onset_only = True from a performedPart, after setting mid.sustain_pedal_threshold = 127.

The code to reproduce the problem is:

mid = partitura.load_performance_midi("MIDI-Unprocessed_03_R2_2008_01-03_ORIG_MID--AUDIO_03_R2_2008_wav--3.midi")
mid.sustain_pedal_threshold = 127
partitura.utils.compute_pianoroll(mid, onset_only = True)

MIDI-Unprocessed_03_R2_2008_01-03_ORIG_MID--AUDIO_03_R2_2008_wav--3.zip

Update dtypes

As of Numpy 1.20.0, the use of np.int or np.float is deprecated, and it is suggested to use int or float by itself. Otherwise, we get the following warnings:

DeprecationWarning: `np.int` is a deprecated alias for the builtin `int`. To silence this warning, use `int` by itself. Doing this will not modify any behavior and is safe. When replacing `np.int`, you may wish to use e.g. `np.int64` or `np.int32` to specify the precision. If you wish to review your current use, check the release note link for additional information.
Deprecated in NumPy 1.20; for more details and guidance: https://numpy.org/devdocs/release/1.20.0-notes.html#deprecations
DeprecationWarning: `np.float` is a deprecated alias for the builtin `float`. To silence this warning, use `float` by itself. Doing this will not modify any behavior and is safe. If you specifically wanted the numpy scalar type, use `np.float64` here.
Deprecated in NumPy 1.20; for more details and guidance: https://numpy.org/devdocs/release/1.20.0-notes.html#deprecations

Exclude ongoing ties from removal in load_musicxml

In line 272 load_musicxml cleans up all ongoing (unfinished) elements after the full part is loaded:

        # remove unfinished elements from the timeline
        for k, o in ongoing.items():
            if k not in ("page", "system"):
                if isinstance(o, list):
                    for o_i in o:
                        part.remove(o_i)
                else:
                    part.remove(o)

For tied notes the "ongoing" dict contains the note object itself which shouldn't be removed from the part. Notes with ongoing/open ties are yet unchanged (note.tie_next is None) and can just be ignored.

Don't remove incomplete Slurs/Tuplets when loading MusicXML

Currently Incomplete slurs and tuplets are removed in the load_musicxml function. The incomplete elements can be a nuisance for some cases, but for other use cases they are vital (e.g. a UI application that allows a user to load MusicXML and correct incomplete slurs or tuplets), so they should not be removed.

Matchfile version 1 error?

file importmatch.py line 525:
pattern_v1 = MatchNote.pattern + '-' + MatchNote.pattern_v1
instead of:
pattern_v1 = MatchSNote.pattern + '-' + MatchNote.pattern_v1

Use Part or PerformedPart objects directly as inputs for methods in `partitura.musicanalysis`

Until now, all methods in partitura.musicanalysis take a note array (i.e., a structured array) generated from a Part object as an input. Since these methods are also commonly applied to performance information, it would be very useful to allow users to also use the methods with information from a PerformedPart object. Furthermore, allowing the input to these methods to be either a structured array, a Part or PerformedPart object would simplify their usage.

Restructure time-related fields in the `note_array` property of `Part` and `PerformedPart` objects

In order to avoid confusion with different time units (e.g., beats, quarters, divs for Part objects), it would be beneficial to rename the time-related fields in note arrays to be explicit about the units:

  • Structured note arrays should include all available time units (e.g., onset_beats, onset_quarters, etc.).
  • Remove redundant properties (i.e., remove note_array_quarters), as well as deprecate the note_to_notearray method (in partitura.utils.music).
  • Check compatibility with new field names throughout package, specifically:
    • the note_array attribute of the PartGroup class
    • the musicxml_to_notearray function

save_match relies on unreliable score information

matchfile_from_alignment() (called from ````partitura.save_match()```) relies on existence and uniqueness of measure numbers, which cannot be guaranteed. See line 122 in partitura/io/exportmatch.py

incorrect doc string for estimate_key

The documentation for the estimate_key function says that it returns a triplet of root, mode, and fifths, but in reality it only returns a string representation of the root+mode.

add measure_number_map

add a map that returns the measure number of the measure that contains a timepoint in divs.

Missing UnpitchedNote class

As far as I understand correctly, there is no such class and during XML import, all notes without a pitch are treated as Rests, even percussive notes.

I have seen in the documentation of GenericNote that this is planned anyway, I just thought opening an issue might be a good idea.

New `Score` object

Currently, loading a score from a file can result in either a single Part object, a PartGroup or a list of parts. While it is possible to ensure that the output of the score loading methods is a list of Part objects, it would be convenient to have a simple Score object that works like a list, but can have a few extra attributes to hold meta information about the score (e.g., piece name, composer, layout of the piece?)

A basic structure of the object could be

class Score(object):
    parts # list of parts
    note_array # note array of the combined parts
    title = 'Title of the Score'
    composer = 'Composer'
    score_info # Information about formatting of the score (paper size, etc., if available)

The introduction of a Score object would change the current default behavior of the current methods and can/will result in somethings not being backwards compatible anymore.

For now, development of this class will be on the score_class branch, and we should not merge it in develop until we have tested all loader methods thoroughly.

Inconsistent default staff values

In io.importmusicxml._handle_direction the default value for 'staff' is 1 if there is none specified, however for other objects the default value is None.
The 1 should be changed to None, so as to be consistent with the other values and it also makes more sense, what if there is no staff 1 specified anywhere in a score?

Barline to score time mapping in load_musicxml

The musicxml tag defines the attribute "location" with the possible values "left", "right", and "middle": https://www.w3.org/2021/06/musicxml40/musicxml-reference/elements/barline/

With this attribute the barline can be placed at any moment in a measure without taking care of the current typehead and it should still be placed at the end or the beginning of the measure if the attribute is "right" or "left", respectively. load_musicxml ignores this information which can lead to wrong repeat placements ( elements are children of ).

New Matchfile format

A new version of the Matchfile format that will streamline the information in (performed) note lines, and add the missing information to fully represent/infer the (performed) repetition structure of a score.

note_array_from_note_list include attribute GraceNote of type bool

In partitura.utils.note_array_from_note_list add a attribute is_gracenote : bool . This will add this field in the partitura.utils.ensure_notearray to easily detect grace notes or at least include them in the note array.

Current Method

The currect method to deal with Grace notes in note arrays is to filter notes by 0 duration.

Possible Grace Note types

int instead of bool for Grace notes.

Tests for exporting MEI files

Since we do not currently have a method for importing MEI, we should simply check that the method for exporting MEI is able to reproduce a "ground truth" file, which we know works using online visualization tools for MEI (i.e., Verovio).

Examples for methods in `partitura.musicanalysis`

It would be important to add examples in the documentation to all methods in partitura.musicanalysis module. This would make the usage of these methods clearer to the users without having to dive into the code.

Methods with missing examples:

  • estimate_spelling (in partitura.musicanalysis.pitch_spelling)
  • estimate_key (in partitura.musicanalysis.key_identification)
  • estimate_voices (in partitura.musicanalysis.voice_separation)
  • estimate_tonaltension(in partitura.musicanalysis.tonaltension)

Add cleanup of ties to score.sanitize_part

Sometimes ties are encoded wrongly or incompletely in musicxml files. Partitura parses ties by pitch so weird errors can occur. partitura.score.sanitize_part() could include removal of ties whose tied duration doesn't correspond to the difference between starting and ending time point. That is, notes that are tied even though they are not adjacent in the score.

The method musicxml_to_notearray does not work on scores with multiple parts

The Error occured when tried to parse a score with 4 parts and the number of note instances in every part are different.

Traceback (most recent call last):
  File "src\descriptors\note_density.py", line 132, in <module>
    note_array = partitura.musicxml_to_notearray(my_musicxml_file)
  File "C:\Users\melki\Desktop\JKU\codes\Music-Structure-Segmentation\venv\lib\site-packages\partitura\io\importmusicxml.py", line 1304, in musicxml_to_notearray
    scr = np.vstack(scr)
  File "<__array_function__ internals>", line 5, in vstack
  File "C:\Users\melki\Desktop\JKU\codes\Music-Structure-Segmentation\venv\lib\site-packages\numpy\core\shape_base.py", line 283, in vstack
    return _nx.concatenate(arrs, 0)
  File "<__array_function__ internals>", line 5, in concatenate
ValueError: all the input array dimensions for the concatenation axis must match exactly, but along dimension 1, the array at index 0 has size 300 and the array at index 1 has size 257

The method musicxml_to_notearray is quite old, and should be deprecated. It was created in an early version of partitura, but then we moved to a different way to get note_arrays.

It should be replaced by the method ensure_notearray (in partitura.utils).

Example :

note_array = partitura.utils.ensure_notearray(partitura.load_musicxml("/my/score.musicxml"))

Add example in the documentation for loading MIDI files

Partitura has two methods for loading MIDI files, load_performance_midi and load_score_midi, which return PerformedPart and Part objects, respectively. For users that are not familiar with the distinction between score and performance, this might be confusing. Therefore, it would be important to add an example in the documentation of a usual pipeline for getting common information from a MIDI file (e.g., MIDI pitch, MIDI velocity, onset times in seconds, etc.), as well as a quick guide that helps users decide which loading method would be the appropriate for their use cases.

Nakamura-file format functions incorrectly assume that values are tab separated

Since Nakamura does not seem to specify a separation character for the text file formats, I think the functions should accept any whitespace separated data, or at least spaces, as he uses in his examples.

To illustrate the problem: when copy-pasting the data from the example in Nakamura's manual, page 5:

0 1.00833 C#5 73 36 0 0 C#5 73 50
1 1.025 A3 57 32 2 0.00625 A3 57 31

The function load_nakamuracorresp returns empty arrays.

Restructure/simplify method for piano roll

  • Update the method for generating piano rolls following issues #16 and #17
  • Add default time_div for performance and score
  • Test with multiple MIDI files for potential issues? (e.g., percussion instruments, etc.)

Undefined Variable Error

In score.py, in the method _cleanup_point of the class Part
_self.remove_point is called with o.end, however o is not defined within the scope of the method

I think the intention was to simply pass the parameter tp onto _self.remove_point and that definitely fixes the error, however, not sure if it is intended that way.

Naming format in exportmei.py

  • Rename (fix camel case) methods defined in exportmei.py to have a consistent naming throughout the package.
  • Add the export MEI method to init.py

Partitura Save Musicxml saves empty part,

The partitura.save_musicxml functions saves an empty part with no notes.

I'm working on fix_kern branch that was taken from the latest develop.

To reproduce input any kern score :

For examle

import partitura
ps = partitura.load_kern(partitura.EXAMPLE_KERN)
partitura.save_musicxml(ps, "example_kern.musicxml")

produced file :

<?xml version='1.0' encoding='UTF-8'?>
<!DOCTYPE score-partwise PUBLIC
  "-//Recordare//DTD MusicXML 3.1 Partwise//EN"
  "http://www.musicxml.org/dtds/partwise.dtd">
<score-partwise>
  <part-list>
    <score-part id="score_example">
      <part-name>0</part-name>
    </score-part>
    <score-part id="score_example">
      <part-name>1</part-name>
    </score-part>
  </part-list>
  <part id="score_example"/>
  <part id="score_example"/>
</score-partwise>

To save a single part:

import partitura
ps = partitura.score.merge_parts(partitura.load_kern(partitura.EXAMPLE_KERN))
partitura.save_musicxml(ps, "example_kern.musicxml")

metrical information for incomplete measures

Incomplete measures, i.e. pickup measures and "split measures" (for repetitions or key signature changes), pose a challenge for the computation of metrical information.
image

Assuming that we can correctly detect them (not so easy for repetitions, and not possible if there are other encoding mistakes) the following points need to be discussed:

  1. should the downbeat be only on D or on D and F?
  2. should the measure_map for the note F return as start_measure the position of D or the position of F? Conversely what should end_measure be for notes D and E?
  3. should the start_measure for a pickup bar be on the 0 or should it be set to a negative number to give the "complete" measure?

update README.rst

Check that all code examples in README.rst are correct, and relevant.

Cashed properties for time maps in `Part` objects

For many use cases, Part objects do not change after being created. Nevertheless, attributes such as beat_map and quarter_map are being computed every time, which can be very slow for large pieces. Therefore, it would be useful to just compute these properties once.

Add part merger for piano scores

Piano scores can be "wrongly" saved in an XML as a list of different parts or as a group of parts.
This will be encoded in partitura with a list(Part) or with a PartGroup.

We should add a utility to collapse those representations into a single part when we are sure that only a single part exists (e.g. for piano music).

Upper/lower case note names

The documentation of Note suggests that lower case note names can be used for the step argument, but this yields unexpected results (calling render shows the note at the wrong staff position). The documentation should be updated to use upper case names, and perhaps we should convert step to uppercase, for more robustness.

Import_match Create Part error.

Key Error occurs when load_match function is called with create_part = True. Issue resolved when old_part_generator=True.

There seems to be an issue with some files in which the position of the notes in the score (from the cells with bar:beat_in_bar and beat_offset) seems to not match with the position of the notes using the onset_in_beats cell. part_from_matchfile_old uses the onset_in_beats information from the Matchfile, whereas part_from_matchfile uses the other (redundant) information.
It seems that bar_times does not have an element starting at 0, which means that either the position of that bar is incorrectly coded in the match file, or there is something else going on.

Using current partitura develop branch


KeyError                                  Traceback (most recent call last)

<ipython-input-16-079fc90cb3e0> in <module>
      1 from basismixer.performance_codec import to_matched_score
      2 
----> 3 ppart, alignment, spart = partitura.load_match( match_file_path)

~\AppData\Local\Programs\Python\Python38\lib\site-packages\partitura\io\importmatch.py in load_match(fn, create_part, pedal_threshold, first_note_at_zero, old_part_generator)
   1131             spart = part_from_matchfile_old(mf)
   1132         else:
-> 1133             spart = part_from_matchfile(mf)
   1134     ###### Alignment ########
   1135     alignment = alignment_from_matchfile(mf)

~\AppData\Local\Programs\Python\Python38\lib\site-packages\partitura\io\importmatch.py in part_from_matchfile(mf)
   1329     for (ts_beat_time, ts_bar, (ts_beats, ts_beat_type)) in ts:
   1330         #import pdb; pdb.set_trace()
-> 1331         bar_start_divs = int(divs * (bar_times[ts_bar] - offset))  # in quarters
   1332         bar_start_divs = max(0,bar_start_divs)
   1333         part.add(score.TimeSignature(ts_beats, ts_beat_type), bar_start_divs)

KeyError: 0

Add support for all MIDI controls in `PerformedPart`

Currently, PerformedPart only adds sustain and soft pedal information and discards other MIDI controls. In order to add support for all MIDI controls, they need to be registered in performed part.

Furthermore, instead of having a dictionary with the name and number of the control types, only register the number of the control messages. This would make MIDI_CONTROL_TYPES no longer needed, so it should be removed.

Load compressed MusicXML

So far, load_musicxml only allows for loading uncompressed MusicXML files (.xml or .musicxml), but compressed MusicXML files (.mxl) are widely available online (e.g., from MuseScore).

This feature should be very simple to add, since it just requires to unzip the .mxl file and then load the expanded .musicxml.

Error exporting score MIDI file from Part with pickup measure.

There is an error in save_score_midi when exporting a MIDI file from a Part with a pickup measure. The error is caused by the negative onset times in quarters of the notes in the pickup measure.

~/miniconda3/envs/environment/lib/python3.7/site-packages/mido/midifiles/meta.py in encode_variable_int(value)
    110     """
    111     if not isinstance(value, Integral) or value < 0:
--> 112         raise ValueError('variable int must be a positive integer')
    113
    114     bytes = []

ValueError: variable int must be a positive integer

Move beat_per_measure from time_signature to metrical_position

Right now the time_signature_map beat, refers to the beat that is being used in the part, i.e. either musical beat or notate beat. This can be confusing for people that want to know the "real" time signature.

I plan to move this "number of beat per measure" information to be returned as part of the metrical_position information.

Inconsistent use of warning and logging

It seems some functions of partitura use a logger while others use the warnings library. Is there a reason for this or should we fix this?

Related to this: sometimes it'd be nice if partitura could handle everything silently. Consistent logging/warning makes this easier.

Performance Array integration from Basis Mixer

As a feature of music Analysis we propose the integration of Performance arrays including local tempo, timing, velocity and articulation.

A match file can be imported with Partitura and compute the performance array using a minimally integrated version of the Performance Codec from Basis Mixer in Partitura. The performance array should be used in unison with the note array.

Type Error in an utility function

In utils/music.py

the function "pitch_spelling_to_midi_pitch(step, alter, octave)"

uses the parameter "octave" directly as an integer, however it is of type String

this is simply fixed by converting the parameter to an int before usage

Obsolete functions in `partitura.utils.music`?

Since the Part class has a note_array property I suppose it supersedes the notes_to_notearray function in partitura.utils.music. Since function and the property do not yield identical results we should ensure that the functions that take the notes_to_notearray output as its input (mostly in partitura.music_analysisI guess) handle the output of the Part.note_array property. Especially since the onsets/durations are returned as floats instead of ints.

Besides that polyphonicslices_from_notearray seems to have a typo causing an undefined variable and an unused variable, which makes me wonder whether we should keep this function. If it would be in use the bug would have been spotted. What about polyphonicslices_from_parts?

Solution as discussed: remove notes_to_notearray and (for now) polyphonic slicing related functions.

Chew voice estimation test results to Error in develop branch.

The test_vosa_chew and the test_vosa_chew_chordnotes both result to error when running unittests on the develop branch #61 .

Here is the resulting :

Run python -m unittest discover ./tests/ 'test*.py'
.........................................No key signature found, assuming C major
..FF......
======================================================================
FAIL: test_vosa_chew (test_voice_estimation.TestVoSA)
----------------------------------------------------------------------
Traceback (most recent call last):
  File "/home/runner/work/partitura/partitura/tests/test_voice_estimation.py", line 28, in test_vosa_chew
    self.assertTrue(
AssertionError: False is not true : Incorrect voice assignment.

======================================================================
FAIL: test_vosa_chew_chordnotes (test_voice_estimation.TestVoSA)
----------------------------------------------------------------------
Traceback (most recent call last):
  File "/home/runner/work/partitura/partitura/tests/test_voice_estimation.py", line 40, in test_vosa_chew_chordnotes
    self.assertTrue(
AssertionError: False is not true : Incorrect voice assignment.

----------------------------------------------------------------------
Ran 51 tests in 32.766s

FAILED (failures=2)
Error: Process completed with exit code 1.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.