|
I've just completed ADR-0035 on remembered alterations: the system determining when accidentals print in music notation. The client's first window won't open for yet a few weeks, so there's no technical pressure for this work. But conceptually, it felt necessary. Pitch representation, time signatures, key signatures: all complete. Before proceeding to visualization, I needed to see these systems work together. I needed conceptual closure. The result surprised me. Not because it works (of course it works), but because of how naturally the pieces fit. The Actual ProblemAccidental rendering isn't 'print a sharp when the note differs from the key signature'. Accidentals have memory. Once F♯ appears in a measure, subsequent F notes remember that sharp until the barline. This memory flows left-to-right through musical time, independent of visual layout. The complexity emerges in multi-staff instruments. Piano, harp, organ, even choirs: all staves share accidental memory. A sharp in the treble affects naturals in the bass. Multiple voices complicate further; temporal sequence follows rhythmic position, not staff order or voice structure. You need a model where musical time is explicit and independent of how things appear on the page. This is precisely the problem that four separate architectural decisions, made for entirely different reasons, were built to solve. What Was Already There Pitch representation (ADR-0026): Letter names, octaves, accidental keywords. Built for memory efficiency and canonical identity. No thought given to accidental rendering at the time. Time signatures (ADR-0033): Metric positions as rationals (1/4, 3/8, 5/16) providing exact temporal coordinates for every event. Built to handle irrational and additive meters correctly. Again, no consideration of accidental logic. Key signatures (ADR-0034): Define which accidentals are 'normal' for a given context. Standard keys, keyless modes for keyless music, per-octave microtonal signatures for contemporary notation. Built as baseline, not as accidental memory. Timewalk (ADR-0014): Traverses music in strict temporal order. Built for efficient general-purpose traversal. The musical timeline made explicit as implementation detail. Four systems, four separate problems, no coordination between them. The Single Comparison RuleWith those foundations in place, remembered alterations became straightforward. The algorithm is a wave pattern flowing left to right:
Decision rule: A note requires a printed accidental when its accidental differs from the current remembered state for that letter and octave. That's it. This single rule handles both required accidentals (contradicting key signature) and courtesy accidentals (restating after alteration). No special cases. No heuristics. The data structure stores only deviations from baseline; eight entries typical versus seventy for full representation. Grace notes participate fully in the memory system. Tied notes bypass conditionally with position-based French tie distinction. Simultaneities detect conflicts where the same letter has different accidentals at the same moment. Cross-octave courtesy accidentals work through letter-first grouping that makes the lookup O(m) where m equals octaves for that letter, not O(k) for all octaves globally. All of this through the same mechanism. The complexity isn't in the algorithm; it's in having the right foundations. The Mental ShiftTimewalk changed how I think about notation problems. Instead of 'iterate over notes and check context', the remembered alterations pipeline is stream transformation: Each stage is pure transformation. Grace notes are repositioned to exact temporal locations based on tempo-dependent duration (85ms default, compressed on collision). Simultaneities group by rhythmic position. Conflicts detect same-letter different-accidentals at the same moment. The reducer threads remembered state through the stream, accumulating decisions. This pattern will handle dynamics, articulations, phrase marks: any notation requiring temporal context. The abstraction scales because the foundations were right to begin with. What This Actually RevealsThe algorithm produces semantic decisions about accidental requirements, independent of layout. These decisions are deterministic: same music, same decisions, always. They're layout-independent: work identically across all visual representations. They're configurable: house style settings modify behaviour without code changes. They're correct: edge cases handled through the same mechanism as common cases. But here's what matters: I didn't design these four systems to work together. I designed each to solve its own problem correctly. The alignment emerged because correct solutions in related domains tend to compose naturally. This is evidence. Either the domain model reflects musical reality accurately, or I've successfully imposed coherent structure on chaos. Those are different conclusions with different implications, but both suggest the foundations can carry what comes next. The Timing QuestionWhy now? Why remembered alterations before any visualisation exists?
Because I needed to know whether the foundations were actually complete. Pitch, rhythm, key signatures, temporal traversal: individually validated, but never tested as a system. Remembered alterations forced that test. If they didn't align naturally, I'd have learned something important about what was missing. They aligned. Beautifully. With no compromises in existing architecture, no special cases, no friction. Four systems built independently composed into a solution more elegant than any I'd planned. That's conceptual closure. That's knowing the foundations are right before proceeding to build on them. That's why this work happened now, before technical necessity demanded it. The next phases (windowing, rendering, note entry) will build on these same primitives. But now I know they're sound. Not because I believe they should be, but because I've seen them work together when they had no reason to unless the underlying model was correct. The window opens soon. But first, this needed to be right. Now I know that when notes appear on screen, there will be no special cases left to fix, no rules-of-thumb to implement. Accidentals are now correct regardless of staff, voice, cross-staff, or cross-measure situation or house rule preferences. Es ist alles eins, as Marie sings in Wozzeck. But in a good way.
5 Comments
Magnus Johansson
20/11/2025 13:55:37
Thanks, Peter, for this very interesting look into your programming workshop! To create something and discover that it became better than expected is truly fascinating. Now I look forward to the ADR on clefs.
Reply
20/11/2025 16:33:13
Glad you like it - it's one of those blog posts that might be difficult for non-programmers and non-musicians alike, since it sits right in the middle of both disciplines. I'm glad it was comprehensible despite that.
Reply
Malte
26/11/2025 07:35:18
Do I understand correctly that grace notes in Ooloi take real time from other notes? And that their duration in relation to other notes is tempo-dependent and hard-coded at 85ms? That doesn’t feel right to me. Please have a look at the following screen shot that shows how I’ve understood your description of grace notes.
Reply
Malte
26/11/2025 07:51:01
See also this screen shot for implications on cautionary accidentals:
Reply
27/11/2025 15:17:54
Great questions. You've identified exactly why grace notes are hard. Let me clarify:
Reply
Leave a Reply. |
AuthorPeter Bengtson – SearchArchives
December 2025
Categories
All
|
|
|
Ooloi is a modern, open-source desktop music notation software designed to produce professional-quality engraved scores, with responsive performance even for the largest, most complex scores. The core functionality includes inputting music notation, formatting scores and their parts, and printing them. Additional features can be added as plugins, allowing for a modular and customizable user experience.
Ooloi is currently under development. No release date has been announced.
|
RSS Feed