Handel Dixit Dominus HWV 232 — répétiteur / piano rendering architecture
Canonical accompaniment rendering workflow v1 FINAL
Status: canonical production method
Date: 8 Oct 2026
Scope: canonical accompaniment method through Movement 8 FINAL
Companion canonical documents:
DIXIT_REHEARSAL_METHODS_canonical_through_mvt8_FINAL.md
DIXIT_MODULAR_PLAYER_ARCHITECTURE_v1_FINAL_updated_through_mvt8_FINAL.md
This document is authoritative for the accompaniment construction and piano-rendering layer of the project.
Its purpose is to prevent three distinct decisions from becoming conflated:
what Handel wrote
↓
what the rehearsal piano should play
↓
what piano timbre renders that accepted MIDI
The first two are musical/structural decisions. The third is a rendering decision.
A change in piano sound must not silently change the accepted notes, rhythms, ties, voicing, or reduction logic.
1. Canonical layered model
Use this separation:
literal instrumental score extraction
↓
instrumental QC / tie / tuplet validation
↓
accepted rehearsal reduction MIDI
↓
canonical piano rendering chain
↓
canonical WAV master
↓
web MP3
↓
hidden player calibration
Each layer should be independently reproducible.
Do not collapse the pipeline into "generate a piano WAV".
2. Decide the accompaniment strategy from the written texture
Two accompaniment cases are now established.
A. Sparse continuo texture
If the score supplies essentially:
solo voice
+
continuo / figured bass
the rehearsal accompaniment may require a cautious harmonic realisation.
Movement 2 — Virgam virtutis tuae — is the canonical example.
The realisation should remain subordinate to the written bass and figures. Do not invent gratuitous pianistic activity.
B. Fully written orchestral texture
If Handel has already written enough independent upper voices to define the harmony, reduce those written voices directly.
Movement 3 — Tecum principium — is the canonical example:
RH / upper texture:
Violin I
Violin II
Viola I
Viola II
LH / bass:
continuo
General rule:
Fully written harmony should be reduced before harmony is invented.
The répétiteur is a rehearsal representation of Handel's written texture, not an attempt to reproduce an unrelated published piano reduction.
3. Literal instrumental extraction must close before reduction
Do not repair parser errors inside the reduction layer.
For every instrumental staff:
- parse literal pitches;
- parse literal durations;
- parse active clef;
- parse accidentals;
- identify ties;
- identify rests;
- identify candidate tuplets;
- validate every measure against the active metre.
Proceed to reduction only when there are zero unexplained bar-closure errors.
Movement 3 final instrumental extraction:
Violin I 403 events
Violin II 257 events
Viola I 190 events
Viola II 194 events
Continuo 244 events
confirmed instrumental ties: 12
unexplained bar-closure errors: 0
This is the model standard.
4. Tuplets: engraving topology proposes; metre validates
Do not classify every three-note beam group as a triplet.
Canonical inference:
- use common physical beam-group identity to identify a triplet candidate;
- evaluate that interpretation against exact measure closure;
- choose the smallest necessary set of tuplet interpretations that closes the bar correctly;
- preserve ordinary quavers where straight duration already closes the metre.
Movement 3 continuo bar 35 is the regression case:
dotted crotchet
+
three ordinary beamed quavers
=
exactly one 3/4 bar
Those three quavers are not a triplet.
5. Ties are structural, not cosmetic
Confirmed ties must survive into the accompaniment MIDI.
Canonical MIDI behaviour:
tie source -> note-on
tie destination -> NO new note-on
final tie note -> note-off
Do not re-articulate a tied bass or upper voice merely because a new bar begins.
Harmonic reattack rule
Movement 2 exposed a subtler failure:
A tied bass was correctly sustained, but the generated RH chord was re-struck at the tie destination, making the whole piano texture sound as though the bass had been attacked again.
Canonical rule:
If an RH attack occurs exactly on a confirmed bass-tie destination, repeats the existing voicing, and there is no new harmonic/figured-bass instruction, sustain the existing texture rather than re-striking it.
If harmony genuinely changes over the tied bass, the upper texture may move.
Tie QC must therefore inspect the whole accompaniment texture, not just the literal bass MIDI events.
6. The accepted MIDI is the musical master of the accompaniment
Once the reduction has passed listening QC, freeze the MIDI independently from its rendered piano sound.
For Movement 3:
accepted musical reduction:
dixit_mvt3_repetiteur_piano_v1.mid
When the piano timbre was later found to differ from Movements 1 and 2, the correct repair was:
reuse accepted v1 MIDI unchanged
↓
rerender through canonical piano chain
Do not regenerate the reduction merely to change timbre.
Core rule:
Notes/timing and instrument rendering are separate versioned layers.
7. Canonical piano rendering chain
The accepted common piano timbre for the project is:
renderer:
FluidSynth
SoundFont:
/usr/share/sounds/sf2/FluidR3_GM.sf2
instrument:
FluidR3 General MIDI Acoustic Grand Piano
FluidSynth gain:
-g 0.6
sample rate:
44100 Hz
Canonical command pattern:
fluidsynth -ni -g 0.6 \
/usr/share/sounds/sf2/FluidR3_GM.sf2 \
INPUT.mid \
-F OUTPUT.wav \
-r 44100
This rendering family was established in Movement 1 and retained for the accepted Movement-2 répétiteur.
Movement 3 was initially rendered with a different piano sound; it was later rerendered from the accepted v1 MIDI through this FluidSynth/FluidR3 chain and accepted as matching the earlier movements.
Therefore:
FluidSynth + FluidR3_GM.sf2 is the canonical répétiteur piano renderer unless a future project-wide change is explicitly evaluated and accepted.
Do not silently fall back to another installed SoundFont merely because it is available.
8. Canonical WAV versus web encoding
The canonical accompaniment render should first exist as an uncompressed WAV.
Movement-3 matched-timbre render:
/home/ajp/dixit/mvt3/
dixit_mvt3_repetiteur_piano_v2_FluidR3.wav
The web player should use a derived MP3.
Typical project web encoding:
ffmpeg -i INPUT.wav \
-ac 1 \
-ar 32000 \
-codec:a libmp3lame \
-b:a 96k \
OUTPUT.mp3
A higher-bitrate audition MP3 may also be produced, e.g. 160 kb/s.
Never treat the web MP3 as the canonical musical master.
Hierarchy:
accepted MIDI
+
canonical WAV
>
web MP3
9. Do not bake player balance into the master audio
Raw piano render level and rehearsal-player balance are separate concerns.
The canonical WAV should not be destructively amplified or normalised merely to make a particular web-player slider position convenient.
Instead:
raw rendered level
↓
hidden per-stem calibration
↓
visible mixer percentage
The visible mixer defaults to 70%.
The hidden calibration compensates for differences between renderers, voicebanks, and accompaniment masters.
10. Recalculate calibration after a timbre/render change
A new piano render can differ dramatically in raw level even when it represents the same MIDI.
Therefore a timbre rerender invalidates the previous hidden calibration.
Movement 3 is the canonical example.
Original Movement-3 piano render:
required hidden piano calibration ≈ 9.0
That unusually high factor reflected the quiet raw render, not a musical desire for ninefold piano emphasis.
After rerendering through the canonical FluidR3 chain:
- compare the raw new piano level with an accepted reference piano;
- account for the movement's master gain;
- derive a new starting hidden calibration;
- audition musically;
- freeze only after listening.
A calibration value belongs to:
specific audio render
+
specific player gain structure
It does not belong permanently to "Movement 3 piano".
11. Reference-based starting calibration
Movement 2 is a useful accepted reference because its final piano is already part of the common FluidR3 family.
Accepted Movement-2 player values:
Piano hidden calibration = 3.59
master gain = 0.58
A useful starting estimate for a newly rerendered Movement-3 piano is:
new_calibration
≈
reference_calibration
×
(reference_master / target_master)
×
linear RMS-level ratio
where:
linear RMS-level ratio
=
10 ^ ((reference_dB - target_dB) / 20)
This is a starting point, not an automatic musical truth.
Final calibration still requires comparative listening.
12. MIDI instrument/program discipline
The accompaniment MIDI should use an acoustic piano program compatible with the canonical SoundFont.
If a builder creates a dedicated piano reduction MIDI, ensure its program change is explicit rather than relying on whatever program the synthesizer happens to default to.
For General MIDI, Acoustic Grand Piano is program 1 in human-facing numbering (program value 0 in zero-based MIDI program-change data).
Do not allow an orchestral preview program assignment to leak into the répétiteur MIDI.
13. Velocity and articulation principles
The répétiteur is not intended to imitate a concert pianist.
Its priorities are:
- rhythmic clarity;
- voice-leading clarity;
- stable rehearsal pulse;
- correct harmonic attacks;
- tied-note continuity;
- enough dynamic differentiation to avoid mechanical hammering.
Do not use renderer-specific tricks to conceal incorrect notation.
If articulation sounds wrong, first inspect:
score extraction
tie interpretation
MIDI note-on/off placement
voicing
velocity
before changing reverb, EQ, SoundFont, or post-processing.
14. Pedal policy
Do not use sustain pedal as a substitute for correct tie handling.
Pedal may be considered only if it improves the rehearsal sound without smearing contrapuntal detail.
Default canonical assumption:
structural legato comes from correct MIDI durations/ties
not from continuous sustain pedal
Any pedal layer introduced later should be explicit and reproducible.
15. Post-processing policy
Default production principle:
Prefer the SoundFont render itself over a chain of corrective effects.
Do not add undocumented:
- EQ;
- compression;
- limiting;
- reverb;
- stereo widening;
- loudness normalization.
If post-processing becomes necessary, record the exact command/settings and apply the decision consistently across all movements.
Player-side compression is a separate playback-system decision and must not be confused with alteration of the canonical accompaniment master.
16. File/version naming
Version the musical reduction and rendered sound separately when appropriate.
Example:
dixit_mvt3_repetiteur_piano_v1.mid
may remain the accepted note/timing master while the corrected common-timbre render becomes:
dixit_mvt3_repetiteur_piano_v2_FluidR3.wav
This means:
v1 MIDI = accepted musical reduction
v2 audio = new render of that same accepted reduction
The version bump documents an audible production change without falsely implying that the score reduction was rewritten.
17. Reproduction workflow for a future movement
For Movement 4 onward:
Phase A — build the accompaniment
- extract all relevant instrumental staves;
- verify staff topology;
- resolve clefs and accidentals;
- identify ties;
- identify tuplet candidates;
- require exact bar closure;
- decide:
- sparse continuo → cautious harmonic realisation;
- fully written texture → direct reduction;
- produce rehearsal-piano MIDI;
- regression-test ties and repeated harmony;
- listen;
- freeze the accepted MIDI.
Phase B — render the canonical piano
Use:
fluidsynth -ni -g 0.6 \
/usr/share/sounds/sf2/FluidR3_GM.sf2 \
ACCEPTED.mid \
-F CANONICAL.wav \
-r 44100
Then audition.
Phase C — create the web stem
Encode a derived MP3.
Do not replace the canonical WAV with the MP3.
Phase D — calibrate
- install the web stem;
- set a reference-derived starting hidden calibration;
- compare against previous accepted movements;
- adjust only the hidden calibration;
- leave visible default at 70%;
- freeze the accepted value in
movement.json.
18. Regression checklist
Before freezing a new accompaniment:
MUSICAL CONTENT
[ ] literal instrumental bars all close
[ ] no unexplained tuplet interpretations
[ ] all confirmed ties survive into MIDI
[ ] tied harmony is not falsely re-attacked
[ ] accompaniment strategy matches score texture
[ ] accepted MIDI has been auditioned independently
RENDERING
[ ] FluidSynth used
[ ] exact FluidR3_GM.sf2 path used
[ ] FluidSynth gain = 0.6
[ ] render sample rate = 44100 Hz
[ ] explicit piano program is correct
[ ] no undocumented pedal/effects/post-processing
VERSIONING
[ ] accepted reduction MIDI retained
[ ] canonical WAV retained
[ ] web MP3 treated as derivative
[ ] timbre-only changes do not rewrite the MIDI
PLAYER
[ ] hidden calibration recalculated after any audio rerender
[ ] visible mixer remains 70% default
[ ] balance compared against accepted neighbouring movements
[ ] calibration frozen only after listening
19. Current production references
Movement 1 — Dixit Dominus
Established the FluidSynth / FluidR3_GM rendering family.
Canonical rendering principle:
FluidSynth
FluidR3_GM.sf2
44.1 kHz
Movement 2 — Virgam virtutis tuae
Canonical sparse-continuo realisation example.
Accepted accompaniment:
répétiteur piano v3 tie-aware FINAL
Accepted player calibration:
Piano 3.59
Movement 2 also established the whole-texture tie rule: unchanged RH harmony must not create a false reattack over a tied bass.
Movement 3 — Tecum principium
Canonical fully written orchestral reduction example.
Accepted musical reduction:
dixit_mvt3_repetiteur_piano_v1.mid
Accepted reduction architecture:
Violin I + Violin II + Viola I + Viola II
↓
upper piano texture
continuo
↓
piano bass
The first piano render used a different timbre and was later superseded for project consistency.
Accepted common-timbre rerender:
dixit_mvt3_repetiteur_piano_v2_FluidR3.wav
It reuses the accepted v1 MIDI unchanged and renders it through the same FluidSynth / FluidR3 chain as the preceding movements.
This is the canonical example of separating musical master from instrument-render master.
Movement 6 — Dominus a dextris tuis
Accepted musical master:
dixit_mvt6_repetiteur_piano_v2.mid
Accepted canonical render:
/home/ajp/dixit/mvt6/dixit_mvt6_repetiteur_piano_v2.wav
Accepted rendering chain remains unchanged:
FluidSynth
/usr/share/sounds/sf2/FluidR3_GM.sf2
-g 0.6
44100 Hz
Movement 6 established a new reduction rule for exact simultaneous doubled orchestral unisons.
The literal v1 reduction retained both Vln I and Vln II when they struck the same pitch simultaneously, and likewise both Viola I and Viola II. A piano render then triggered the same piano key/sample twice at the same instant, creating artificial weight, especially at the full-tutti entrance around bar 81.
Accepted v2 treatment:
within Vln I + Vln II:
same attack time + same MIDI pitch -> one piano attack
within Vla I + Vla II:
same attack time + same MIDI pitch -> one piano attack
Keep all of the following distinct:
same-family exact unison duplication -> collapse
cross-family pitch coincidence -> retain
continuo coincidence -> retain
true repeated note -> retain
written tie -> sustain, no reattack
Movement-6 v2 audit:
logical attacks v1: 2215
logical attacks v2: 1686
duplicates removed: 529
before bar 81: 1
bars 81–148: 528
This is not dynamic compression and not a player-side attenuation rule. It is a correction to the keyboard reduction itself.
The accepted final player piano calibration is:
1.7382
at visible 70%. It was deliberately retained from the already satisfactory light first half after the v2 reduction was introduced; the bar-81 correction came from fixing note multiplicity rather than turning down the whole piano.
Movement-6 timing:
148 bars · 3/4 throughout · 100 BPM
score/MIDI endpoint: 266.400 s
FluidR3 WAV endpoint: 269.105 s
renderer tail: 2.705 s
The natural FluidR3 tail is preserved rather than trimmed to the MIDI boundary.
20. Canonical rule summary
1. Parse literally.
2. Require rhythmic closure.
3. Resolve ties before reduction.
4. Choose reduction strategy from the written texture.
5. Freeze the accepted accompaniment MIDI.
6. Render every accepted répétiteur through FluidSynth + FluidR3_GM.sf2.
7. Keep the canonical WAV.
8. Encode web audio only as a derivative.
9. Recalculate hidden calibration whenever the rendered audio changes.
10. Never regenerate musical content merely to change piano timbre.
11. In a piano reduction, collapse exact simultaneous same-pitch attacks from
paired doubled orchestral staves when they represent one physical piano key;
do not collapse cross-family coincidences or continuo.
That is the accompaniment/piano standard for the remainder of the project.
21. Movement 7 — Judicabit — piano v1 FINAL
Movement 7 adds two extraction lessons before reduction.
21.1 Continuo clef changes are local score state
The Continuo changes clef within systems. Pitch extraction therefore uses the latest active clef to the left of each note rather than a fixed staff-level clef.
Canonical parser rule:
part default clef
-> overridden by any printed in-staff clef change
-> active until the next printed clef change
Do not allow a clef glyph from another system on the same PDF page to leak into the current system. Clef ownership must be constrained both by staff ownership and by vertical proximity to the current score system.
21.2 Polyphonic continuo bars validate by voice, not by summed duration
Movement 7 Continuo contains genuine simultaneous written voices in:
bars 2, 3, 8, 13, 41, 42
A monophonic bar-closure test therefore reports raw totals greater than four quarter notes:
bar 2 8.0 q
bar 3 8.0 q
bar 8 6.5 q
bar 13 7.0 q
bar 41 5.5 q
bar 42 10.0 q
These are not malformed measures. The parser must separate simultaneous voices (e.g. by stem direction / voice topology) and validate each complete voice independently.
For piano v1, the complete lower/bass voice is selected from each such measure:
bar 2 down-stem bass voice
bar 3 down-stem bass voice
bar 8 down-stem bass voice
bar 13 down-stem bass voice + written rests
bar 41 up-stem bass voice
bar 42 down-stem bass voice
The resulting selected Continuo bass closes exactly in all 61 measures.
21.3 Literal extraction audit
Movement 7 score:
61 bars
4/4 throughout
100 BPM rehearsal tempo
one-flat key signature
exact score duration = 146.400 s
Literal instrumental extraction:
Violin I 594 events / 538 pitched notes
Violin II 594 events / 538 pitched notes
Viola I 384 events / 304 pitched notes
Viola II 383 events / 304 pitched notes
Violoncello/Bass 81 events / 67 pitched notes
Continuo 409 events / 383 pitched notes
Upper strings close exactly in all 61 bars. The separate Violoncello/Bass staff is useful as an audit of the Continuo bass where it is present, but the reduction uses the Continuo bass line so that passages where the orchestral bass rests but keyboard continuo continues are preserved.
21.4 Reduction architecture
Movement 7 is a fully written orchestral-texture case:
Violin I + Violin II
-> upper piano texture
Viola I + Viola II
-> upper piano texture
selected written Continuo bass voice
-> lower piano texture
No new harmony is invented.
Movement-6 same-family exact-unison collapse remains in force:
within Violin I + II:
same attack + same MIDI pitch -> one piano attack
within Viola I + II:
same attack + same MIDI pitch -> one piano attack
cross-family coincidence -> retain
continuo coincidence -> retain
true repeated note -> retain
written tie -> sustain
Movement-7 v1 reduction audit:
upper-string logical spans before same-family collapse: 1684
upper-string attacks after collapse: 1170
same-family duplicate attacks removed: 514
Continuo-bass logical spans: 360
total reduction attacks: 1530
Accepted musical master:
dixit_mvt7_repetiteur_piano_v1.mid
The unchanged v1 MIDI was subsequently rendered through the canonical FluidR3 chain, accepted by listening, and promoted to FINAL.
21.5 Historical preview render was not the canonical timbre
During construction, a convenience preview was rendered through:
TimGM6mb.sf2
44.1 kHz
gain 0.6
Preview files:
dixit_mvt7_repetiteur_piano_v1_PREVIEW_TimGM6mb.wav
dixit_mvt7_repetiteur_piano_v1_PREVIEW_TimGM6mb.mp3
That preview was never promoted as a canonical master.
The accepted unchanged MIDI was later rendered using the project-standard chain:
fluidsynth -ni -g 0.6 \
/usr/share/sounds/sf2/FluidR3_GM.sf2 \
dixit_mvt7_repetiteur_piano_v1.mid \
-F dixit_mvt7_repetiteur_piano_v1.wav \
-r 44100
The FluidR3 render was accepted. Movement-7 final timing and player calibration are:
score/MIDI endpoint: 146.400 s
FluidR3/player endpoint: 148.402 s
renderer tail: 2.002 s
Piano hidden calibration: 2.3179
Movement 7 piano v1 is therefore FINAL.
22. Movement 8 — Conquassabit — piano v1 FINAL
Movement 8 confirms the Movement-6/7 direct-written-reduction architecture and adds a useful system-ownership regression case.
22.1 Literal instrumental extraction
Movement 8 score:
50 bars
3/4 throughout
100 BPM rehearsal tempo
one-flat key signature (B-flat only)
exact score/MIDI duration = 90.000 s
Accepted literal instrumental extraction:
Violin I 207 events / 198 sounding
Violin II 200 events / 192 sounding
Viola I 169 events / 145 sounding
Viola II 170 events / 147 sounding
Continuo 189 events / 171 sounding
Pitch ranges:
Violin I/II F4..C6
Viola I C4..D5
Viola II G3..A4
Continuo D2..D4
There are zero instrumental ties in this movement, and every instrumental staff closes to exactly three quarter-note units in every bar.
22.2 Clef ownership requires both staff identity and current-system geometry
The final Movement-8 system shares a PDF page with the beginning of Movement 9. An early extraction accidentally associated a lower-system Movement-9 treble clef with the Movement-8 Continuo.
Canonical rule:
candidate clef must:
belong to the named staff
AND
lie within / immediately relevant to the current score system
Do not resolve ownership by horizontal position alone on a page containing more than one score system or movement.
22.3 Accepted direct reduction and same-family collapse
Movement 8 uses:
Violin I + Violin II
-> upper piano family
Viola I + Viola II
-> upper piano family
written Continuo
-> lower piano family
No harmony is invented.
Same-family exact simultaneous same-pitch spans collapse to one piano attack:
Violin spans before collapse: 390
duplicates removed: 67
Violin attacks after collapse:323
Viola spans before collapse: 292
duplicates removed: 9
Viola attacks after collapse: 283
Continuo attacks retained: 171
---
total piano note-ons: 777
Cross-family coincidences remain separate. Continuo coincidences remain separate. True repeated attacks remain attacks.
This rule represents one physical piano key and must not be confused with synthetic-vocal phase management. Vocal parts remain distinct performers even when their rendered waveforms need timing decorrelation.
22.4 Accepted musical master
Canonical MIDI:
dixit_mvt8_repetiteur_piano_v1.mid
SHA-256:
24f1bf0283d24c4813e5fa56aad756e23dd7f658754a0fb2d7eb066f62e09690
The accepted render uses the canonical chain:
fluidsynth -ni -g 0.6 \
/usr/share/sounds/sf2/FluidR3_GM.sf2 \
dixit_mvt8_repetiteur_piano_v1.mid \
-F dixit_mvt8_repetiteur_piano_v1.wav \
-r 44100
Final timing:
score/MIDI endpoint: 90.000 s
FluidR3/player endpoint: 92.704 s
renderer tail: 2.704 s
Final piano hidden calibration at visible 70%:
1.5852
Movement 8 piano v1 is FINAL.
22.5 Cross-layer rule established by Movement 8
Three superficially similar “doubling” problems now have different canonical solutions:
paired orchestral staves hit the same piano key
-> collapse within family in the reduction MIDI
two cloned synthetic vocal instances have phase-correlated waveforms
-> retain both written voices; decorrelate one with a fixed accepted
micro-timing realization in the canonical USTX
two vocal parts substantially double the same written line
-> retain both voices; use light passage attenuation where musically needed
Never solve one of these at the wrong layer.