Mingus 0.7: classes and mixins
I've been working on a OO redesign of mingus which is slowly progressing into something usable (see the files in the mingus/ root on the mingus-oo branch). The new code is hopefully more user-friendly and easier to program, and gets rid off the disconnect between the procedural style of mingus.core and the clunky OO style of mingus.containers.
I started mingus as a side project whilst in uni to explore the algorithms behind music theory, which basically grew into mingus.core. A bit later on I wanted to hook the notes generated by mingus up into a midi synthesizer for which I ended up needing a bunch of container classes. The design that emerged has been a bit of a pain to maintain and work with ever since.
As an example: in core we can use a note to build intervals, chords and scales, but in containers we don't have that ability and we need to get the note name out first and then convert the result back into a relevant container. This could be remedied in the current code base, but the fact remains that there are two different representations for notes, and this is excluding the conversion to MIDI and LilyPond, etc. which complicate matters even further. So in short: there is a usability problem; we have duplication, complicated conversions, etc.
The new design sort of merges core and containers together and uses mixins to provide most of the behaviour. It also prefers immutable operations over mutable ones, which makes it easier to do procedural generation. The new design is not only cleaner but also makes it easy to implement some new features like the ability to build chords and progressions on top of arbitrary scales.
Unfortunately there's quite a bit to do before this can be released as a replacement for mingus 0.5:
- finish porting, refactoring and testing
- rewrite the documentation
- describe the upgrade process/provide backwards compatibility
I don't have a lot of time to spend on mingus these days, but this is the direction I want to take the project in. Feedback welcome.
The mingus library offers some very nice features in the area of music theory. The use of Python, however, has some problems. In the new OO version could you possibly fix some very troublesome things:
-
Operator overloading that violates the semantics of the operator. For example, the
Bar.__add__()method behaves like__iadd__()should, adding in place. The proper operator to do that is+=and the dunder method is__iadd__. If you are doing a major upgrade this is the time to root out this very unpythonic use of dunder methods. -
__str__and__repr__methods that go quite far to hide data about notes, especially the velocity. -
MIDI note_start events with zero velocity are to be interpreted as note_stop. The mingus code shows them as normal notes and also hides the velocity. This is extremely confusing and not really correct.
-
The tortured explanation around
Bar.set_meter()could be avoided by making meter a property with@propertydecorator. Then meter could be set like an attribute or with aset_meter()that forwards to the property method. Either usage would work properly.