OOLOI.ORG
Menu

OOLOI

An Organism Evolved.

OVERVIEW

DOCUMENTATION

NEWSLETTER

Music for Computer Scientists

10/1/2026

0 Comments

 
Picture
​A few weeks ago I wrote a post explaining computer science terminology to musicians. This is the inverse: an explanation of music notation for programmers who assume the domain is simpler than it is.

That assumption is common. It's also expensive. Most notation software has been written by very competent engineers who underestimated the problem. The result is systems that work impressively until they don't – at which point they fail in ways that seem arbitrary to users but are, in fact, architectural.

This post explains why.

Notation Is Not MIDI with Graphics

Picture
The most damaging assumption programmers bring to this domain is that music notation is a visual layer over time-stamped events. Work with audio software, game engines, or digital music for long enough, and this seems obvious: notes have start times, durations, and pitches. Notation just draws them nicely.

This is wrong in a way that corrupts everything downstream.

Consider two representations of identical duration:

  • (a) quarter note
  • (b) dotted eighth tied to sixteenth

These produce the same acoustic event. They do not mean the same thing. The first is a single rhythmic impulse sustained. The second implies a specific re-articulation point encoded in the notation itself. Performers read these differently. Conductors might even beat them differently. The semantic distinction is not ornamental.

MIDI cannot represent this distinction. It knows only NOTE_ON, NOTE_OFF, and duration. Notation systems built on MIDI-like assumptions inherit this blindness and spend their entire existence fighting it.

Music notation encodes musical meaning, not acoustic events. The implications of this single fact occupy the rest of this post.

Time Is Not Integers

Picture
Programmers reach instinctively for integer representation. MIDI uses ticks – typically 480 or 960 per quarter note. DAWs use samples. The assumption is that any temporal precision can be achieved by choosing a sufficiently small quantum.

This is false for music notation.

Consider a simple case: a quarter-note triplet against regular eighth notes. The triplet divides the beat into thirds; the eighths divide it into halves. To represent both exactly in a tick-based system, you need a tick count divisible by both 2 and 3. Fine: use 6 subdivisions.

Now add a quintuplet in another voice. You need divisibility by 2, 3, and 5: LCM = 30.

Now consider what real music does. Chopin writes nested tuplets. Ferneyhough writes 7:6 against 5:4 against 3:2. Elliott Carter writes simultaneous streams at different tempi. The required tick resolution grows combinatorially:

Picture
where di are tuplet denominators and k is your base resolution. For complex contemporary music, this can exceed 10^6 ticks per beat, at which point integer overflow becomes a real concern and accumulated floating-point error in tempo calculations produces audible drift.

The solution is obvious once stated: rational arithmetic. A quarter-note triplet is exactly 1/3 of a half note. No approximation. No accumulated error. The arithmetic is exact because the representation matches the domain.
​
  • triplet quarter = 1/3 × 1/2 = 1/6 of whole note
  • regular eighth  = 1/8 of whole note

These don't share a finite decimal expansion. They don't need to. Rationals are closed under the operations music requires.

Clojure provides this natively. Most notation software doesn't use it. The consequences appear everywhere timing matters – which in notation is everywhere

The Structure Is Not a Tree

Picture
Programmers expect hierarchical data. XML, JSON, ASTs, DOM trees – the mental model is that complex structures decompose into nested containers. Parent nodes own child nodes. Traversal is well-defined.

Music notation has multiple simultaneous hierarchies that do not nest cleanly.

A single note participates in:
  • Metric structure: beat → measure → section
  • Rhythmic grouping: tuplet → beam group → phrase
  • Pitch organisation: voice → chord → harmonic progression
  • Measure layout: measure → staff → instrument → system → page
  • Notational conventions: slur, dynamic hairpin, articulation group

These hierarchies intersect. They do not nest. Consider cross-staff notation: a chord where some notes appear on the treble staff and others on the bass. Which staff 'owns' the chord? Neither. Both. The question assumes a tree structure that doesn't exist.

Or consider voice exchange: soprano and alto swap pitches mid-phrase. The melodic line (a horizontal relationship) contradicts the voice assignment (a vertical relationship). Both are musically meaningful. Neither subsumes the other.

Grace notes exist precisely at the intersection of conflicting hierarchies. They have pitch (placing them in a voice) but steal time from adjacent notes (making their metric position contextual). They may or may not take accidentals from the main-note context. The rules vary by historical period.

Systems that force music into a single hierarchy spend enormous effort on edge cases that are only 'edge' cases because the data model is wrong.

Context Is Non-Local: The Accidental Problem

Picture
​Here is a concrete example of why music notation is harder than it looks.

Question: Does this F need a sharp sign?

Answer: It depends on:
  1. The key signature (established possibly pages earlier)
  2. What happened earlier in this measure in this voice
  3. What happened earlier in this measure in other voices on the same staff
  4. What happened earlier in this measure in other staves (in keyboard music, an F♯ in the left hand may affect an F in the right)
  5. Whether there's a tie from the previous measure
  6. Whether this is a grace note (different rules apply)
  7. Publisher conventions (some always mark cautionary accidentals, some don't)
  8. Historical period (18th-century conventions differ from 20th-century)

A naive algorithm checks each note against previous notes in the measure. This is O(n) per note, O(n^2) per measure. Fine for simple music.

Now add multiple voices. The F in the soprano might be affected by an F♯ in the alto, depending on conventions. You need to track alterations across voices. If voices cross staves (as in keyboard music), the interactions multiply.

Now add simultaneity. What happens when two voices sound the same pitch at the same instant but with different accidentals? Yet another edge case difficult to catch when imprisoned in the Jail of Recursive Descent.

Now add grace notes. A grace note at the beginning of a measure might be notated at the barline but sound at the end of the previous measure. Does its accidental affect the next measure? Does the next measure's key signature affect it?

The dependency graph for accidentals is not a simple sequence. It's a directed acyclic graph with edges determined by temporal position, voice membership, staff assignment, and notational category. Correct handling requires topological sorting with domain-specific edge semantics.

Most notation software handles this with heuristics: rules-of-thumb that cover common cases and fail on uncommon ones. The failures aren't bugs in the usual sense. They're consequences of architectural decisions made decades ago when the problem was less well understood.

Ooloi handles this through what I call the 'timewalker' – a transducer that processes musical events in semantic order (not storage order) allowing full temporal context accumulation. The accidental algorithm becomes stateless over its input stream: given the same sequence of musical facts, it produces the same decisions. Deterministically. Every time.

The complexity is still O(n · v) for n events and v voices, but the constant factor drops dramatically because traversal and processing are separated. The transducer handles navigation; the algorithm handles meaning.

Concurrency Is Not Optional

Picture
​Here is where most notation software fails silently.

A modern computer has multiple cores. Users expect responsiveness: type a note, see it appear immediately. But notation isn't like a word processor where inserting a character affects only nearby layout. Changing one note can alter accidentals throughout a measure, reflow an entire system, or invalidate cached engraving calculations across pages.

The traditional approach is to serialise everything. One thread handles all mutations. The UI blocks or queues. This is why notation software freezes when you paste a large passage, or why collaborative editing remains essentially unsolved in this domain.

The problem deepens when you consider what 'correct' means during an edit. If a user changes an F♮ to an F♯ in measure 4, the accidental state of measure 5 depends on this change. But if the rendering thread is currently drawing measure 5, what does it see? The old state? The new state? Some inconsistent mixture?

Mutable state with locks doesn't solve this; it creates a new category of bugs. Deadlocks. Race conditions. Heisenbugs that appear only under specific timing. A very difficult work environment indeed, and one where diminishing returns becomes a real impeding factor.

The functional approach is different. If musical data is immutable, the question dissolves. The rendering thread has a consistent snapshot – always. The editing thread produces a new snapshot. There's no moment of inconsistency because there's no mutation.

This is what Software Transactional Memory provides in Clojure. Transactions compose. Reads are always consistent. Writes are atomic. The system guarantees that no thread ever sees a half-updated score.

The performance implications are substantial. Ooloi's STM handles heavy contention without the coordination overhead that serialised systems pay constantly. The bottleneck shifts from synchronisation to actual work.

Real-time collaboration becomes architecturally possible. Two users editing the same passage don't corrupt each other's state; they produce alternative futures that the system can merge or present as conflicts. This isn't a feature bolted on afterwards. It's a consequence of representing music correctly from the start.

Engraving Is Constraint Satisfaction

Picture
Ravel being difficult
​Programmers sometimes assume that once you have the musical data, displaying it is straightforward. Calculate positions, draw glyphs, done.

This underestimates the problem by roughly an order of magnitude.

Consider accidental placement in a dense chord. Multiple accidentals must avoid colliding with each other, with noteheads, with stems, with ledger lines, and with accidentals in adjacent chords. The placement rules aren't arbitrary – they encode centuries of engraving practice optimised for readability.

This is a constraint satisfaction problem. In the general case, it's NP-hard. Real systems use heuristics, but the heuristics are subtle. Gould's Behind Bars – the standard reference on notation practice – devotes many pages to accidental stacking alone.

Now multiply by every other engraving decision: beam angles, stem lengths, tie curves, slur routing, dynamic placement, tuplet brackets, ottava lines, system breaks, page breaks. Each interacts with the others. Change a stem length and the beam angle needs adjustment; beam ends need to follow sit-straddle-hang rules and might both move. Change a beam angle and adjacent voices may collide.

LilyPond's engraving quality comes precisely from treating this as a serious optimisation problem. Its page-breaking algorithm runs a variant of the Knuth-Plass line-breaking algorithm (developed for TeX). Its spacing uses spring-based constraint systems. The 'simple' rendering layer contains some of the most sophisticated code in the system.

Interactive notation software faces an additional challenge: these calculations must be fast enough for real-time editing. You can't spend ten seconds optimising layout every time the user adds a note. The tension between quality and responsiveness has driven much of the architectural evolution in this field.

Historical Conventions Are Not Bugs

Picture
​A programmer encountering music notation for the first time will find countless apparent inconsistencies. Surely these could be rationalised?

No. Or rather: not without destroying information.

A fermata on a note means 'sustain this note'. A fermata on a barline means 'pause here'. A fermata on a rest means something slightly different again. These distinctions emerged from practice. Composers use them. Performers understand them. A system that normalises them into a single 'fermata event' loses musical meaning.

Grace notes in Bach are performed differently than grace notes in Chopin. The notation looks similar. The performance practice differs. A system that treats all grace notes identically will produce correct output that performers find misleading.

Clefs change meaning by context. A C-clef on the third line is an alto clef; on the fourth line, a tenor clef. Same symbol, different staff position, different meaning. This isn't legacy cruft – orchestral scores routinely use multiple C-clef positions because different instruments read different clefs.

Mensural notation (pre-1600) has entirely different rules. The same notehead shapes mean different things. Accidentals follow different conventions. Barlines serve different purposes. A truly comprehensive notation system must handle this or explicitly disclaim it.

The temptation to clean this up, to impose regularity, to treat historical conventions as technical debt – this temptation must be resisted. These conventions encode musical knowledge. Destroying them in the name of consistency destroys the knowledge.

The Performer Is the Point

Picture
​All of this serves a purpose that has nothing to do with computers.

Notation exists to communicate with humans. Specifically: performers who bring interpretation, physical constraints, and centuries of inherited practice to their reading.

This isn't sentimental. It has engineering consequences.

A page turn in the wrong place forces a pianist to stop playing or memorise a passage. This is a functional failure, not an aesthetic preference. The page-breaking algorithm must allow this to be modelled.

Awkward beam groupings obscure metric structure. The performer reads beats through beam patterns. Wrong beaming means wrong emphasis. The beaming algorithm must model this based on the currnent time signature.

Unclear voice leading forces performers to decode the texture before they can interpret it. The system must make voices visually distinct in ways that match musical distinctness.

Engraving choices that are mathematically equivalent may not be performatively equivalent. Two layouts might use the same space and avoid all collisions, but one reads naturally and the other requires active deciphering. The difference matters.

This is why notation is not a solved problem. The specification is 'communicate musical meaning to human performers'. That's not a format spec. It's a design constraint that touches every decision in the system.

Conclusion

Picture
Music notation looks like a data format problem. It is actually a meaning representation problem with a millennium of accumulated context.

The systems that fail – and most fail in some way – do so because they treat notation as something to be processed rather than something to be understood. They model the symbols without modelling what the symbols mean.

The systems that succeed take the domain seriously. They represent time exactly. They handle multiple hierarchies without forcing false containment. They process context correctly even when context is non-local. They treat engraving as a real problem, not a rendering detail. They preserve historical conventions because those conventions carry meaning.

This is why Ooloi's architecture looks the way it does. Rational arithmetic isn't ideology; it's the only way to represent tuplets exactly. Immutability isn't fashion; it's the only way to guarantee that accidental decisions are deterministic. Transducers aren't showing off; they're the cleanest and most efficient way to process a semantic stream with accumulated context. STM isn't over-engineering; it's the only way to achieve both correctness and responsiveness without sacrificing either.

The domain dictates the tools. Not the reverse.

0 Comments

And Only Then

9/1/2026

4 Comments

 
Picture
We have a new year, and it's time to make plans. Ooloi's architecture is now closed, and the work enters a new phase. What follows is a road map, not a schedule – no dates, no promises – but a logical progression.

These stages are different in nature from what has gone before. Conceptually simpler than the deep semantic work (what the music is, how it's represented and manipulated) or the infrastructure (server/client transports and roundtrips, monitoring, certificates). Everything below is comprehensively architectured and implementation-ready. The thinking is done; what remains is execution.

The Preparations

Event-Driven Client Architecture: The nervous system that lets the interface respond without freezing. (ADR-0022, ADR-0031)

Windowing System: Windows, menus, palettes, dialogs, notifications, connection status. The application becomes something you can see and touch. (ADR-0005, ADR-0038)

Multi-Mode Clients: Standalone operation, peer-to-peer connection, shared server connections. (ADR-0036)

Skija / GPU Rendering: The drawing substrate. GPU-accelerated graphics, paintlist caching, lazy fetching. The machinery for putting marks on screen. (ADR-0005, ADR-0038)

Hierarchical Rendering Pipeline: The transformation from musical structure to visual layout. (ADR-0028, ADR-0037)

Plugin System: First-class access from any JVM language. (ADR-0003, ADR-0028)

MusicXML: The first, limited version, implemented as a canonical plugin. Real scores entering the system. (ADR-0030)

And then – and only then – will the first staff line appear.
4 Comments

Six Degrees of Unification

6/1/2026

2 Comments

 
To implement what was described in the last blog post deterministically, ADR 0028, on the hierarchical rendering pipeline, and ADR 0037, about measure distribution, both have been updated. The rendering pipeline now has six stages rather than five.

The additional stage enables the behaviour discussed in the previous post, but also allows slurs, lyrics, dynamics, and other elements that require vertical space to adapt dynamically without introducing layout jitter.

What follows is a brief tour of the six pipeline stages. Each has a clearly defined role, a fixed direction of information flow, and no hidden feedback paths. Together, they transform musical structure into pages without iteration.

If you are a musician, you should be able to follow how the music moves from essential meaning to visual expression. If you are a developer, the architectural choices should be readable between the lines. In both cases, the ADRs contain the full technical detail.

Stage 1: Atoms

Each measure is processed independently and turned into engraving atoms: indivisible musical units that already contain noteheads, augmentation dots, accidentals, stems, articulations: everything that belongs together. A note or a chord is an atom, including everything at a fixed distance from that note or chord. Once an atom is computed, its constituent parts never move relative to each other, though they can be adjusted manually or converted by the user to pure graphics for Illustrator-like manipulation.
​
From these atoms, the system derives three facts about the measure stack: a minimum width, where atoms are simply lined up after one another (guaranteeing that nothing ever collides); an ideal width, based on proportional spacing from rhythmic density; and a gutter width – extra space required only if the measure begins a system. Courtesy accidentals caused by system breaks are accounted for here as space requirements, not as symbols. Ordinary courtesy accidentals are already part of the atom.

​Stage 2: Rhythmical Alignment

All measures in a stack contribute a rhythmic raster: the sequence of atom positions implied by their rhythmic content at ideal spacing. Stage 2 takes these per-staff rasters and aligns them into a single, stack-wide rhythmic grid, so that 'the beat structure' is shared across staves rather than each staff carrying its own local spacing. Because the system has both the rasters and the atom extents from Stage 1, it can adjust the aligned positions so that collisions are avoided while still preserving the intended proportional structure.

​Stage 3: System Formation

With rhythmical alignment complete, the score collapses to a one-dimensional sequence of measure stacks, each described only by stack minimum width, stack ideal width, and possible stack system-start gutter. System breaks are chosen using dynamic programming, and a scale factor is computed for each system so that ideal proportions are preserved as well as possible within the available width. At the same time, system preambles (clefs, key signatures) are fully determined. Apart from these, the stage produces only break decisions and scale factors; no measure content is positioned yet.

​Stage 4: Atom Positioning

The abstract decisions from system formation are applied. Each atom is positioned horizontally by scaling its ideal spacing according to the scale factor of its system. Because atoms were defined with purely relative internal geometry, they can be moved without recomputation. This stage is a pure projection from musical proportions to absolute coordinates.

​Stage 5: Spanners

All connecting elements are resolved against the fixed atom positions: ties, slurs, hairpins, ottavas, lyric extenders. They adapt to the horizontal geometry they are given and never influence spacing upstream. System-start decorations live here as well: courtesy accidentals now appear in the gutter space that was explicitly reserved earlier.

​Actual system heights emerge at this stage as a consequence of what must be drawn – slurs, ties, lyrics, pedalling indications, hairpins – each claiming vertical space as required to avoid collisions. In this stage, braces, brackets, and instrument name indications are also computed for the left margin, as all information required to determine system grouping and extent is now available.

​Stage 6: Page Formation

Systems are distributed across pages using dynamic programming, this time over the actual system heights produced by the previous stage. As in Stage 3, the distribution is optimal with respect to the available space. Once page breaks are chosen, layout is locked and no earlier stage is revisited. At this point, all rendering decisions have been made. The score can now be drawn directly from the cached paintlists.
2 Comments

System-Break Courtesy Accidentals

5/1/2026

0 Comments

 
Picture
Standard practice in many house styles is to show a courtesy accidental at the start of a new system when a tied note continues across a system break. In traditional notation workflows, this is handled manually: the engraver adds or forces the accidental after layout.

That manual step has consequences. A courtesy accidental has width. Adding it can push spacing past a threshold, move a system break, or reflow measures. A small local correction can trigger a cascade elsewhere, sending the engraver back to the same passage again. This is not a matter of care or skill. It is a side effect of heuristic layout combined with post-hoc correction.

Ooloi takes a different path.

Courtesy accidentals that exist because of a system or page break are derived, not edited. Ooloi has user settings to control preferred behaviour – such as whether these accidentals appear at all system breaks, page breaks only, or not at all. The required space is known before layout begins. System and page breaks are explicit decisions, and the distribution pass incorporates these accidentals exactly once.

Edit the score and the layout is recomputed.
Change a preference and the layout is recomputed.

There is no iterative correction loop, no heuristic adjustment, and no manual cleanup phase. Layout-dependent notation is a deterministic consequence of the score, its breaks, and the engraver’s stated preferences.

0 Comments

Arc

4/1/2026

0 Comments

 
Picture
I keep an internal development log. It's not public, partly because publishing it would create expectations about sequence and timing that I have no intention of meeting. But something happened to its structure recently.

For over a year, the log tracked numbered phases. Phase 1 through Phase 6, each with clear boundaries, some of them with sub-phases. The numbers implied I knew what came next.

After Phase 6, I was supposed to implement Phase 7 (event-driven client architecture) and Phase 8 (windowing system). Opening a window was 'weeks away'. That's what the plan said.

That's not what happened.

Something – veteran instinct, fifty years of pattern recognition too deep to articulate – said: complete the semantic layer first. Not the plan. Not what 'agile' methodology recommends. But the foundations needed to handle real musical complexity before anything was built on top of them.

So instead of windows, I implemented the full semantic layer. Time signatures, key signatures, remembered alterations – the systems that determine what accidentals print and when. The hard problems in notation software, the ones that have resisted clean solutions for forty years.

I've written about that work as it happened. What I hadn't written about, until now, is what it revealed about the plan itself.

​The development log no longer uses numbered phases for future work.

This isn't abandonment of structure. It's recognition that the work has entered a different mode. The section heading now reads 'Future Stages' with a note: 'Not numbered phases – sequencing may shift based on what the work reveals.'

That sentence took eighteen months to earn. The plan implied I knew the sequence. The reality is that the architecture now tells me what it needs. The foundations are proven; what follows is revelation, not construction. And I now need to listen.

​For eighteen months, the work was architectural: designing possibilities, extending the system, proving it could handle what I asked of it. That mode of thinking was adaptive. It built what now exists.

That mode of thinking is now dangerous.

The guardrail, however, is surprisingly simple. A single principle: if rendering something changes the semantics of what's being rendered, the logic is wrong. Not 'possibly wrong' or 'worth reconsidering'. Wrong as in 'don't go down that path; retrace your steps entirely'.

This sounds obvious, but it's deceptively easy to violate. The instinct to adjust, to consider alternatives, to make something 'look better' by feeding visual decisions back into musical ones – these reflexes served construction. They now threaten what's been built.

The architecture is now closed. It’s no longer fluid in any sense.​ Rendering reveals; it doesn't renegotiate. I may return to this topic, because the implications run deeper than they first appear.
0 Comments

Twice

31/12/2025

2 Comments

 
Picture
Two weeks ago, the remembered alterations algorithm proved that accidental rendering could be solved deterministically. I wrote about needing to breathe, to get my head around it.

Today, I formally specified measure distribution as ADR-0037. The Knuth-Plass algorithm – the same dynamic programming approach TeX uses for paragraph breaking – applies directly to distributing measures across systems. Not through cleverness, but because Ooloi's five-stage rendering pipeline decouples concerns that traditional architectures leave coupled. By the time the distribution algorithm runs, collision detection and vertical coordination are already resolved. What remains is a one-dimensional sequence with scalar preferences. Textbook problem. Textbook solution.

The algorithm itself is not news. Knuth-Plass has existed since 1981.

The news is that this is the second time.

Two problems the industry treats as inherently heuristic – requiring manual correction, special cases, user-facing options to tune approximations – collapsed into straightforward algorithms. Same architectural properties both times: immutable data, rational arithmetic, explicit stage boundaries, semantic determinism before layout.

Once might be coincidence. Twice suggests the architecture itself is doing something.

For engravers, if this holds: no accidental weirdness. No measure distribution cleanup. No jitter when editing – changing bar 47 won't mysteriously reflow bar 12. Layouts that are globally optimal, not locally adjusted. Proportional spacing preserved by construction. Adjustments for taste, not necessity.

I keep writing 'if this holds' because the proof is mathematical, not yet empirical. The algorithm is sound; the question is whether real scores – Gesualdo madrigals through Berg's Orchesterstücke or Ligeti's Requiem – expose edge cases the staged pipeline doesn't fully decouple. The remembered alterations work is tested. Measure distribution needs equivalent validation.

But the pattern emerging is harder to dismiss than any single result. If two 'impossible' problems turn out to be straightforwardly solvable, how many others?

I don't know yet. That's the honest answer.

Roland Gurt's comment last week – about spacing instability in the programs he uses, where editing one element mysteriously reflows unrelated staves on following pages – started me thinking seriously about this problem. Thanks, Roland.

Happy New Year, everyone.
2 Comments

Knuth-Plass

30/12/2025

0 Comments

 
Today I discovered that measure distribution over systems and pages, thanks to Ooloi’s architecture, can be solved deterministically using the Knuth-Plass algorithm. 

Wow.
Picture
0 Comments

Cross-Platform, Verified

25/12/2025

3 Comments

 
Picture
Just verified that the Ooloi development and application environment installs and runs on macOS, Windows, and Linux. All tests pass on all three platforms. This is exactly as unsurprising as it sounds when you're running on the JVM.

Expectation is not the same thing as verification. This check removes a class of future problems before they arise. There are no platform assumptions embedded in the codebase. If you can run a JVM, you can run Ooloi.
3 Comments

Computer Science for Musicians

21/12/2025

8 Comments

 
Picture
Roland Gurt, a musician and regular reader here, recently asked whether I could explain some of the computer science terminology that keeps appearing in these posts – terms like functional programming, immutability, and transducers – in layman's terms, and preferably from a musical point of view.

I was genuinely glad to be asked.

At this stage of Ooloi, nothing has yet been drawn on the screen. What has been happening is work on problems that sit underneath notation, problems that have been considered 'mostly solvable' at best since the 1980s. The deterministic accidental system I recently wrote about is one such problem. It looks abstract because it has to be. It deals with musical meaning before anything becomes visible.

This post is an attempt to explain why these terms keep appearing, and what they actually refer to, without turning this into a programming tutorial. It's written for musicians who are curious, not for programmers who already know the vocabulary.

Starting Without Baggage

​One reason Ooloi can attempt this at all is that it's a new system.

Most notation programs in use today have roots in techniques from the 1980s and 1990s. Internally, they tend to look surprisingly similar. They represent music in roughly the same way and rely on the same architectural assumptions: object-oriented design, mutable state, and large codebases written in C or C++.

Once a system has grown for decades on top of those assumptions, it becomes extraordinarily difficult to rethink its foundations without breaking everything at once. We saw Finale collapse in 2024 for precisely this reason.

There have been only two real departures from that lineage. One was Igor Engraver in the 1990s. The other was Dorico from 2016. Dorico has much in common with Igor Engraver in terms of musical data representation, and it made important advances. But even Dorico still rests on the technological assumptions of that era: object-oriented design, mutable state, and C++ at its core.

Ooloi puts all its money on a different assumption, namely that those older techniques fundamentally are architecturally inadequate for the problem of music notation as we now understand it. That inadequacy has consequences for users: accidentals behaving oddly, freezes and delays, limited scalability, no real collaboration, and poor use of modern multi-core machines.

​To address these problems, Ooloi uses an entirely different set of techniques.

A Genuinely Hard Problem Domain

Picture
​It also needs to be said very clearly that music notation, from a computer science perspective, is an extremely hard problem.

It's not 'a word processor for music'. That analogy has done lasting harm.

Music notation sits in the same general complexity class as compiler construction, symbolic mathematics systems, or advanced typesetting engines. It combines several difficult aspects at once: hierarchical structure, temporal meaning, long-range context, simultaneous layers, and a visual representation that's not a straightforward reflection of the underlying data.

A compiler reads a stream of symbols, builds meaning from context, enforces consistency rules, and produces deterministic output. Music notation does all of that, and then adds engraving conventions, historical practice, performer expectations, and visual clarity on top.

If you approach this domain with tools designed for relatively static documents or interactive graphics, you end up fighting the problem instead of modelling it. The result is systems that work impressively most of the time, but fail in edge cases, which in music aren't rare.

Determinism as the Musical North Star

Picture
​Before any technical terminology enters the picture, there's a simple musical requirement.

If you engrave the same piece twice, you should get the same result twice.

Not roughly the same. Not 'close enough'. The same.

Most notation software quietly gives up on this requirement. Instead, they rely on rules of thumb: 'this usually works', 'this is how engravers tend to want it', 'clean this up manually if it looks odd'. Musicians have learned to live with that because, for a long time, there was no alternative.

From a musical point of view, this is deeply unsatisfactory. It means the system doesn't really know what it's doing. When things get complicated, it starts guessing. And once guessing enters the picture, everything downstream becomes fragile.

Determinism simply means that given the same musical input, the system makes the same musical decisions every time.

Immutability: Trusting what has Already Happened

Picture
​Imagine packing a suitcase before a trip. You put clothes, toothpaste, shoes inside. Once the suitcase is closed and checked in, you make decisions based on what you packed. You don't buy extra clothes at the airport because you trust they're already there.

Now imagine that, while the suitcase is in transit, someone silently changes its contents. In a trivial case this is merely annoying. In a serious system – air-traffic control, medical records, nuclear command – it's catastrophic: people might die.

To reason about anything, you must be able to trust the past.

In computer science, immutability means this: once a thing has been created, it never changes. If you need a slightly different version, you don't alter the original. You create a new one. The old one remains exactly as it was.

This sounds wasteful until you realise that modern systems can do this efficiently by sharing structure internally. This is where a bit of Harry Potter magic comes in. If someone changes one shirt, they get a new suitcase with just that one shirt changed, while you still have your original suitcase, untouched and with the original shirt still inside.

In music notation this matters because the domain is full of remembered context. Accidentals depend on what happened earlier. Key signatures establish expectations. Voices interact. If earlier musical facts can silently change while later decisions depend on them, determinism collapses.

Functional Programming: same Input, same Result

​Most people already understand from school what a function is.
Picture
If x is 100, the result is always 101. Not sometimes. Always.

That property is determinism.

Now imagine that x is not a number but a suitcase. If the function's result depends on what is inside the suitcase, you must be absolutely certain that the contents haven't changed since last time. And for this, the suitcase needs to be one of our magical suitcases. Otherwise, calling the same function twice with what looks like 'the same input' might silently produce different results. The consequences range from a missing accidental to obliterating Tokyo.

Functional programming is simply the discipline of insisting on this property at scale. Functions don't reach out and change things behind your back. They don't depend on hidden mutable state. They take inputs and return results without any such surprises.

In Ooloi this matters because musical decisions must be reproducible. If accidental decisions or tie behaviour depend on invisible state changes, the system cannot be fully trusted, even if it usually looks right.

The Score as a Semantic Stream

Picture
A central idea in Ooloi is to treat the score as something that flows.

Music is read from left to right. Context accumulates. Decisions depend on what has already passed. Accidentals are remembered and later forgotten. Grace notes steal time from what they follow. Tuplets locally distort time.

This is not a static tree that you occasionally inspect. It's musical meaning - semantics - unfolding over time.

Once you accept that, you need a way to traverse this stream efficiently without constantly rebuilding lists or retracing paths.

​And this brings us to transducers.

 Transducers: Separating the Route from the Work (in the Jail of Recursive Descent)

Picture
​Imagine a high-security prison complex with multiple buildings, floors, and endless cells. Every day, a warden must traverse the entire structure to take stock of what's inside. And he must do it in the same order each day, just as the notes in a piece must be played in the same order each time.

Most of the warden's effort goes into navigation: remembering routes, tracking where he's been, writing lists just to keep his place. He does this over and over again, every day.

A transducer is like giving the warden Ariadne's thread. But again, there's magic involved: the thread weaves from cell to cell of its own accord. The route through the maze is fixed and reliable. Navigation stops being the problem. 

Better still, the warden doesn't even have to walk, thanks to more magic: the thread acts like a firehose and sends back all the information to the origin. The warden can sit in his office while the traversal happens and receive a continuous stream of information about what's found along the way. He can devote his entire attention to the meaning of the data, not how to walk the prison complex.

The crucial point is that traversal and processing are separated. The route is handled once. The real work happens as data flows past, without intermediate lists or repeated navigation.

In Ooloi, transducers allow musical meaning to be processed in exactly this way. The system doesn't build a large structure and then analyse it afterwards. It reacts to musical facts as they appear, deterministically and efficiently.

This is what a transducer is. Then there's even more wizardry involved in that several transducers can be stacked on each other to perform even more abstract operations. The path has been abstracted away, the distractions are gone, and the flow of  meaningful musical data is all that matters.

Vocabulary

​These terms aren't ideology, and they're not badges of virtue. They're simply the most precise language I've found for describing how musical meaning behaves when you try to handle it rigorously.

The music comes first. The vocabulary follows.
8 Comments

Breather

17/12/2025

5 Comments

 
Picture
If anyone wonders what the above is, it's the deterministic solution to a hairy engraving computer science problem nobody thought was solvable. It's been like that since the 80s. Everybody has just kind of capitulated and lived with a 'it's 95% okay, the rest is impossible' type of mindset and then, as one must in that situation, used rules-of-thumb to reach that 95%. Which is a lot, and a very respectable achievement.

However, it turned out that Functional Programming and immutability - and non-consing push transducers - could solve the problem deterministically. For the first time ever.

​I think it holds. We shall see.

What it would mean for notation? No accidentals weirdness. No cleanup. Consistency. Adjustments for taste, not necessity.

The power of Clojure, of treating the piece as a transforming semantic stream, and of not working with OOP and mutable state.

Now I need to sit down and breathe for a while. Time to go into Hammock Mode. I need to get my head around this.
5 Comments

The Eternal Return

5/12/2025

1 Comment

 
Picture
GX ligatures
​When I began coding Igor Engraver around 1995, the choice of platform was straightforward. Macs were where creativity lived. Windows – clumsy, unintuitive, user-hostile – was for accountants and management consultants. I needed to escape Finale's stranglehold, and I needed the best possible foundation for professional music engraving.

That foundation was QuickDraw GX.

Apple had released something genuinely remarkable: a complete 2D graphics and typography system with sophisticated font handling, Bézier curve operations, transformation matrices, and sub-pixel anti-aliased rendering. For music notation – which is essentially complex typography with thousands of precisely positioned curves – GX was perfect. Not adequate, not sufficient: perfect.

Igor Engraver was built on QuickDraw GX from the beginning. Mac-only, by choice and by necessity. Windows didn't matter. We founded NoteHeads, shipped the software, and believed we'd eventually need to address cross-platform support. But that was a distant concern.

Apple Pulls the Rug

Picture
Then Apple announced that Mac OS X would not include QuickDraw GX.

The technological bedrock simply disappeared. Everything Igor depended upon – the font handling, the curve rendering, the transformation system – would not exist in the next operating system. We weren't just facing a port; we needed to find something equivalent to GX's capabilities whilst making Igor work on both Mac and Windows.

In 1999 and 2000, that combination was extraordinarily rare. Most graphics libraries offered either good typography or good 2D graphics, rarely both. Cross-platform support usually meant compromising on quality. We needed the full GX feature set: anti-aliased Bézier curves, sophisticated font rendering, transformation matrices, professional typography. And we needed it to work identically on Mac and Windows.

I searched. Found something. Used it for the Windows port and the post-GX Mac version. And then, over the following decades, the name simply slipped away into that particular fog where technical details go when you've moved on to other problems.

Twenty-Five Years Later

In 2025, building Ooloi, I wanted to document Igor's history properly. But I couldn't remember the name of the library we'd used to replace QuickDraw GX. I could describe it – commercial, cross-platform, sophisticated 2D graphics, professional typography – but the name was gone.

So I did what one does in 2025: I asked Claude to search the web archives.

The answer came back: AlphaMask Graphics Library.

And then I read who had founded the company.

The Lineage Revealed

Picture
​AlphaMask Inc. was founded in 1999 by Mike Reed and Oliver Steele. Reed had been the tech lead on Apple's TrueType and font system. Steele had been on the QuickDraw GX development team and had led the Apple Dylan project at Apple Cambridge – the former Coral Software, where Macintosh Common Lisp originated.

The people who built QuickDraw GX had left Apple and founded a company to continue that work. When Apple made what I considered a profound mistake in abandoning GX for OS X, the GX team apparently agreed – to the point of leaving Apple entirely to focus on their superior graphics engine.

Whether I knew about Steele's Lisp background when we chose AlphaMask, I honestly cannot recall. I like to think the choice was purely on merit: AlphaMask offered GX-level capabilities in a more decoupled, portable form. It did what we needed. The fact that someone who understood both graphics and Lisp had designed the API might explain why it integrated so cleanly with our Lisp codebase, but that may simply be a pleasant historical detail rather than a decision factor.

Either way, when QuickDraw GX disappeared, I had unknowingly followed the people whose work I trusted.

The Pattern Continues

Picture
​Years later, when designing Ooloi, I chose Skia as the graphics foundation. Modern, open-source, GPU-accelerated, excellent typography, sophisticated path operations, cross-platform. I chose it on technical merit, comparing it against alternatives and finding it superior.

I had no idea that Skia was founded by Mike Reed and Cary Clark – another QuickDraw GX team member – a few years after AlphaMask. Or that Google had acquired Skia in 2005 and made it the graphics engine for Chrome, Android, and Flutter. Or that billions of devices now use Skia for their rendering. Or that the internal name at Apple for Quickdraw GX was - Skia.

QuickDraw GX has had three incarnations: first as itself, then as AlphaMask, then as Skia. The same design philosophy that made GX excellent – abstract graphics model, resolution independence, professional typography – survived through each transformation. I recognised that quality in 1995, in 2000, and in 2025, without realising I was choosing the same team's work each time.

Perhaps this indicates that certain kinds of graphical excellence are simply necessary for music notation, a constant need that has persisted since the last millennium. Or perhaps I'm simply stubborn enough to arrive at the same solutions regardless of how much time passes.

A Curious Timing

​Another detail emerged from the research. AlphaMask was acquired by OpenWave around 2001–2002, and the desktop product was discontinued. OpenWave wanted the technology for mobile browsers, not for professional graphics applications. Support ended, updates ceased.

2002 was also when NoteHeads fell silent.

Whether that timing was coincidental or causal, I cannot say with certainty. Finding a replacement for AlphaMask's capabilities in 2002 would have been extraordinarily difficult – arguably impossible. The engineering effort to rebuild on different foundations would have been substantial. Perhaps the ponytailed pop zombies running NoteHeads at that point gave up when the graphics engine disappeared. Perhaps they simply declined to invest in solving the problem. I don't know if we'll ever have a definitive answer, and frankly, the question is less interesting than the pattern it reveals.

What This Means for Ooloi

​The reassuring aspect of this circle is that it cannot break the same way again.

Skia powers the rendering in Chrome, Android, Flutter, and countless other applications. It has billions of users. It's open-source, BSD-licensed, maintained by Google and a broad community. Even if Google stopped development – which won't happen, as Android depends on it – the codebase is available, the expertise exists, and the user base is large enough that maintenance would continue.

Similarly, Ooloi runs on the JVM, which has multiple vendors: Oracle, Azul, Amazon, Microsoft, IBM, Red Hat, Eclipse. Battle-tested is a trite phrase, but it's accurate here. The JVM has been refined for nearly three decades across billions of deployments. It provides capabilities – proper concurrency models, cross-platform consistency, mature tooling – that enable much of Ooloi's architecture.

Everything Ooloi depends upon is either open-source with massive adoption or has redundant commercial vendors ensuring longevity. This isn't accidental. This is architectural design informed by what happens when foundations disappear.

The Unifying Thread

Looking back across thirty years, there appears to be a unifying pattern that I wasn't consciously aware of whilst making these decisions. A consistent need for graphical and typographical excellence. A recognition of quality when it appears, regardless of who built it or where it came from. A preference for sophisticated abstractions over quick implementations.

Perhaps I've learnt something during that time about building software that endures. Or perhaps I'm simply persistent enough to keep arriving at similar solutions when faced with similar problems. The distinction might not matter.

What matters is that the circle closes. The technology that made Igor Engraver possible in 1995 has evolved, through the hands of its original creators, into the technology that makes Ooloi possible in 2025. And this time, the foundations cannot be deprecated on a whim or acquired into oblivion.
1 Comment

The Belly of an Architect

5/12/2025

0 Comments

 
Picture
And my heart yearns baffled and blind, moved vainly toward thee, and moving  
As the refluent seaweed moves in the languid exuberant stream


— Algernon Charles Swinburne, 'Hesperia' (1866)
​Oh dear. Here's another quasi-philosophical blog post from the developer who still hasn't put anything on screen. You know the genre: intricate justifications for why invisible work matters, peppered with references to Victorian poets to make the whole enterprise seem less like procrastination and more like... what? Research? Vision? Architectural discipline?

I get it. A year and a half in, I want to see five lines and a treble clef. Instead, I get Swinburne and ruminations about streams. Fair enough. But something actually happened in the last few weeks that might explain why there's still nothing to look at — and more importantly, what that absence created space for.

After completing the backend infrastructure, I could have drawn the staff. Five lines, treble clef, a few notes on screen — visual feedback that would make the work feel real, tangible, moving forward. Every instinct pointed that direction. Show something. Prove it works. Keep momentum.

I chose accidentals instead.

The Architect's Hunch

​Why? Because after decades of building systems, you develop a sense for what needs to happen when. Not through conscious analysis, but through pattern recognition too deep to articulate. The commercial world calls this procrastination: 'Show something now. Validate with users. Iterate visibly'. But architectural intuition operates on different timescales. Sometimes the right move is to resist visibility until foundations are provably correct.

I felt compelled — and I mean that seriously, as in compelled — to solve accidental calculation before implementing rendering. Not for rational reasons I could enumerate in a planning document, but because something about the architecture whispered that accidentals would either validate everything or expose problems that couldn't be patched later.

Scary stuff, that. Betting 18 months of invisible work on a hunch.

​What Accidentals Actually Are

PictureThe usual suspects
​If you're not a musician, accidentals are the sharps, flats, and naturals that modify pitches within a measure. Simple enough in principle: once you write a sharp on a note, subsequent notes at that pitch remain sharp until cancelled or the measure ends.

​In practice, however, it's fiendishly complex.


Every notation program faces having to handle this complexity. Most handle it through special cases, heuristics, and lots of user-facing options for 'accidental behaviour in situation X'. The complexity emerges not from incompetent developers — the best commercial systems are built by brilliant people — but from architectural constraints where mutable state and rendering-first design make comprehensive solutions intractable.

I wanted to know if Ooloi's architecture could do better. Not through cleverness, but through correctness. If you find the word 'correctness' problematic, as in 'hyper-focused proto-Aspie obsession', bear with me for a paragraph or two so I can explain.

The Languid, Exuberant Stream

​Swinburne's metaphor turns out to be architecturally precise. The 'languid exuberant stream' operates on two dimensions simultaneously.

There's the mechanical dimension: Ooloi's timewalker is exuberant, powerful, a computational firehose processing enormous amounts of musical data. The machinery underneath is doing extraordinary work — coordinating temporal sequences, managing state across hierarchies, maintaining correctness through thousands of simultaneous operations.

And there's the conceptual dimension: languid, unhurried, effortless. When I actually write code, I'm asking simple questions: 'Does this note's accidental equal what we remember at this pitch and octave?' No wrestling with complexity, no thinking about coordination, no managing the machinery. Just natural musical questions that flow without effort.

The division is absolute. The architecture provides the exuberant power. I provide the languid purpose. They meet somewhere in the middle, and problems that should be hard simply... aren't.

The Great Contrast

​Commercial development forecloses this path. When visual pressure exists, you cannot separate these dimensions. You're forced to think about rendering whilst solving semantics, to optimise display whilst establishing correctness, to show something whilst building everything.

The result isn't wrong exactly — it's approximate. When architecture makes comprehensive solutions intractable, you end up with many options that tune approximations. The settings don't control behaviour; they compensate for architectural constraints.

This isn't criticism of commercial developers. They're working under pressure that makes this separation structurally impossible. Ship something. Show progress. Iterate based on user feedback. Entirely rational within commercial constraints; completely incompatible with certain architectural possibilities.

Working 'in the dark' created space for pure separation. The semantic foundation could reach mathematical correctness without visual compromise. When those dimensions finally unite, capabilities emerge that mixed approaches cannot achieve.

Not different in degree. Different in kind.

The Achievement

​The real achievement isn't solving accidentals. It's proving that separation of concerns works. That languid conceptual flow on exuberant mechanical power enables solutions that mixed approaches cannot reach. That working in the dark creates space for architectural correctness that commercial pressure forecloses.

The accidentals solution is evidence, but he architecture is the achievement.

The stream is languid and exuberant simultaneously. The mechanical power flows abundantly underneath. The conceptual purpose moves effortlessly above. They meet where music becomes mathematics and mathematics becomes music, and problems that should be hard turn out not to exist at all.

Because the architecture is right.

And now I can begin to trust it in earnest.
0 Comments

Re-Reading Read

2/12/2025

2 Comments

 
Picture
​I'm re-reading Gardner Read's Music Notation from 1974. I bought my copy in 1977, which makes me 16 at the time – old enough to take it seriously, young enough to believe comprehensive understanding was achievable through diligent study. Later, this book would influence Igor Engraver's formatting decisions, though not always in ways I'd care to defend today.

What strikes me now is what Read doesn't cover. There's nothing about ledger line thicknesses, actual distances in spaces between noteheads and accidentals, sit-straddle-hang rules, slur curvatures, or tie formatting. None of the engraver-level detail that Elaine Gould's Behind Bars (2011) and Ted Ross's The Art of Music Engraving & Processing (1970, but I didn't discover it until much later) document so comprehensively. Read gives you musical orthography – what symbols mean and when to use them – but not typographical execution.

What Igor Got Away With

​When Magnus Johansson published examples of Igor's output on NOTATIO recently, I experienced that particular species of discomfort that comes from seeing your 25-year-old work through 2025 eyes. The ledger line thicknesses were wrong. The beam slants were inconsistent. We clearly knew nothing about sit-straddle-hang.

So what made Igor well-received? Not typographical perfection, that's certain.

First, integrated parts. Only Composer's Mosaic had them at the time, and Igor had them long before Finale or Sibelius. This alone solved a workflow problem that cost professional copyists days of manual labour.

Second, the user experience didn't fight the music. After spending years with Finale on The Maids – full score, parts, piano reduction – I ended up hating Finale. I've called it 'as user-friendly as a cactus' more than once. Creating something that didn't actively work against the creative process was evidently a sufficient innovation.

Third, note entry was fast and powerful. The modal Flow Mode interface that would later vanish completely from notation software for 23 years gave professional users substantial note entry and editing speed improvements. When you're saving many hours per score, you'll forgive a few ledger lines being slightly too thin – and there was a setting for that anyway.

Fourth, we had stellar MIDI playback and a semantic model that made things consistent rather than a collection of rules-of-thumb. That alone provided predictability. And everything could be adjusted – the absence of automatic sit-straddle-hang rules just meant more manual interventions.

The landscape in 1996 made these trade-offs reasonable. The streamlined experience outweighed what we today immediately see was missing.

The Bar Has Been Raised

​2025 is not 1996.

The leading programs have improved considerably since 1996. They're genuinely competent at beam placement and formatting – not flawless, but competent enough that egregious errors are rare.

A new program entering this landscape must get the foundations correct from day one. Beam placement, slurs, ties, accidental positioning – these must be flawless, not 'good enough to ship'. The field has progressed, and users' baseline expectations have risen accordingly.

This is as it should be. But there's something deeper that hasn't been solved.

The Semantic Deficit

Here's what I've stated repeatedly: Ooloi is not about 'disruption' or market share. The entire motivation is to escape what commercialism leads to and create something modern, scalable, and architecturally correct from the ground up. Why? Because music notation is an extremely messy and difficult field of computation, and it requires correctness to address its long-standing problems of scalability and accuracy.

This starts with internal representation.

The old programs – and many modern ones still in broad use – were all based on a paradigm inherited from MIDI. MIDI was the standard for pitch representation at the time, and all notation software needed MIDI output for playback anyway. This meant pitches were MIDI numbers (0-127) with attachments indicating whether they were sharp or flat. Figuring out musical context – for instance, to determine what accidentals to draw – had to be derived from something with no connection to musical structure whatsoever. It had to be inferred from context each time.
​
That's at the root of the problems programs still have with accidentals. The internal representation is designed around the presentation – the visual aspect – not around the meaning, the semantics, of the music.

And of course, MIDI has no concept of microtonality, which is why notation programs struggle with microtonal entry, presentation, and playback.

Furthermore, for duration, these early programs based their rhythmic representation on a raster of 480 subdivisions – ticks – of a quarter note (TPQN: Ticks Per Quarter Note). A quarter note is 480 ticks long in some arbitrary tempo, an eighth is 240, and so forth. This is the equivalent of pixels in a JPEG, which means there's a limit to what the raster can represent.

The number 480 isn't evenly divisible by very many factors. This leads to all the problems we're still seeing in music notation programs. Various kinds of duct tape – rules of thumb, arbitrary rounding, tolerance spans – have to be used. When tuplets are nested, the approximation errors compound. We're still seeing the effects of this unfortunate MIDI heritage in 2025.

A MIDI-derived representation centred on presentation – the visual aspect – will always have difficulty interpreting what the music means. That interpretive layer is essential for presenting it correctly and consistently.

For that, you need a semantic model, which turns this on its head. The representation is 'musically correct' and detached from its presentation. Once this is in place, you can make informed decisions instead of relying on rounding and rules-of-thumb. It also makes things like playback trivial, which in MIDI-based systems is paradoxically complex.
​

Igor's Semantic Foundation

​Igor Engraver was, I believe, one of the first programs – possibly the very first – to use a fully semantic internal model. It was also the first to model the real world by using Musicians playing Instruments, which allowed new and powerful abstractions.

It's interesting that Dorico also has this arrangement, though they call their Musicians 'Players' – but it's the same thing. I have no idea whether Daniel Spreadbury was inspired by Igor here, but it's not unlikely. On the other hand, introducing Musicians/Players into the representational hierarchy is a logical choice once you commit to semantic modelling.

I'm not certain Dorico has a fully semantic model, though it's closer than any other program I know of. LilyPond doesn't, despite its sophisticated batch nature. One telling diagnostic: look at how they handle remembered accidentals for grace notes, and how they treat them rhythmically. Another: how durations are represented. If they're floating-point numbers, they're approximations. For true accuracy in all situations, you need rational numbers – infinite precision, always correct. Anything else eventually leads to problems.

If a program has problems with edge cases or behaves inconsistently when dragging things cross-staff, check how it represents pitch and duration. If floating-point is involved, or rasters of ticks (480 or otherwise), the representation isn't semantic. The program might still handle 95% of hairy accidental placements competently. But when it starts having problems with tied notes across key changes or grace notes at measure starts, you know rules-of-thumb are involved – which means results can never be fully deterministic.

Ooloi is fully semantic with the explicit intention of making results fully deterministic.

This might not matter if you're satisfied with what capable commercial programs achieve today. That's legitimate – they handle about 95% of cases well. But if you depend on the remaining 5%, or if you spend your days as an engraver adjusting those 5% repeatedly, then you understand what I mean by deterministic results saving considerable time.

This Time: No Compromises

Now, on to Gould and Ross – books that weren't available when Igor was created. We'd inevitably have implemented their specifications had we had time. But as you know, I was ousted from my own company by venture capital pop zombies before we could. They thought guitar tablature was more important than correct engraver-level beaming.

This time, there will be no guitar tablature at the expense of correct beaming and orthography. All things in their proper order. Lead sheets are kid's stuff, comparatively speaking, and will be added later as plugins.
2 Comments

When Four Systems Align

20/11/2025

5 Comments

 
Picture
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 Problem

Accidental 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 Rule

With those foundations in place, remembered alterations became straightforward. The algorithm is a wave pattern flowing left to right:
  1. Start of measure: Initialize to key signature baseline
  2. Process each note: Compare against current remembered state
  3. Update after each note: This accidental becomes new remembered state  
  4. Measure boundary: Reset to baseline

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.
Picture

The Mental Shift

Timewalk changed how I think about notation problems. Instead of 'iterate over notes and check context', the remembered alterations pipeline is stream transformation:
Picture
​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 Reveals

​The 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 Question

​Why 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.
Picture
5 Comments

Key Signatures

11/11/2025

2 Comments

 
Picture
Key Signatures in Ooloi have been specified and implemented, and as a result we have a new Architectural Design Record, ADR-0034, on the Key Signature Architecture.

Standard Key Signatures

​​It covers standard key signatures – the usual and expected: major, minor and modal in all keys:
Picture
Picture
Picture
Key signatures with double flats or sharps are also supported:
Picture

Ich fühle Luft von anderem Planeten

​Ooloi also supports keyless signatures, custom key signatures mixing flats and sharps, as well as microtonal key signatures.
Picture
Picture
Picture
Ooloi also handles key signatures where accidentals differ between octaves (for those moments when you feel your beard turning blue).

Playback

All this works with playback, of course, and even the microtonal key signatures handle cautionary accidentals between voices and measures as expected, according to the engraving principle of 'remembered alterations'.

A note on the ADR: It's not the UI

The ADR shows the internal architecture - what the software does behind the scenes. Users enter key signatures through standard dialogs: 'Eb major', 'D Dorian', etc. The technical infrastructure matters because it's what enables all those custom and microtonal features to work seamlessly alongside standard notation.
2 Comments

Half Measures

8/11/2025

8 Comments

 
Picture
Fractional numerators are now official. Ooloi’s time-signature system (ADR-0033) supports everything from common time to irrational and additive meters, and now fractional counts like “2½ / 4”. Halves only, for now – enough to cover Grainger and Chávez without venturing into Boulezian fantasy.
​
Full ADR: ADR-0033-Time-Signature-Architecture
Picture
Henri Dutilleux: Choral et variations
8 Comments

Vertigo: On Spirals, Obsession, and Architectural Identity

7/11/2025

0 Comments

 
Picture
Alfred Hitchcock's Vertigo opens with spirals. They appear in the credits, in Carlotta's hair, in the cross-section of the redwood, in the geometry of the bell tower staircase. Spirals aren't circles; they're recursive ascents, passing the same point at different heights. Each loop looks familiar yet transformed.

In the film's second half, Scottie Ferguson attempts the impossible: reconstructing a lost woman. He obsesses over every detail – the hair, the suit, the mannerisms – trying to make Judy become Madeleine. The reconstruction is meticulous, desperate, ultimately doomed. Madeleine was never real. She was always performance, designed to deceive.

I've been obsessed with this film for decades. Vertigo asks the question I cannot stop asking: what constitutes identity across time? Can something be reconstructed, or does reconstruction merely create elaborate performance? When does architectural continuity become delusion?

Twenty-five years ago, I built notation software called Igor Engraver. Then the world moved on, and the code became archaeologically interesting but technologically obsolete. Common Lisp running on pre-OS X Macintosh, rendering via QuickDraw GX, single-threaded on single-core CPUs. Now I'm rebuilding it as Ooloi – new language, new rendering engine, new concurrency model, new architecture.

So I have to ask: am I just Scottie in Vertigo? Reconstructing a past that never really existed?
Picture

The Fundamental Difference

​Madeleine never existed. Igor Engraver did.

Scottie reconstructs a performance designed to deceive him. I'm reconstructing software that worked perfectly well with the technology it had. Igor Engraver didn't die from technical inadequacy. It died from narcissistic neglect by guys with ponytails who couldn't see past their own reflections.

The architecture was sound. QuickDraw GX handled what we asked of it. Common Lisp did exactly what we needed. The software worked. What failed was human commitment, not technical capability.

Ooloi takes the same architectural vision and asks: what becomes possible when you're free of narcissistic partners and have access to genuinely better tools? The answer: not survival, but fulfilment of what was always possible.

​For, which is important: unlike Scottie, I'm not reconstructing the same woman. That's another significant difference. Igor's strengths lay in its ease of use and its user interface (and its playback, but that's another matter). Ooloi must go much further than Igor ever did in terms of typographical beauty, and it must do so from the first release.

​Herrmann's Transformed Tristan

Picture
​Bernard Herrmann's score for Vertigo doesn't just accompany the psychological state; it induces it. Those falling, spiralling arpeggios. Obsessive motifs that keep returning. Chromatic harmonies that never resolve. Lush orchestration that simultaneously feels unstable.

The music is Wagner's Tristan und Isolde transformed – the same chromatic restlessness, the same endless longing, the same refusal to resolve. Wagner created music about impossible love that could never find harmonic rest. Herrmann took that DNA and made it cinematic, made it about obsession itself rather than the object of obsession.

Years ago I quoted four measures from Herrmann's Vertigo in my opera The Maids – using his music about false love to underscore Genet's performed identities. Servants performing their mistress, performing revolution, performing each other. Identity as pure theatrical construction with no stable referent.

The circularity is almost too perfect: the composer of Vertigo scoring the film about vertigo, whose music I once quoted to mark falseness, now frames my own question – whether I'm caught in the same spiral of reconstruction.

But notation software can prove itself. Ooloi either handles Strauss's Elektra without freezing or it doesn't. It either supports real-time collaboration or it doesn't. Unlike Scottie's obsession, mine has to compile.

​What Constitutes Identity?

​This has always been the question. Vertigo asks it. The Maids asks it. Every recursive project asks it.

Is Judy really Judy if she becomes Madeleine? Was Madeleine ever real? Does performed identity become real identity through sufficient commitment? Is Ooloi Igor Engraver, or am I performing the identity of my younger self while building something entirely new?

Most programmers rebuild things pragmatically – new requirements, new tools, new project. But I'm asking whether I'm still the same architect when the materials have completely changed. Whether continuity of vision across technological discontinuity constitutes identity or elaborate self-deception.

The technical choices answer the question.

I preserved the idea: architectural vision, musical semantics, core abstractions, the fundamental insight that notation software requires deeper engineering than the industry has provided. But I let the implementation transform completely: Clojure instead of Common Lisp, STM instead of locks, GPU rendering instead of QuickDraw, immutable data structures, client/server architecture.

That's what genuine identity actually is: essential persistence through necessary transformation.
Picture

The Ooloi Metaphor Becomes Literal ​​

​Octavia Butler's ooloi are alien beings who perform genetic transformation – taking DNA from incompatible species and making them compatible. They preserve what's essential while enabling survival in new environments. They don't fake compatibility; they genuinely reconstruct at the genetic level.

That's what I'm doing with software architecture. The DNA persists: core musical semantics, hierarchical design, fluid user interface that doesn't get in the way. Add to that massive parallelism, a pervasive plugin philosophy, and the realisation that collaborative capabilities are a by-product of the architecture itself. The organism transforms to survive in 2025: different language, different rendering, different concurrency model.

The Ooloi name wasn't whimsy. It was recognition that genuine transformation requires going deeper than surface reconstruction.

​The Spiral Ascends

​Scottie's spiral destroyed him because the object was always false. The reconstruction was doomed because there was nothing real to reconstruct.

My spiral can succeed because the architecture was always sound; what failed was human commitment, not technical possibility. Igor Engraver died from neglect, not inadequacy. The guys with ponytails moved on. I did too,  from the circumstances. But not from the subject.

Twenty-five years later, the obstacles aren't technological maturity – they're human. I can build this alone, without partners whose narcissism exceeds their commitment. I can use tools that are genuinely better (Skia, STM, cloud architecture) without needing them to justify the project's existence.

The obsession is real. The vertigo is real – that uncanny feeling when you realise what was abandoned can be completed. The psychological pattern is acknowledged. But where Scottie's reconstruction existed purely in romantic space with no objective validation, mine has material proof: code that compiles, tests that pass, collaborative editing that actually works, Strauss's Elektra rendering in real time.

Identity is architectural continuity, through material transformation and human liberation. Not performance. Not even evolution. Completion.

The spiral passes the same point, but at a different height. This time, without the ponytails and the pop zombies.
Picture
​Vertigo remains my favourite film. I understand Scottie's obsession. I recognise the danger. But I also know the difference between reconstructing what was never real and finishing what should never have been abandoned.

The partners are gone. So are the commercial pressures. The new architecture holds. Herrmann's spiral ends in unresolved ascent – motion without final cadence. Ooloi's must too.
0 Comments

As Time Signatures Go By

3/11/2025

9 Comments

 
Picture
You must remember this
a bis is just a bis
a sign is just a sign
The fundamental things apply
as time signatures go by

​Time signature support in Ooloi, from common to esoteric.

Plain Vanilla

Ooloi of course supports the usual:
Picture
... and in 'the usual' I include things like time signatures spanning multiple staves in scores for readability purposes, etc. You know, what you'd expect from a modern, professional program.

Intuitive Entry

​Specifying a time signature is simple: you just write your signature as a string in the input dialog: "4/4", "C", "2/2", etc. As you will see, this paradigm holds for very complex or unusual meters, too.

Additive Meters

Additive meters are of course also supported:
Picture
which simply is entered as "3+2+3/8".
Picture
which is entered as "2+2+2+3/8". You get the idea.

​You can do things like this too:
Picture
This would be input as "1/4+1/4+3/8+1/4". Use whitespace for clarity if you like: ​"1/4 + 1/4 + 3/8 + 1/4".

​You can combine this with multiple terms:
Picture
... which simply is entered as "3+2/8 + 6/16".

Orff, Fortuna!

Carl Orff invented a notation showing beat duration as a note symbol rather than a number. It's occasionally useful, so Ooloi supports it:
or
They are entered as "3/8" and "2/4.", respectively (don't miss the full stop at the end of the second string). There's a checkbox to trigger this type of formatting – but as the second example contains a dotted value, Ooloi will detect the latter case automatically.

Fractional Meters

Boulez, Ferneyhough, Finnissy et al. Yes, Ooloi will support fractional meters such as 4/3 or 4/5. I personally would never use them, but then it's not up to me to pass judgement on what I think is musical over-engineering. That's what conservatories are for.

​Consequently, Ooloi supports the following:
Picture
9 Comments

The Lineage: When Ledger Lines Shorten

27/10/2025

2 Comments

 
Picture
Today, preparing the drawing system, I returned to LilyPond’s essay on engraving. Within a few paragraphs I realised: we come from exactly the same place.

The moment my spine tingled was when they described the shortened ledger line beside an accidental – that precise, almost invisible kindness that makes a score feel right before you know why. The line yields a little, the principle remains. That gesture is the mark of true engraving.

Martin Spreadbury studied LilyPond when he built Dorico. I’m convinced Martin Keary did too, though we didn't talk about it when I had him on the line some time ago. LilyPond is the gold standard – the Holy Grail of digital engraving with a soul.

The Masters We Serve

​Bärenreiter, Durand, Peters, Schott, Universal Edition. Publishers whose engravers spent ten years learning how to disappear behind their craft.

The copper-plate aesthetic: bold, confident, generous. Staff lines weighty enough to guide the eye, noteheads round enough to feel sung, stems drawn with conviction.

Modern digital engraving forgot this. It grew thin, bloodless — optimised for screens instead of for musicians.

The Musician’s Eye

As a performer, I react to good engraving before I’ve even played a note. My hands and eyes recognise the rhythm of care – the breathing room between notes, the balance of white space, the subtle confidence of proportion.

A well-engraved page feels alive: it draws the body toward the instrument. The pulse is visible before sound begins. That is what the old masters knew, and what the best modern systems are all trying to recapture in their own ways.

Good engraving isn’t decoration. Not by any means. It’s the first phrase of the music itself.

The Recognition

The lineage is clear, and the standard unchanging: those 1920s scores, those shortened ledger lines, that unspoken discipline that still knows how to sing.

We all worship at that shrine.
Picture
2 Comments

Where's the Music?

26/10/2025

0 Comments

 
Picture
I've noticed people on various web forums asking when they'll see Ooloi render notation. Fair question.

Not yet. Foundation work comes first: the stuff that makes it possible to draw music efficiently. When the rendering implementation begins, the blog will shift from infrastructure to musical decisions: how things sit, straddle, and hang.

Why this approach? This is open-source software built for decades of durability. It's not a commercial product racing as fast as possible to market. No competitors to 'eliminate', no users to 'capture'. Just correct foundations before visible output. Come back in a year or so: the conversation will be about music by then.

What 'correct' means: Nested tuplets to arbitrary depth with exact arithmetic, for instance. No ticks, no fudging, no approximations. The kind of precision that takes time to build right. And tuplets are just one small example.

Single-user first. Ooloi is designed for one person working on one score. Collaboration features are a byproduct of the architecture, not the main focus. The distributed design is about clean separation of concerns and deployment flexibility: collaboration just happens to work because the architecture supports it.

Do I care if people understandably say 'I'll believe it when I see it'? No. 

The work continues.
0 Comments

Ooloi Flow Mode Revelations

20/10/2025

7 Comments

 
Research for Ooloi’s input system turned up something I hadn’t expected. Igor Engraver’s Flow Mode – the modal, stateful keyboard entry that defined its way of working – has never been recreated. Not by Dorico, not by Sibelius, not by Finale, nor by any of the open-source projects. Twenty-three years on, the idea has simply vanished.

Flow Mode was straightforward. You pressed “.” once and staccato stayed active; crescendos extended naturally as you continued writing. The commands mapped directly to the symbols – intuitive, fast, and oddly satisfying. When Igor died of business failure in 2001, the method died with it. There is no academic record, no terminology, no sign that anyone even remembered it existed. I had fully expected other programs to have copied this feature; it gives a five- to ten-fold increase in music-entry speed.

Web forums on notation are full of people asking for faster, more fluent keyboard entry, yet without the vocabulary to describe what they want. They are looking for something they have never seen.

So this part of Ooloi isn’t innovation; it’s recovery. The system worked. It was lost for reasons that had nothing to do with design. The decision to re-implement it, and the details, are now recorded in ADR-0032: Ooloi Flow Mode.
​
What remains is to implement it – and to find Magnus Johansson, who just might still have the user manual.
Picture
Notate all this without ever leaving Flow Mode
7 Comments

Nun denn, allein!

16/10/2025

0 Comments

 
Picture
'Well then, alone!' – Elektra's cry when Chrysothemis refuses to help her. Not triumphant independence, but desperate necessity fused with unwavering resolve. The isolation isn't chosen; it's forced by the impossibility of finding anyone who shares her singular purpose. Orestes isn't likely to materialise.

There was a functional programming conference in Stockholm recently. I'm sure it was excellent. I didn't attend. I should probably have been there – Ooloi is built in Clojure, after all, and finding collaborators would be useful – but I felt conflicted, and that conflict revealed something I'd been avoiding: the FP community cannot help me, and I don't need it anyway.

​Sect Dynamics

​I'm disappointed with the functional programming community. I was expecting higher-level thinking – freer thinking, commensurate with the intellectual freedom Clojure itself offers – but the atmosphere proved to be a shallow puddle of sectarianism​. That probably has its reasons – being marginalised as a community is probably one of them – but the end result remains unchanged.

The patterns are unmistakable. Knowledge as gatekeeping: the endless monad tutorial phenomenon, where every advocate believes they can explain monads better than everyone else, typically through increasingly baroque metaphors involving burritos, space suits, or elephants. This isn't pedagogy; it's ritual initiation. The complexity serves a social function – maintaining boundaries between insiders and outsiders.

Purity as virtue signalling: debates about whether using `IO` makes you impure, whether exceptions violate functional principles, whether mutation in bounded contexts is acceptable. These discussions frame technical trade-offs as moral categories, as though architectural design were a moral discipline rather than an engineering one. The language reveals it – clean, pure, disciplined versus dirty, impure, undisciplined. This is religious vocabulary applied to software engineering.

Terminology as tribal marker: deliberate retention of academic terminology when simpler terms exist. Endofunctor, catamorphism, anamorphism when 'map over containers', 'fold', 'unfold' would suffice. The obscurity is the point – it establishes hierarchy and demonstrates membership.

The emphasis falls on mathematical elegance rather than problem-solving. The question isn't Does this help ship software but Is this theoretically sound. People who can recite monad laws but have never shipped a product receive more status than developers applying functional patterns to solve actual problems.

Then there's the missionary behaviour: the conviction that imperative programmers need conversion. The framework isn't Here's another useful tool but You're doing it wrong until you see the light. This creates antagonism rather than adoption.

Being marginalised as a community probably explains some of this – defensive posture manifesting as increased boundary enforcement, which creates insider/outsider distinctions, which enables status hierarchies based on doctrinal purity. But understanding the cause doesn't change the result, and it doesn't make the behaviour intellectually rigorous or practically useful.

The Clojure Exception

Clojure largely escaped this because Rich Hickey explicitly rejected purity culture. 'It's acceptable to use Java libraries'. 'Mutability in bounded contexts is fine'. 'Solve problems first'. The Clojure community focused on what you can build, not on arcane knowledge as status marker. This produced broader adoption without compromising functional principles.

This is why I chose Clojure for Ooloi in the first place. But even within that pragmatic oasis, the broader FP community dynamics leak through. The conference I didn't attend would have featured both kinds of people – those interested in building things and those interested in doctrinal purity – and I couldn't predict which would predominate.

The Intersection Problem

​Here's the substantive issue: finding Ooloi collaborators in FP communities is statistically improbable because very few people occupy my intersection point between various disciplines.

Music notation requires an understanding of compositional structure, engraving conventions, and how musicians actually work. Functional architecture requires a sophisticated understanding of immutability, higher-order functions, transducers, STM transactions, and compositional patterns. Backend infrastructure requires a willingness to work on unglamorous problems like endpoint resolution and temporal traversal rather than visible features, and in Ooloi's case, an understanding of server technology and secure cloud operations.

The population at that intersection is approximately one.

FP communities might yield people who appreciate my transducer implementations or STM transaction handling. But they won't understand why endpoint resolution for slurs matters, how temporal traversal serves musical structure, or what makes intelligent engraving different from geometric placement. The domain expertise is orthogonal to FP community concentration.

The inverse holds equally: musicians who understand notation deeply rarely have the architectural sophistication to work on Ooloi's core, and even fewer would find satisfaction in building infrastructure rather than using tools.

I've worked outside the FP community all my life. Functional programming is a tool, not a (monadic) religion. (And why are monadic and nomadic so similar?) Why join the community now, when the benefits are unclear and the costs palpable?

Consilium Latinum

​The technical response is what I call the Latin strategy: making Ooloi's core a stable foundation for a plugin ecosystem. Build the architectural core once in Clojure, then let developers in other JVM languages contribute via plugins without needing to understand the underlying functional implementation. I've written about this approach in Penitenziagite!, so I won't rehearse it here.

Elektra or Quixote?

Picture
The psychological question is whether this makes me Elektra or Don Quixote.

Elektra confronts a real murder, real injustice, a legitimate need for action that others refuse. The isolation comes from their cowardice or pragmatism, not from her misunderstanding of reality. The task is achievable and gets completed. The tragedy is the psychological cost, not the validity of the purpose.

Quixote confronts imaginary problems with obsolete ideals, mistaking windmills for giants. The isolation comes from a fundamental disconnect with reality. The task is impossible because it's based on delusion. The comedy (later tragedy) is that the quest itself is meaningless.

The distinction depends on whether the problem is real. Do musicians actually need what Ooloi provides? If existing notation software genuinely fails at problems Ooloi solves, then Elektra. If musicians are adequately served by current tools, if the architectural sophistication I'm building doesn't translate to problems they actually experience, then Quixote.

But there's a third option beyond tragic obsession and delusional quest. I'm building something architecturally excellent because I can, because it interests me, because functional approaches to musical structure are intellectually satisfying. The architecture might be elegant, but it's not worth psychological dissolution.

The Latin model suggests I've already chosen this third path. I'm building core infrastructure well, documenting it properly, then making it available via plugin architecture that assumes others might have different needs. That's craft separated from identity.

Not Dancing to Death

Elektra's tragedy is total consumption by purpose. She becomes nothing but the task, and when it completes, there's nothing left because she permitted no existence beyond vengeance. She dances herself to death.

I'm certainly not doing that. Ooloi is a project, not my entire existence. Sustainable completion means finishing the backend, documenting it clearly, releasing it, and then moving on. The work stands independently; I remain separate from it.

I'll finish Ooloi's core architecture working alone, not because I prefer isolation, but because collaboration at this intersection point is impractical. The resolve comes from accepting reality rather than pretending community exists where it doesn't.

The backend is complete. The transducer-based timewalker is fast, tight, and efficient. Endpoint resolution handles slurs and ties correctly. Nearly nineteen thousand tests pass. Vector Path Descriptors enable elegant client-server communication.

Then comes plugin architecture, and seeing whether anyone finds Ooloi useful. If they do, excellent. If they don't, I built something architecturally sound and learned what I needed to learn.

Either way, the work speaks for itself. And I continue existing beyond it.

Nun denn, allein!
Picture
0 Comments

ADR-0031: Frontend Event-Driven Architecture

15/10/2025

2 Comments

 
Picture
Every notation program eventually reaches the same constraint: the interface and the layout engine compete for control of time. When they do, the system freezes.

ADR-0031 defines how Ooloi avoids that conflict. Local actions such as editing, scrolling, and selection remain inside the JavaFX event system, which responds instantly. Network events, like collaborative edits or layout changes, are handled separately, through a dedicated Event Router that never blocks the interface.

For engravers, this means something simple but long overdue: editing and scrolling stay smooth, no matter how large or complex the score, and no matter who else is working on it.

The document doesn’t describe a finished feature; it describes the foundation that makes such responsiveness possible. From this point on, Ooloi’s design rests on a single rule: the interface must never wait for the network, and the network must never interrupt the interface.

Full text → ADR-0031: Frontend Event-Driven Architecture
2 Comments

Poetic Licence

10/10/2025

0 Comments

 
Picture
Last week's discussion on VI-Control turned into an unintentional seminar on what 'open source' actually means.

Nando Florestan, a composer and developer learning Clojure, read through the draft licence with unusual care and pointed out something I hadn't thought through properly: the anti-rebranding clause made Ooloi proprietary in practice. Forks would have been impossible without my permission. The OSI definition is clear: that's not open source, regardless of intent.

He was right.

The clause came from experience, not malice. Igor Engraver derailed out of my control, and I didn't want that repeated. But open source is a matter of definition, not sentiment. Trademark protects the name 'Ooloi'. Anything beyond that belongs to the commons.

The fix was simple: remove the modification. Pure MPL 2.0, no amendments. Register the trademark properly. Add a clear policy statement confirming that plugins and applications built using Ooloi's APIs aren't derivative works.

Better to discover it before release than after. The conversation forced me to confront what open source actually means for this project: giving up control while retaining integrity.

Why MPL 2.0

The Mozilla Public Licence sits exactly where Ooloi belongs: halfway between the ideological asceticism of GPL and the cheerful anarchy of MIT. File-level copyleft keeps the core collaborative while leaving everything built upon it entirely free.

Reciprocity without coercion.

If someone improves Ooloi's STM transaction coordinator or gRPC layer, those improvements remain in the commons. If someone builds a sophisticated playback system or commercial notation front-end atop Ooloi, they own it completely. That's how platform infrastructure should work.

The 'for the avoidance of doubt' clarification states what's already true: plugins, extensions, and applications using Ooloi's APIs aren't derivative works. This matters because commercial developers won't participate if they need solicitors to interpret 'Larger Work' provisions. The clarification prevents that friction.

The Alternatives Fail

GPL would poison the plugin ecosystem. The FSF's position on plugins-as-derivatives creates legal ambiguity that kills commercial participation. No professional algorithm vendors, no sophisticated commercial tools, no ecosystem.

Apache/MIT/BSD permits enclosure. Someone could fork Ooloi's core into proprietary software, capturing improvements that should remain shared. For infrastructure intended as commons, permissive licences are actually less free.

AGPL extends copyleft to network usage, which would criminalise legitimate commercial deployments: publishers running collaborative servers, institutions hosting multi-user environments, enterprises managing internal infrastructure.

LGPL adds complex compliance requirements without benefits. MPL 2.0's file-level copyleft provides cleaner separation.

The WordPress Parallel

The economics mirror WordPress's evolution. Core CMS functionality became commoditised infrastructure. Commercial value migrated to themes, plugins, hosting, services. Companies like Automattic built substantial businesses while the core improved collaboratively through thousands of contributors.

Ooloi follows similar logic. What legacy notation systems monetise becomes architectural givens:
  • Multiple musician collaboration: natural consequence of STM transactions
  • Large ensemble support: linear performance scaling  
  • High-quality printing: Skija's cross-platform rendering
  • Plugin extensibility: safe operations on immutable data

Commercial opportunities shift to where genuine value exists: sophisticated interfaces, professional algorithms, premium workflows, enterprise services. The core handles infrastructure. The plugins handle musical domain knowledge.

The Ultimate Irony

Under MPL 2.0, a product such as Järvenpää Silence Notator 2.0 (purely hypothetical, right?) could theoretically build atop Ooloi while maintaining proprietary differentiation through proprietary plugins and interface. The core infrastructure they'd no longer need to maintain. The competitive advantages they'd demonstrate through superior musical intelligence.

Whether this happens is irrelevant. The goal is proving that functional programming solves long-standing problems, enabling possibilities previously impractical: real-time collaboration without subscription lock-in, parallel processing without performance collapse, plugin extensibility without architectural fragility.

The licence ensures improvements flow back to the commons while permitting commercial innovation.

Practical Implications

For developers evaluating Ooloi:

Building plugins: Licence them however you want. Sell them, give them away, open-source them. No GPL contamination, no AGPL network copyleft. MPL 2.0 applies to Ooloi, not to your work.

Modifying Ooloi's core: File-level copyleft applies. Modified files must remain MPL 2.0. You can still build proprietary applications using modified Ooloi. Just release your modifications to Ooloi's source files.

Commercial deployment: Run SaaS services, embed in proprietary applications, charge what you like. MPL 2.0 requires nothing from you unless you modify core files.

On Integrity

Picture
Licensing isn't a legal appendix to the codebase; it's part of the architecture. A distributed system defines its boundaries through protocols. A licence does the same, only in law instead of syntax.

Open source isn't marketing; it's a contract of trust. You keep the code open not because you must, but because integrity demands it. You protect the name not to hoard it, but to prevent confusion.

Ooloi's licence now mirrors its architecture: clear boundaries, open interfaces, and a shared foundation for whatever might be built next.

0 Comments

A Wagner-Sized Benchmark

8/10/2025

1 Comment

 
Picture
When we last measured Ooloi’s storage engine, 50,000 musical objects occupied 14.5 KB – about 0.3 bytes per note. That already hinted at something unusual. The new benchmarks confirm it.

A 1,000-measure orchestral score for 3333 / 4331 + piano + divisi strings was used as the test case – the kind of piece length found in the largest late-Romantic works: Wagner’s Götterdämmerung, Strauss’s Elektra, or Mahler’s Eighth Symphony.

For non-musicians, 3333 / 4331 means three flutes, three oboes, three clarinets, three bassoons; four horns, three trumpets, three trombones, one tuba; plus piano and strings divided into multiple independent parts. In total: 29 staves, over 520 000 pitches, and thousands of simultaneous events – a scale that has historically defeated notation programs.

So the orchestra is medium-sized romantic, but the length and amount of music is extreme: everyone is playing fast notes from start to finish. The benchmark is designed to test a heavy score. Bring on the worst case, so to speak.

File Size and Persistence

Saving this complete piece took 1.3 seconds; loading it, 3.3 seconds. The resulting file was 172 KB – smaller than a single page of PDF. The piece does not yet include graphical information (layout, coordinates, glyphs), which would roughly double the size or more, but at these levels it makes no practical difference. Even if it becomes ten times larger, it's still of no consequence. The numbers are that good.

Streaming export (MIDI or MusicXML) completed in 1.25 seconds, using under 10 MB of memory. Even full materialisation of every internal element peaked at 244 MB, far below what such scores normally require.

Traversal and Computation

​Behind those figures lies the traversal engine that makes them possible. The full 520 000-pitch traversal completed in 0.58 seconds – roughly one million pitches per second. Cache repairs and dependency updates finished in 1–5 ms. Endpoint searches (for ties and slurs) are blazingly fast too, obviating the need for direct pointers.

For comparison, a score of this magnitude would have strained the limits of any existing notation program. Finale or Sibelius might take tens of seconds – sometimes minutes – to perform an equivalent operation. Ooloi completes the same structural pass between heartbeats.

What the Numbers Mean

What makes this possible is not optimisation trickery but architecture: immutable musical data, transducer-based traversal, and disciplined cache coherence across every layer. The system streams; it does not churn.

​For composers and engravers, these results suggest something once thought impossible – that even a full Wagnerian tutti might one day update instantly after an edit. Everything so far indicates that this should be achievable, not through hardware brute force but through architectural clarity.

For developers, the message is the same: a purely functional, streaming model can handle orchestral-scale data in constant memory, with sub-millisecond locality.

As far as I know, this is the first time a professional notation system has demonstrated real-time traversal of a Wagner-scale score with constant memory and sub-second exports. The invisible foundation – the hard part – is finished.

​All tests were run on a 2017 MacBook Pro with a 2.2 GHz six-core Intel i7 processor and 16 GB of RAM. A modern 2025 laptop or workstation would almost certainly halve every number reported here, and perhaps more. What feels instantaneous today will, in a few years, be beyond perception.

​Full benchmark results here.

Still on track towards that goal of smooth scrolling through the Elektra recognition scene.
1 Comment
<<Previous

    Author

    Peter Bengtson –
    Cloud architect, Clojure advocate, concert organist, opera composer. Craft over commodity. Still windsurfing through parentheses.

    Search

    Archives

    January 2026
    December 2025
    November 2025
    October 2025
    September 2025
    August 2025
    July 2025
    June 2025
    April 2025
    March 2025
    September 2024
    August 2024
    July 2024

    Categories

    All
    Accidentals
    Alfred Korzybski
    Architecture
    Benchmarks
    Clojure
    CLOS
    Common Lisp
    DDD
    Death Of Igor Engraver
    Documentation
    Donald E Knuth
    Dorico
    Dynamic Programming
    Finale
    FrankenScore
    Franz Kafka
    Functional Programming
    Generative AI
    GPL V2
    GRPC
    Igor Engraver
    Jacques Derrida
    JVM
    License
    LilyPond
    Lisp
    MIDI
    MuseScore
    MusicXML
    Ooloi
    Ortography
    Pitches
    Plugins
    Python
    QuickDraw GX
    Rendering
    Rhythm
    Rich Hickey
    Road Map
    Scheme
    Semiotics
    Sibelius
    Site
    Skia
    Sponsorship
    UI
    Umberto Eco
    Vertigo
    VST/AU
    Wednesday Addams

    RSS Feed

Home
​Overview
Documentation
About
Contact
Newsletter
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.​


  • Home
  • Overview
    • Background and History
    • Project Goals
    • Introduction for Musicians
    • Introduction for Programmers
    • Introduction for Anti-Capitalists
    • Technical Comparison
  • Documentation
  • About
  • Contact
  • Home
  • Overview
    • Background and History
    • Project Goals
    • Introduction for Musicians
    • Introduction for Programmers
    • Introduction for Anti-Capitalists
    • Technical Comparison
  • Documentation
  • About
  • Contact