Musical Nuance Language

random trip report

NOTE: Since writing this, I've implemented many of these ideas in a Python library called Numula.


Listen carefully to Arthur Rubinstein playing a Chopin Mazurka. You'll notice that no two beats have exactly the same duration, and no two notes have exactly the same volume. The performance has "nuance" - complex variations in timing, dynamics, and articulation. This nuance is not represented in the score. If we played the score exactly as written, it would sound banal, like video game music. The beauty and emotional expression is largely in the nuance.

I have, for a long time, been interested in how to express nuance in computer-based systems for editing and playing music. This arises, in large part, from my desire to use computers to create virtual performances of classical piano music that I'm unable to play physically.

One approach is to integrate nuance with the score itself. I have some ideas about how this might be done. But it's a big project - it would involve major changes to score-editing software like MuseScore. I'm not sure I have the energy to do this, or the ability to get other people to do it. And in the end it might not work very well.

While on my bike today, I thought of a simpler approach: separate the nuance from the score. Apply nuance as a post-processing step, in Unix pipeline style. Express the nuance in a language designed just for that purpose (and not for score representation). I call this Musical Nuance Language (MNL). MNL would let you say things like:

  • Make the 2nd beat of each measure 10% longer.
  • Make the top and bottom notes of a chord 50% louder than the others.
  • Accelerate linearly by 30% from measures 4 to 8.

I call these "nuance primitives". The ones listed above are probably too simplistic; e.g. a good accelerando might not be linear. I assume there's a lot of research on the nuance used by real musicians, and we could use this research to define a good set of primitives.

Primitives might be defined in terms of time periods (e.g. a crescendo over 4 beats) or sequences of notes (e.g. the 2nd and 5th notes in a sequence are emphasized). Primitives may apply to all the notes during a particular period, or to a subset, e.g. to particular single voice. There are lots of details to work out.

To describe nuance compactly you need programming language features: e.g. to do something a certain number of times, or to define a function that takes parameters. So I propose that MNL be based on Python, which is a great language in general and has features that will be useful for MNL. So:

  • An MNL program is a Python program that invokes "nuance primitive" functions, and indicates where they should be applied in a score.
  • The input to an MNL program is a score. The logical choice of format is MusicXML, which can be generated by most score editors (MuseScore, Finale, Sibelius). One requirement: we need to be able to "tag" subsets of the score (e.g. voices) so that MNL can refer to them. I believe that MuseScore lets you do this; if not, it would be easy to add.
  • The output of an MNL program is a note list, with the precise timing and dynamics of each note. The logical file format is MIDI.

Trivial MNL programs could apply to any score: e.g. a crescendo from start to end. But in general MNL programs will work only with specific scores.

Anyway, that's the basic idea. I don't think it would be that hard to implement; I could do the basic framework in a few months, and then other people could flesh it out.

As described here, MNL is purely textual. You have to type in numbers for nuance parameters. This isn't ideal; when you're working with music it's better to have a nice GUI. This would be a version 2 thing.

Copyright 2024 © David P. Anderson