Hello everyone. I’ve been working on a dynamic chord library for my next harmonizer project. Harmonizer 01 had an obvious limitation of only allowing triads, so a flexible chord library capable of handling, not only midi note ranges, but also note names and chord degrees was needed to take my projects to the next level. MusicEngine is also being developed as a stand-alone project to serve as an independent tool, following a OOP paradigm.
I’m looking for feedback specifically on the class structure and overall architecture of my Music engine library. This is my first serious attempt at building a system using OOP in SuperCollider, so I’d like to know if my design choices make sense or if I’m misusing classes, initialization patterns, or data encapsulation.
About MusicEngine
MusicEngine doesn’t rely on an in internal table of MIDI offsets. Instead, it parses what I call a verbose syntax (e.g. "CM3P5m7M9"), and from this generates:
- Midi offsets
- note name and accidental offsets
- chord degrees
- ranges trimmed by octaves
There’s also an alias system that maps common chord symbols to their verbose equivalents, for example:
<root>9 = <root>M3P5m7M9
The dictionary of aliases is comprehensive, but, obviously, not all inclusive[1].
Creating and inspecting ranges
Ranges are generated as instances of MENoteRanges:
~range = MENoteRanges("Fm3P5M6")
From there we can obtain an array of MENotes objects:
~range.notes // [a MENotes, a MENotes, a MENotes, a MENotes, ...]
Since all note data is encapsulated inside each MENotes object. We can retrieve it by calling on its properties:
~range.notes[10].degree // Rt
~range.notes[10].midi // 53
~range.notes[10].freq // 174.6141157165
~range.notes[10].name // F3
Or by calling on MENoteRanges instance methods, to extract the data into arrays:
~range.degrees // [P5, M6, Rt, m3, P5, M6, Rt, m3, ...]
~range.midi // [24, 26, 29, 32, 36, 38, 41, 44, ...]
~range.freq // [32.703195662575, 36.708095989676, 43.653528929125, ...]
~range.names // [C1, D1, F1, Ab1, C2, D2, F2, Ab2, ...]
This is just a brief description of what it does and what its intent is. That said, I’d like to know if there’s anyone who’d be willing to review it and provide feedback and improvement ideas.
To those interested there are two files (inspectME.scd and inspecttools.scd), at the root of the repository, for the purpose of trying different symbols and inspecting the results. The project still needs systematic testing, but so far seems to be working as intended.
There are also two important additions I haven’t had the chance to implement yet:
- A register system where users may create registers of their custom symbols, paired with the respective verbose representation, and have that be stored in a file.
- See if it’s possible to, somehow, integrate the
Tuningclass intoMENoteRanges. I haven’t used that class and haven’t looked into that yet, so I have no idea if it’s possible.
That’s all for now.
I’d greatly appreciate any architectural or class-design feedback.
All the best to you all!
For reference see the wiki page Chord Symbols ↩︎