Monday, February 21, 2022

Why I'm not porting Polymeter

Milkii Brewster on GitHub asks "Linux version? Plugin version? Possibly maybe in the future?" and here's my answer:

The Polymeter source currently consists of 47,100 lines of C++ code. Of that, 80% is UI. How do I know that? To facilitate automated testing, I created a command line version of Polymeter, which can open and play a .PLM (Polymeter) document, and optionally export it to a standard MIDI file. After all of the UI is eliminated, 9,447 lines of code remain, and if you were planning to port the project, that would be the right place to start. The UI code is so dependent on MFC (Microsoft Foundation Classes) that it would almost certainly be easier to throw it away and start from scratch.

The sequencer core also depends on MFC, though far less so: it only depends on CString and the CArray and CMap container classes. It’s on my to-do list to make a fork of the command line version that uses the standard C++ library only. That means creating wrappers that emulate the interfaces of CString, CArray, and CMap, and that’s a much bigger job than it sounds. You might think someone would have already done that work, and perhaps they have, but if so they didn’t advertise it very well.

Even supposing those wrappers already existed and worked reliably, my application still depends on the Windows API. In particular, the sequencer is designed around the MIDI Stream API. Equivalent APIs may exist in Linux or MacOS, but even seemingly small differences between those hypothetical APIs and the Windows API could present huge obstacles. I surmise that it’s possible, because my program works correctly under Wine. I’ve never studied the Wine MIDI Stream code, but I wouldn’t be surprised to learn that it’s messy. It’s solving a hard problem that involves multithreading and device drivers.

But these are just technical issues. I’ve done plenty of porting, for example during my professional career I ported software from Windows to embedded processors, so I have a good idea what’s involved. The real issue isn’t technical, it’s temporal. I’m old! I’ve been working on the modern (Windows) version of this project for three years already, and I started the original version in 1998 under MS-DOS. I probably don’t have enough time left in my life to learn UI programming for MacOS or Linux or WxWidgets or Qt, certainly not at the same level of expertise I already have with Windows and MFC.

I didn’t write a polymeter sequencer out of curiosity, I did so because I wanted to compose in complex polymeter. I had hoped to avoid spending so much time writing software. I tried many commercial products before undertaking the Windows version of Polymeter, but sadly none of them had significant support for complex polymeter, and certainly not for polymeter modulation, many types of which I have—as far as I know—invented. I prefer to spend my remaining years actually using my sequencer, which I’ve paid so dearly for, to compose novel and aesthetically pleasing music. Other than composing persuasive examples of complex polymeter, probably the best use of my time would be to write a paper about all this. That’s also on my to-do list.

But even if I had another life to lead, why would I spend it on porting when perfectly good solutions already exist? There’s no significant obstacle to you or anyone else running Polymeter. You could simply obtain a Windows computer. It needn’t be anything fancy. A used PC would set you back a few hundred bucks, surely insignificant compared to thousands of hours of development time. Or you could use PlayOnMac or Crossover or Wine itself to run Polymeter under Linux or MacOS. Sure there are a few issues running in Wine, but 99% of the program works fine. Or you could run a VM, or do dual boot. So in short, the answer is, are you volunteering to port the project? If so, great. Otherwise, it is what it is.

Heptatonic scales with a minor third

Which heptatonic scales consist entirely of semitones, whole tones, and a single minor third, without having two semitones in a row? The he...