Skip to content

A2M Piano Engine

Justagwas edited this page Jul 15, 2026 · 1 revision

A2M Piano Engine

The A2M Piano Engine is one transcription system executed through CPU, CUDA, or DirectML. It combines a feature frontend, two ONNX model components, interval decoding, and section stitching; CPU and GPU modes do not select different musical models.

A2M audio-to-MIDI pipeline

The model bundle

Component Role
frontend.npz Six analysis windows and the mel filter that produce compatible input features
scorer.onnx Scores possible event intervals and produces learned context
attributes.onnx Predicts velocity, refined onset/offset timing, and boundary presence
manifest.json Declares the model identity, frontend dimensions, symbols, components, versions, sizes, and hashes

The current bundle identifies Piano Engine version 1.0.1, schema 1, and model ID a2m-piano.

Ninety modeled symbol tracks

The score tensor has one track for each modeled symbol:

  • 88 piano pitches, MIDI 21 through 108;
  • sustain pedal, represented internally as -64 and exported as CC64;
  • soft pedal, represented internally as -67 and exported as CC67.

Negative values distinguish controller symbols from note pitches inside the event pipeline. The current bundle has no sostenuto CC66 symbol.

Scoring intervals instead of isolated frames

For each section, the scorer returns:

  • interval_scores, evidence for possible start/end pairs on each symbol track;
  • skip_scores, evidence used when the decoded path advances without an event;
  • context, a learned representation used by the attribute model.

The interval-score shape is conceptually T × T × 90: two time dimensions describe candidate start and end positions, and the final dimension selects a note or pedal symbol. This lets the decoder reason about an event's span instead of thresholding every frame independently.

Conceptual interval scores and Viterbi decoding

Decoding and attributes

A backward Viterbi-style dynamic program compares skip paths with scored intervals and reconstructs a coherent path using back-pointers. A forced-start position carries relevant state across overlapping sections.

For each selected interval, attributes.onnx then predicts:

  • one MIDI velocity class;
  • onset and offset adjustment within approximately half a frame;
  • whether an onset or offset is genuinely present at a section boundary.

The model frame is about 23.22 ms, while refinement can move a boundary by roughly ±11.61 ms. That gives the output continuous timing rather than restricting every event to the frame grid.

Session reuse and GPU batching

The scorer and attribute sessions are cached by resolved model path, device, provider, and runtime path. CPU processes one section per inference batch. GPU execution can batch several sections; if a scorer batch exceeds available capacity, A2M reduces it and retries.

Changing the provider affects where operations execute and how work is batched. It does not change the model weights or intended interpretation of the score.

Primary source files: piano_engine.py, model_service.py, onnx_runtime_service.py, and runtime_service.py.

Clone this wiki locally