# jaynik-s/pianoannotations architecture

> Architecture diagram of the GitHub repository jaynik-s/pianoannotations, generated by GitDiagram from its file tree, README and a sample of source files (last updated 2026-09-29). It is an AI-made overview: check details against the source.

- Interactive diagram: https://gitdiagram.com/jaynik-s/pianoannotations
- Repository: https://github.com/jaynik-s/pianoannotations

## Overview

Piano Annotations converts MIDI into normalized note events, onset-based chord groups, RH/LH labels, and a JSON payload; a separate rendering stage loads that JSON, quantizes note starts onto shared time columns, and produces aligned ASCII and/or HTML. The graph follows the CLI-owned calls and shared layout used by both renderers. README documents these capabilities; sampled source supports the wiring shown, while details of any unsampled implementation are not inferred.

Main entry points: [`src/main.py`](https://github.com/jaynik-s/pianoannotations/blob/main/src/main.py) (CLI pipelines), [`src/midi_parser.py`](https://github.com/jaynik-s/pianoannotations/blob/main/src/midi_parser.py) (MIDI parser), [`src/quantizer.py`](https://github.com/jaynik-s/pianoannotations/blob/main/src/quantizer.py) (Grid quantizer), [`src/renderer.py`](https://github.com/jaynik-s/pianoannotations/blob/main/src/renderer.py) (ASCII renderer)

## Diagram (Mermaid)

```mermaid
flowchart TD

subgraph group_midi_stage["MIDI analysis"]
  node_cli["CLI pipelines<br/>[main.py]"]
  node_midi_parser["MIDI parser<br/>[midi_parser.py]"]
  node_normalizer["Note normalization<br/>[midi_parser.py]"]
  node_grouping["Chord grouping<br/>[chord_grouping.py]"]
  node_hands["Hand inference<br/>[hand_inference.py]"]
  node_exporter["JSON export<br/>[exporter.py]"]
end

subgraph group_render_stage["Annotation rendering"]
  node_json_loader["JSON loader<br/>[quantizer.py]"]
  node_quantizer["Grid quantizer<br/>[quantizer.py]"]
  node_layout["Shared layout<br/>[renderer.py]"]
  node_ascii["ASCII renderer<br/>[renderer.py]"]
  node_html["HTML renderer<br/>[html_renderer.py]"]
end

subgraph group_shared["Shared models"]
  node_schema["Note schemas<br/>[note_schema.py]"]
end

node_musician(("MIDI user"))
node_json_file["Stage-one JSON"]
node_ascii_file["ASCII annotation"]
node_html_file["HTML annotation"]
node_midi_file["MIDI file"]
node_pretty_midi["pretty_midi"]

node_musician -->|"invokes"| node_cli
node_musician -->|"provides"| node_midi_file
node_cli -->|"parses via"| node_midi_parser
node_midi_parser -->|"reads"| node_midi_file
node_midi_parser -->|"loads with"| node_pretty_midi
node_midi_parser -->|"normalizes"| node_normalizer
node_normalizer -->|"feeds notes"| node_grouping
node_cli -->|"builds groups"| node_grouping
node_cli -->|"infers hands"| node_hands
node_cli -->|"builds payload"| node_exporter
node_exporter -->|"writes JSON"| node_json_file
node_cli -->|"writes via exporter"| node_json_file
node_cli -->|"loads for rendering"| node_json_loader
node_json_loader -->|"reads"| node_json_file
node_json_loader -->|"passes payload"| node_quantizer
node_cli -->|"quantizes via loader"| node_quantizer
node_cli -->|"renders ASCII"| node_ascii
node_cli -->|"renders HTML"| node_html
node_ascii -->|"builds systems"| node_layout
node_html -->|"builds systems"| node_layout
node_quantizer -->|"provides score"| node_ascii
node_quantizer -->|"provides score"| node_html
node_ascii -->|"writes output"| node_ascii_file
node_html -->|"writes output"| node_html_file

click node_cli "https://github.com/jaynik-s/pianoannotations/blob/main/src/main.py"
click node_midi_parser "https://github.com/jaynik-s/pianoannotations/blob/main/src/midi_parser.py"
click node_normalizer "https://github.com/jaynik-s/pianoannotations/blob/main/src/midi_parser.py"
click node_grouping "https://github.com/jaynik-s/pianoannotations/blob/main/src/chord_grouping.py"
click node_hands "https://github.com/jaynik-s/pianoannotations/blob/main/src/hand_inference.py"
click node_exporter "https://github.com/jaynik-s/pianoannotations/blob/main/src/exporter.py"
click node_json_loader "https://github.com/jaynik-s/pianoannotations/blob/main/src/quantizer.py"
click node_quantizer "https://github.com/jaynik-s/pianoannotations/blob/main/src/quantizer.py"
click node_layout "https://github.com/jaynik-s/pianoannotations/blob/main/src/renderer.py"
click node_ascii "https://github.com/jaynik-s/pianoannotations/blob/main/src/renderer.py"
click node_html "https://github.com/jaynik-s/pianoannotations/blob/main/src/html_renderer.py"
click node_schema "https://github.com/jaynik-s/pianoannotations/blob/main/src/note_schema.py"

classDef toneNeutral fill:#f8fafc,stroke:#334155,stroke-width:1.5px,color:#0f172a
classDef toneBlue fill:#dbeafe,stroke:#2563eb,stroke-width:1.5px,color:#172554
classDef toneAmber fill:#fef3c7,stroke:#d97706,stroke-width:1.5px,color:#78350f
classDef toneMint fill:#dcfce7,stroke:#16a34a,stroke-width:1.5px,color:#14532d
classDef toneRose fill:#ffe4e6,stroke:#e11d48,stroke-width:1.5px,color:#881337
classDef toneIndigo fill:#e0e7ff,stroke:#4f46e5,stroke-width:1.5px,color:#312e81
classDef toneTeal fill:#ccfbf1,stroke:#0f766e,stroke-width:1.5px,color:#134e4a
class node_cli,node_midi_parser,node_normalizer,node_grouping,node_hands,node_exporter,node_musician toneBlue
class node_json_loader,node_quantizer,node_layout,node_ascii,node_html toneAmber
class node_schema toneMint
class node_json_file,node_ascii_file,node_html_file,node_midi_file,node_pretty_midi toneIndigo
```

## Components

### MIDI analysis

- [CLI pipelines](https://github.com/jaynik-s/pianoannotations/blob/main/src/main.py): `src/main.py`
- [MIDI parser](https://github.com/jaynik-s/pianoannotations/blob/main/src/midi_parser.py): `src/midi_parser.py`
- [Note normalization](https://github.com/jaynik-s/pianoannotations/blob/main/src/midi_parser.py): `src/midi_parser.py`
- [Chord grouping](https://github.com/jaynik-s/pianoannotations/blob/main/src/chord_grouping.py): `src/chord_grouping.py`
- [Hand inference](https://github.com/jaynik-s/pianoannotations/blob/main/src/hand_inference.py): `src/hand_inference.py`
- [JSON export](https://github.com/jaynik-s/pianoannotations/blob/main/src/exporter.py): `src/exporter.py`

### Annotation rendering

- [JSON loader](https://github.com/jaynik-s/pianoannotations/blob/main/src/quantizer.py): `src/quantizer.py`
- [Grid quantizer](https://github.com/jaynik-s/pianoannotations/blob/main/src/quantizer.py): `src/quantizer.py`
- [Shared layout](https://github.com/jaynik-s/pianoannotations/blob/main/src/renderer.py): `src/renderer.py`
- [ASCII renderer](https://github.com/jaynik-s/pianoannotations/blob/main/src/renderer.py): `src/renderer.py`
- [HTML renderer](https://github.com/jaynik-s/pianoannotations/blob/main/src/html_renderer.py): `src/html_renderer.py`

### Shared models

- [Note schemas](https://github.com/jaynik-s/pianoannotations/blob/main/src/note_schema.py): `src/note_schema.py`

### Other components

- **MIDI user**
- **Stage-one JSON**
- **ASCII annotation**
- **HTML annotation**
- **MIDI file**
- **pretty_midi**

## Connections

- MIDI user → CLI pipelines: invokes
- MIDI user → MIDI file: provides
- CLI pipelines → MIDI parser: parses via
- MIDI parser → MIDI file: reads
- MIDI parser → pretty_midi: loads with
- MIDI parser → Note normalization: normalizes
- Note normalization → Chord grouping: feeds notes
- CLI pipelines → Chord grouping: builds groups
- CLI pipelines → Hand inference: infers hands
- CLI pipelines → JSON export: builds payload
- JSON export → Stage-one JSON: writes JSON
- CLI pipelines → Stage-one JSON: writes via exporter
- CLI pipelines → JSON loader: loads for rendering
- JSON loader → Stage-one JSON: reads
- JSON loader → Grid quantizer: passes payload
- CLI pipelines → Grid quantizer: quantizes via loader
- CLI pipelines → ASCII renderer: renders ASCII
- CLI pipelines → HTML renderer: renders HTML
- ASCII renderer → Shared layout: builds systems
- HTML renderer → Shared layout: builds systems
- Grid quantizer → ASCII renderer: provides score
- Grid quantizer → HTML renderer: provides score
- ASCII renderer → ASCII annotation: writes output
- HTML renderer → HTML annotation: writes output
