{"id":16346580,"url":"https://github.com/marcomusy/pianoplayer","last_synced_at":"2025-10-03T20:51:28.371Z","repository":{"id":40625767,"uuid":"107160052","full_name":"marcomusy/pianoplayer","owner":"marcomusy","description":"Automatic fingering generator for piano scores","archived":false,"fork":false,"pushed_at":"2025-05-17T19:59:07.000Z","size":10111,"stargazers_count":797,"open_issues_count":26,"forks_count":92,"subscribers_count":18,"default_branch":"master","last_synced_at":"2025-09-29T01:16:04.376Z","etag":null,"topics":["fingering","music21","piano","piano-fingering","piano-fingers","piano-keyboard","piano3d"],"latest_commit_sha":null,"homepage":"","language":"Python","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/marcomusy.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null}},"created_at":"2017-10-16T17:25:47.000Z","updated_at":"2025-09-28T05:07:19.000Z","dependencies_parsed_at":"2022-08-01T00:08:01.887Z","dependency_job_id":"9fff3bf0-d519-4405-8e98-beb8bcafe783","html_url":"https://github.com/marcomusy/pianoplayer","commit_stats":{"total_commits":84,"total_committers":6,"mean_commits":14.0,"dds":0.3571428571428571,"last_synced_commit":"511af06c24f254dd02c99f6efe79b46f6ed03bd3"},"previous_names":[],"tags_count":3,"template":false,"template_full_name":null,"purl":"pkg:github/marcomusy/pianoplayer","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/marcomusy%2Fpianoplayer","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/marcomusy%2Fpianoplayer/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/marcomusy%2Fpianoplayer/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/marcomusy%2Fpianoplayer/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/marcomusy","download_url":"https://codeload.github.com/marcomusy/pianoplayer/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/marcomusy%2Fpianoplayer/sbom","scorecard":{"id":618172,"data":{"date":"2025-08-11","repo":{"name":"github.com/marcomusy/pianoplayer","commit":"511af06c24f254dd02c99f6efe79b46f6ed03bd3"},"scorecard":{"version":"v5.2.1-40-gf6ed084d","commit":"f6ed084d17c9236477efd66e5b258b9d4cc7b389"},"score":3.2,"checks":[{"name":"Token-Permissions","score":-1,"reason":"No tokens found","details":null,"documentation":{"short":"Determines if the project's workflows follow the principle of least privilege.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#token-permissions"}},{"name":"Code-Review","score":1,"reason":"Found 3/24 approved changesets -- score normalized to 1","details":null,"documentation":{"short":"Determines if the project requires human code review before pull requests (aka merge requests) are merged.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#code-review"}},{"name":"Dangerous-Workflow","score":-1,"reason":"no workflows found","details":null,"documentation":{"short":"Determines if the project's GitHub Action workflows avoid dangerous patterns.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#dangerous-workflow"}},{"name":"Maintained","score":0,"reason":"0 commit(s) and 0 issue activity found in the last 90 days -- score normalized to 0","details":null,"documentation":{"short":"Determines if the project is \"actively maintained\".","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#maintained"}},{"name":"Binary-Artifacts","score":10,"reason":"no binaries found in the repo","details":null,"documentation":{"short":"Determines if the project has generated executable (binary) artifacts in the source repository.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#binary-artifacts"}},{"name":"Packaging","score":-1,"reason":"packaging workflow not detected","details":["Warn: no GitHub/GitLab publishing workflow detected."],"documentation":{"short":"Determines if the project is published as a package that others can easily download, install, easily update, and uninstall.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#packaging"}},{"name":"CII-Best-Practices","score":0,"reason":"no effort to earn an OpenSSF best practices badge detected","details":null,"documentation":{"short":"Determines if the project has an OpenSSF (formerly CII) Best Practices Badge.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#cii-best-practices"}},{"name":"Pinned-Dependencies","score":-1,"reason":"no dependencies found","details":null,"documentation":{"short":"Determines if the project has declared and pinned the dependencies of its build process.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#pinned-dependencies"}},{"name":"Security-Policy","score":0,"reason":"security policy file not detected","details":["Warn: no security policy file detected","Warn: no security file to analyze","Warn: no security file to analyze","Warn: no security file to analyze"],"documentation":{"short":"Determines if the project has published a security policy.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#security-policy"}},{"name":"Fuzzing","score":0,"reason":"project is not fuzzed","details":["Warn: no fuzzer integrations found"],"documentation":{"short":"Determines if the project uses fuzzing.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#fuzzing"}},{"name":"License","score":10,"reason":"license file detected","details":["Info: project has a license file: LICENSE:0","Info: FSF or OSI recognized license: MIT License: LICENSE:0"],"documentation":{"short":"Determines if the project has defined a license.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#license"}},{"name":"Vulnerabilities","score":10,"reason":"0 existing vulnerabilities detected","details":null,"documentation":{"short":"Determines if the project has open, known unfixed vulnerabilities.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#vulnerabilities"}},{"name":"Signed-Releases","score":-1,"reason":"no releases found","details":null,"documentation":{"short":"Determines if the project cryptographically signs release artifacts.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#signed-releases"}},{"name":"Branch-Protection","score":0,"reason":"branch protection not enabled on development/release branches","details":["Warn: branch protection not enabled for branch 'master'"],"documentation":{"short":"Determines if the default and release branches are protected with GitHub's branch protection settings.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#branch-protection"}},{"name":"SAST","score":0,"reason":"SAST tool is not run on all commits -- score normalized to 0","details":["Warn: 0 commits out of 10 are checked with a SAST tool"],"documentation":{"short":"Determines if the project uses static code analysis.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#sast"}}]},"last_synced_at":"2025-08-21T04:32:08.646Z","repository_id":40625767,"created_at":"2025-08-21T04:32:08.646Z","updated_at":"2025-08-21T04:32:08.646Z"},"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":278227254,"owners_count":25951883,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","status":"online","status_checked_at":"2025-10-03T02:00:06.070Z","response_time":53,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["fingering","music21","piano","piano-fingering","piano-fingers","piano-keyboard","piano3d"],"created_at":"2024-10-11T00:35:41.984Z","updated_at":"2025-10-03T20:51:28.332Z","avatar_url":"https://github.com/marcomusy.png","language":"Python","funding_links":[],"categories":[],"sub_categories":[],"readme":"# PianoPlayer\n\n[![Codacy Badge](https://api.codacy.com/project/badge/Grade/fb513fa9c1a34f9988ec5dc443cbe633)](https://app.codacy.com/app/marcomusy/pianoplayer?utm_source=github.com\u0026utm_medium=referral\u0026utm_content=marcomusy/pianoplayer\u0026utm_campaign=Badge_Grade_Settings)\n[![Downloads](https://pepy.tech/badge/pianoplayer)](https://pepy.tech/project/pianoplayer)\n[![lics](https://img.shields.io/badge/license-MIT-blue.svg)](https://en.wikipedia.org/wiki/MIT_License)\n[![DOI](https://zenodo.org/badge/107160052.svg)](https://zenodo.org/badge/latestdoi/107160052)\n\n\nAutomatic piano fingering generator. \u003cbr /\u003e\nFind the optimal fingering combination to play a piano score.\nOptionally visualize it in 3D with [vedo](https://github.com/marcomusy/vedo).\u003cbr /\u003e\n\n## Download and Install:\n```bash\npip install pianoplayer\n```\nto enable sound you may need to:\n```bash\nsudo apt install libasound2-dev\npip install simpleaudio\n```\n\n#### Installing without 3D rendering\nTo only install the core functionality and skip everything else, use the following:\n```bash\npip install music21\npip install --no-deps pianoplayer\n```\n\nTo visualize the output annotated score install the latest\n[musescore](https://musescore.org/en/download), or any other renderer\nof [MusicXML](https://en.wikipedia.org/wiki/MusicXML)\nfiles.\n\n**Windows 10** users can place this file:\n[pianoplayer.bat](https://github.com/marcomusy/pianoplayer/blob/master/pianoplayer.bat)\non their desktop (edit the path to your local anaconda or python installation).\nCheck out [this link](https://github.com/marcomusy/pianoplayer/issues/27) in case of\ninstallation problems.\n\n\n## CLI Usage:\nExample command line from terminal:\u003cbr /\u003e\n`pianoplayer scores/bach_invention4.xml --verbose -n10 -rvzm`\u003cbr /\u003e\nwill find the right hand fingering for the first 10 measures,\npop up a 3D rendering window and invoke *musescore*.\n\nThe output is saved as a [MusicXML](https://en.wikipedia.org/wiki/MusicXML)\nfile with name `output.xml`.\u003cbr /\u003e\n\n```bash\npianoplayer         # if no argument is given a GUI will pop up (on windows try `python pianoplayer.py`)\n# Or\npianoplayer [-h] [-o] [-n] [-s] [-d] [-k] [-rbeam] [-lbeam] [-q] [-m] [-v] [--vedo-speed]\n            [-z] [-l] [-r] [-XXS] [-XS] [-S] [-M] [-L] [-XL] [-XXL]\n            filename\n# Valid file formats: MusicXML, musescore, midi (.xml, .mscz, .mscx, .mid)\n#\n# Optional arguments:\n#   -h, --help            show this help message and exit\n#   -o , --outputfile     Annotated output xml file name\n#   -n , --n-measures     [100] Number of score measures to scan\n#   -s , --start-measure  Start from measure number [1]\n#   -d , --depth          [auto] Depth of combinatorial search, [2-9]\n#   -rbeam                [0] Specify Right Hand beam number\n#   -lbeam                [1] Specify Left Hand beam number\n#   --quiet               Switch off verbosity\n#   -m, --musescore       Open output in musescore after processing\n#   -b, --below-beam      Show fingering numbers below beam line\n#   -v, --with-vedo       Play 3D scene after processing\n#   -z, --sound-off       Disable sound\n#   -l, --left-only       Fingering for left hand only\n#   -r, --right-only      Fingering for right hand only\n#   -XXS, --hand-size-XXS Set hand size to XXS\n#   -XS, --hand-size-XS   Set hand size to XS\n#   -S, --hand-size-S     Set hand size to S\n#   -M, --hand-size-M     Set hand size to M\n#   -L, --hand-size-L     Set hand size to L\n#   -XL, --hand-size-XL   Set hand size to XL\n#   -XXL, --hand-size-XXL Set hand size to XXL\n```\n\n### GUI Usage:\u003cbr /\u003e\nJust type `pianoplayer` in a terminal\n(or double click the\n[pianoplayer.bat](https://github.com/marcomusy/pianoplayer/blob/master/pianoplayer.bat) file),\nthen:\n\n![newgui](https://user-images.githubusercontent.com/32848391/63605343-09365000-c5ce-11e9-97b8-a5642e71ca24.png)\n\n- press **Import Score** (valid formats: *musescore, MusicXML, MIDI, [PIG](http://beam.kisarazu.ac.jp/~saito/research/PianoFingeringDataset/)*)\n- press **GENERATE** (`output.xml` is written)\n- press **Musescore** to visualize the annotated score\n- press **3D Player** to show the animation (Press `Esc` to quit the application)\n\n\n#### Example output, as displayed in *musescore*:\n\n(If fingering numbers are not visible enough try `-b` option.)\n\n\n![bachinv4](https://user-images.githubusercontent.com/32848391/63605352-10f5f480-c5ce-11e9-8b00-34f1adc2e79b.png)\n\n\n![pianoplayer3d](https://user-images.githubusercontent.com/32848391/63605322-0176ab80-c5ce-11e9-8213-b572d0303523.gif)\n\n\n## How the algorithm works:\nThe algorithm minimizes the fingers speed needed to play a sequence of notes or chords by searching\nthrough feasible combinations of fingerings.\n\nOne possible advantage of this algorithm over similar ones is that it is completely *dynamic*,\nwhich means that it\ntakes into account the physical position and speed of fingers while moving on the keyboard\nand the duration of each played note.\nIt is *not* based on a static look-up table of likely or unlikely combinations of fingerings.\n\nFingering a piano score can vary a lot from individual to individual, therefore there is not such\na thing as a \"best\" choice for fingering.\nThis algorithm is meant to suggest a fingering combination which is \"optimal\" in the sense that it\nminimizes the effort of the hand avoiding unnecessary movements.\n\n## Parameters you can change:\n- Your hand size (from 'XXS' to 'XXL') which sets the relaxed distance between thumb and pinkie.\n- The beam number associated to the right hand is by default nr.0 (nr.1 for left hand).\nYou can change it with `-rbeam` and `-lbeam` command line options.\n- Depth of combinatorial search, from 3 up to 9 notes ahead of the currently playing note. By\ndefault the algorithm selects this number automatically based on the duration of the notes to be played.\n\n## Limitations\n- Some specific fingering combinations, considered too unlikely in the first place, are excluded from the search (e.g. the 3rd finger crossing the 4th).\n- Hands are always assumed independent from each other.\n- In the 3D representation with sounds enabled, notes are played one after the other (no chords),\nso the tempo within the measure is not always respected.\n- Small notes/ornaments are ignored.\n\n\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fmarcomusy%2Fpianoplayer","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fmarcomusy%2Fpianoplayer","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fmarcomusy%2Fpianoplayer/lists"}