[Stk] Some thoughts about aligning the STK still more with its stated architectural goals

Richard Henninger richard at rghmusic.com
Mon Aug 29 14:31:52 PDT 2016


                I love the compactness and simple elegance of the STK that derives from the sound architectural principles that have guided its development.  Its design and implementation has made it rather easy for me to adapt its code to a restrictive environment (a MS Hololens via the Unity (thus Mono) game engine) which is quite distant from the original unix-like execution environment originally assumed by its creators.

                While succeeding in getting my proof of concept working, I did have to modify my copy of the STK to resolve minor issues which had impeded my adaptation. Several of these were due the STK's current implementation’s falling short of its goal of being platform agnostic. The 4.5.1 implementation is so close, but its not quite there.

                I am sharing some observations about supporting still better platform independence as a discussion here on the STK list-serve rather than by writing them up as issues on github, but I would be happy to do that and even make pull requests should that be wanted.

                Anyway, here is what I wished had been there when I started:

                1) Error Communication: Warnings (via Stk) are hard-coded to the "cerr" stream (I can get errors via exceptions).  Platforms like game engines and mobile apps have no console. I know that I can hijack "stderr" into my own stream, but having Stk simply send errors to an "ostream" which could be supplied by a host program at initialization (but defaulting to "cerr" if not) for later retrieval would be a better level of abstraction and less kludgey than having to capture "cerr".

                2) File I/O: Skini parsing and sound sample reading (I didn't look at writing, rtmidi, rtaudio or sockets since I don't use these) assume free access to the file system by hard coding c-style FILE (FileRead) or c++ "ifstream" (Skini) at the lowest level.  In a sandboxed environment, this is hard (though awkwardly possible) to support.  A better level of abstraction would again be to rely on "istream" and have methods to initialize that with either an "ifstream" or a text/binary "istringstream" for in-memory data provided by a host like a game engine. Since hosts often may have already reduced sound files to floating point arrays anyway, maybe a method for accepting these would also be handy.

                3) Calculation quality: Compiling works great for "StkFloat" as "double", but dry-rot has settled in for "StkFloat" as "float".  Since Hololens is tight on memory, has a 32-bit processor and modest sound fidelity (spatialized mono), I tried shrinking my footprint and timings by using "float".  The cascade of errors and warnings, some of which probably matter such as for complex expressions in filters, made me drop back to double. The math of this needs review before "float" can be a serious option again.

                4) Polymorphic "tick"ing: The "Instrmnt" interface defines pure virtual functions for tick(…), but "Generator", "Effect" and "Filter" do not. All of their subclasses implement these.  When running these by proxy from a non-C++ host, I would have benefitted from "tick"ing these polymorphically like I can with "Instrmnt".  I get that introducing a vtable has a mini-performance hit that might start to matter in a tight inner loop.  Still, the STK is supposed to err on the side of clarity and usability as opposed to tight efficiency, right?

                5) Code organization: In the spirit of having already isolated midi (RTMIDI) and audio (RTAUDIO), I'd like to suggest also isolating the remaining real-time parts of the STK into a separate directory as well: especially anything needing threading since you can't control threads in some hosted environments.  I dealt with this by custom-setting my -d's to thwart real-time code and by omitting the classes dealing with real-time and file writing from my codebase altogether.  Wouldn't it be better to delineate real/non-real more clearly by directories and to add real-time capability only when needed rather than to have to subtract so many files manually from a single big directory?

                6) "Modern C++": As a fan of C++/11-17, I wouldn't mind seeing some of C++/11 features, at least, start to creep into the code.  Still, hats off to how well much of the STK avoids many of the pitfalls (especially with memory management) that "modern C++" is designed to facilitate avoiding.  Anyway, I believe all major compilers have complete C++/11 support by now, so why not?

                These are just observations I had as I ported the STK into an environment quite distant from its unix heritage.  It is a tribute to the STK's designers that this was a fairly trivial exercise.  I am already in good shape for my purposes.  I only offer these observations for discussion in the spirit of nudging the STK closer to its architectural goals by freeing it from the few remaining platform-specific idioms still in its codebase left over from its console/unix roots.  Even as it is, though, it has a pretty awesome design.

Richard Henninger
2712 Pembsly Dr
Vienna, VA 22181
USA

-------------- next part --------------
An HTML attachment was scrubbed...
URL: <https://cm-mail.stanford.edu/pipermail/stk/attachments/20160829/8feeade9/attachment.html>


More information about the Stk mailing list