Wednesday, January 30, 2019

Finding Graphviz

Polymeter 0.0.23 includes a graphing feature, powered by a nifty free visualization software called Graphviz. One of the biggest hurdles was inventing a robust method of finding Graphviz. The system path is unhelpful, because Graphviz doesn't add itself to the system path anymore, presumably because the attempt to do so was triggering antivirus software. Below is a flowchart of the steps Polymeter takes in its effort to find Graphviz. It's nontrivial but it works pretty well.

Polymeter 0.0.23 adds graphing capability

Polymeter 0.0.23 introduces graphing, to help you visualize your modulations. The heavy lifting of generating the graph is done by Graphviz, an excellent free software that's used in many projects including Doxygen. The scope of the graph can be one of these:

Scope Description
All Show all modulations regardless of track selection
Selected Show direct modulators of selected tracks
Recursive Show direct and indirect modulators of selected tracks
Bidirectional Show direct and indirect modulators and modulatees of selected tracks

 

Various graph layouts are supported, including dot(for heirarchical graphs) and neato (for relational graphs). The edges are colored to indicate modulation type, and edge labels can optionally be displayed. The graph is generated as vectors (SVG format) so it's zoomable, and can be exported for printing. Hovering over a node's label shows a tooltip containing the track number. The graph is displayed using a web browser control (IWebBrowser2). Note that the recommended Internet Explorer version is 11 or later (Edge); earlier versions of IE may display the graph incorrectly or not at all.

This version also features a MIDI input bar that lists MIDI input events with filtering options.

Polymeter 0.0.21 adds MIDI Output and Piano bars

Polymeter 0.0.21 adds two dynamic visualizations that can help you grasp what you're hearing: a MIDI output bar that shows the output MIDI events as text, with filtering options, and a piano bar that displays the output notes on a piano keyboard, also with filtering. Both of these visualizations were proposed in a previous post.

The main issue with implementing visualizations is a multithreaded design problem, which stems from the fact that the sequencer runs in a different thread from the rest of the application (the sequencer callback thread). In order to safely transfer data from one thread to another, serialization is required, but the goal is to minimize the likelihood of the sequencer callback thread ever being blocked by the user interface thread. The most appropriate and performant architecture for this situation is a buffer swapping scheme. In order to reduce time spent in the critical section to the absolute minimum, only pointers to the buffers are exchanged, rather than the buffers themselves. Fortunately the dynamic array class already supports swapping buffer pointers with another array instance. The result is the best of both worlds: zero-copy exchange between a pair of growable arrays.

This version also adds a command to reset the window layout to defaults. Thanks to Benoit Ruelle for suggesting this useful feature.

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