PianoPlayer

repository·master·Indexed 21 days ago

https://github.com/marcomusy/pianoplayer

An automatic piano fingering generator that finds and visualizes low-effort fingering sequences for MusicXML and MIDI scores. It features a CLI, a Tkinter GUI, and a Web API to process scores, with optional 3D rendering via vedo and support for various hand size presets (XXS to XXL).

Tokens
10.2K
Snippets
34
Records
48
Agent score
71%

What's inside pianoplayer

  1. How PianoPlayer routing works

    master

    PianoPlayer automatically determines how to assign hands to parts or staves. You can use --auto-routing (default) or --manual-routing to override this behavior.

    Routing Logic:

    • 2-part piano scores: Hands are selected by -rpart and -lpart.
    • 1-part, 2-staff piano scores: Hands are selected by staff (RH -> staff 1, LH -> staff 2).
    • Manual Override: Use --manual-routing combined with --rstaff and --lstaff to explicitly define staff numbers for the right and left hands.
  2. Use PianoPlayer via CLI

    master

    Run PianoPlayer from the command line to generate fingerings for a score file.

    Example command: pianoplayer scores/bach_invention4.xml -n 10 -r -v -z -m This command annotates the first 10 measures for the right hand, enables 3D playback, disables sound, and opens the result in MuseScore.

    Default Outputs:

    • MusicXML/MuseScore inputs: Defaults to output.xml.
    • MIDI/PIG inputs: Defaults to annotated tabular output in output.txt.
    pianoplayer scores/bach_invention4.xml -n 10 -r -v -z -m
  3. Install PianoPlayer via pip

    master

    Install the core package using pip:

    pip install pianoplayer

    You can also install optional extras for specific functionality:

    • 3D rendering with vedo: pip install "pianoplayer[visual]"
    • MIDI input support: pip install "pianoplayer[midi]"
    • Enable playback: pip install "pianoplayer[sound]"
    • All optional extras: pip install "pianoplayer[all]"
  4. Build a standalone executable

    master

    To create a standalone executable (without 3D visualization) using PyInstaller, install the build extra and run the provided script:

    pip install "pianoplayer[build]"
    python scripts/build_standalone.py

    Output locations:

    • Linux/macOS: dist/pianoplayer
    • Windows: dist/pianoplayer.exe
  5. Install and run the PianoPlayer Web API locally

    master

    To run the PianoPlayer Web API on your local machine, install the package with the [web] extra and use uvicorn to start the server.

    Supported score file formats for upload include: .xml, .mxl, .mid, .midi, .mscz, .mscx, and .txt.

    pip install "pianoplayer[web]"
    uvicorn webapi.app:app --host 127.0.0.1 --port 8000
  6. Use the PianoPlayer GUI

    master

    To launch the graphical user interface, run pianoplayer without any filename arguments.

    GUI Workflow:

    1. Import Score: Click to load valid formats (MusicXML/MXL, MuseScore, MIDI, PIG).
    2. Generate: Click GENERATE to process the score. Output is saved to output.xml (scores) or output.txt (MIDI/PIG).
    3. Visualize: Click Musescore to view the annotated score (Linux/macOS only).
    4. Advanced Settings: Use the Advanced menu to:
      • Toggle Auto hand routing.
      • Set manual part/staff routing.
      • Enable Colorize hands or Colorize by cost.
    5. Quit: Press Quit, q, or Ctrl+W to exit.
  7. How the annotation pipeline works

    master

    The annotate() function executes a multi-stage pipeline:

    1. Parsing: Loads the input file (MusicXML, MIDI, etc.) and resolves routing (which part/staff belongs to which hand).
    2. Anchor Detection: Scans the input for existing fingering data. If found, these notes are treated as 'anchors' and preserved during optimization.
    3. Hand Generation: Creates Hand objects for the right and left hands. The solver optimizes fingering based on the specified hand_size and depth.
    4. Output Writing:
      • For MusicXML: Annotates the score with fingering and color information.
      • For PIG/MIDI: Writes a tab-separated text file containing note events.
    5. Optional 3D Playback: If with_vedo is enabled, launches a 3D virtual keyboard visualization.
  8. How VirtualKeyboard playback works

    master

    The VirtualKeyboard.play() method implements a step-by-step playback loop.

    The Lifecycle:

    1. Initialization: The keyboard scene, hands (left/right), and decorative elements are built.
    2. The Loop: The method enters a while loop that increments absolute time t by dt.
    3. Hand Movement: For each hand, the system:
      • Releases notes: If a note's duration has elapsed, the finger and key are visually 'released' (moved back to neutral position).
      • Attacks notes: If a note's start time is reached, the finger moves to the correct position and the key is pressed.
    4. User Interaction: The loop blocks at each note attack using _wait_for_advance_key(). The user must press Space to proceed to the next note or Esc/q to abort.
    5. Audio: If playsounds is True and an audio backend is available, play_sound() is called during note attacks.
  9. How Hand posture memory and physical constraints work

    master

    The Hand class uses a combination of target positions and physical constraints to model realistic piano playing:

    1. Relaxed Targets: For any given finger assignment, the class calculates where the other fingers should be if the hand were in a relaxed state relative to the active finger.
    2. Posture Memory: If preserve_posture_memory is enabled, the finger positions are calculated as a weighted average between the previous position and the new relaxed target, controlled by relocation_alpha.
    3. Physical Constraints: After calculating positions, the class applies several constraints to ensure realism:
      • Max Follow Lag: Fingers cannot lag too far behind their relaxed target position (max_follow_lag_cm).
      • Minimum Finger Gap: Fingers must maintain a minimum distance from each other (min_finger_gap_cm) to prevent interpenetration.
      • Maximum Span: The distance between the thumb (finger 1) and pinky (finger 5) is capped (max_span_cm).
  10. Use the PianoPlayer CLI

    master

    PianoPlayer can be run from the command line to annotate music files (MusicXML, MIDI, etc.) with optimized fingerings. You can provide a filename as a positional argument, or launch the Tkinter GUI by using the --gui flag or by running the command without any arguments.

    Supported Input Formats:

    • MusicXML (.xml, .mxl)
    • MuseScore (.mscz, .mscx)
    • MIDI (.mid, .midi)
    • PIG (.txt)

    Basic Usage:

    # Process a file with default settings
    pianoplayer my_score.mxl
    
    # Launch the GUI
    pianoplayer --gui
    
    # Process a file and save to a specific output name
    pianoplayer my_score.mid -o annotated_output.mid
    pianoplayer my_score.mxl
  11. Use the /annotate API endpoint

    master

    The /annotate endpoint processes uploaded score files and returns an annotated version.

    Request Method: POST
    Content-Type: multipart/form-data

    Parameters

    ParameterTypeRequiredDescription
    fileFileYesThe score file to annotate
    hand_sizeAnyNoAnnotation parameter
    depthAnyNoAnnotation parameter
    n_measuresAnyNoAnnotation parameter
    start_measureAnyNoAnnotation parameter
    left_onlyAnyNoAnnotation parameter
    right_onlyAnyNoAnnotation parameter
    below_beamAnyNoAnnotation parameter
    rpartAnyNoAnnotation parameter
    lpartAnyNoAnnotation parameter
    chord_note_stagger_sAnyNoAnnotation parameter

    Responses

    The API returns a file attachment based on the input format:

    • MusicXML/MuseScore inputs: Returns an annotated MusicXML file named *_annotated.xml.
    • MIDI/PIG inputs: Returns an annotated tabular text file named *_annotated.txt.
    POST /annotate HTTP/1.1
    Host: 127.0.0.1:8000
    Content-Type: multipart/form-data
    
    --boundary
    Content-Disposition: form-data; name="file"; filename="score.mid"
    
    [binary data]
    --boundary--