Cheers Corky! The pandemic took me away from live performance for quite a while, and my focus moved onto other things (not least because I work in the world of biotechnology). But now that things are starting to open up again, I’m excited to be back in the thick of it again! Had my first rehearsal with my band in 20 months this last weekend. Loving being back in the world of Cantabile, and from the look of recent developments it’s a great time to be back!!
Wondering…could the anticipated .NET 5 performance improvements help with things like load when running plugins? And time switching between songs? Or are these most likely UI performance improvements?
I was wondering that myself. It looks really cool. Glad you are back in the saddle again. I lost a good portion of my chops, but slowly getting them back. Feels good to bounce off bandmates instead of a backing track. Love my improvisation moments.
Cantabile’s audio engine is entirely written in C++ so the .NET improvements won’t directly help there, although updating to the latest C++ compiler and tool chain may help a little. Most audio engine load though is due to plugins and nothing I can do about that.
The .NET performance improvements will mostly affect UI performance, perhaps song load time (all the Cantabile’s song/setlist serialization is done in C#) and some bindings. Bindings are a mixed bag - most midi to midi bindings are processed directly in the audio engine, but many bindings work through the UI thread (C#) so they could get a bump.
Cantabile’s UI composition, rendering and layout recalculations is the busiest part of Cantabile’s C# code base so that’s where I expect to see biggest improvement and I think that will manifest as things just feeling snappier and more responsive.
That’s actually pretty typical for most apps. Text rendering is a fairly expensive operation - if you think about it, every character is a vector outline that needs to be scaled, rasterized and probably alpha blended around the edges.
Although scrolling is an notoriously CPU intensive operation, the good news is that this usually isn’t an issue:
The redraws during scrolling can be coalesced - in other words if the CPU is busy with other more important stuff the scrolling repaints will batched and you’ll get jittery scrolling, rather than the nice smooth scrolling when there’s CPU available
Unless all cores on your CPU are totally saturated there’s usually enough CPU around to handle an paint redraw.
All scrolling and redrawing in Cantabile is done on a UI thread running at normal priority while the audio threads are running at time critical - so UI updates should never interfere with audio.
All that said, I’ll take a look at scrolling performance with this new update and check it’s not being ridiculous. (Noted it on this trello card)
I hope I haven’t given the wrong idea here. This shouldn’t be something you need to worry about. My point was more that it’s normal to see cpu load during scrolling and it’s usually ok. Unless you’re seeing CPU spikes that are bad enough to interfere with audio processing I wouldn’t worry about it. Of course if it’s really bad it’s probably something I should take a look at, in which case send me a repro example and I’ll check it out.
Last night, I thought I’d knock together a little VS Code extension to do syntax highlighting for “GTL” - the language used for authoring Cantabile themes.
Also, some slight improvements over the old column headers. Firstly, they now highlight when hovered over which will be used in places where click to sort might be added:
Also improvements to the cursor when a column is resized down to nothing. When on the left of the divider it shows the regular resize cursor and will resize “Column 1”
According to my todo list I’m now past half way… which feels about right although big changes like this usually involve a nasty unexpected road block which I haven’t come across yet. (hrm… suspiciously eyes the wiring diagram view)
Leaving it at that for today on Cantabile. I’ve got some ideas for the theming language that I’ll be wanting in the next couple of days so I’m off to tackle that.
I am constantly amazed at the dedication that Brad puts into this. When I talk to musicians using (insert other software name here,) I get these astonished looks. “My software doesn’t do that!” And then there is the community of support. Just an incredible product all the way around.
Last night I made some more improvements to the theming language:
Added support for tuples and implicit tuple conversions. I don’t think this is needed in Cantabile, but will be used in Mitch’s game for supplying vector coordinates for map meta data in a concise format, eg:
coords = [(10,20), (30, 40)] etc…
Added support for scoped theme class names. This will be used to allow common elements (buttons, labels, sliders) to be themed differently in different contexts. For example, GuiKit has a slider control but it’s very flat and square like the rest of the GuiKit controls. When it’s used in Cantabile’s main window I’d prefer keep the more rounded off style. Scopes should make this easier:
scope CantabileStyle
{
class Slider
{
// Attributes from outer Slider class will be inherited automatically,
// but customizations specific to "CantabileStyle" can go here.
}
}
To clarify a little about the GuiKit vs Cantabile styles. Here’s a Cantabile style slider
Here’s GuiKit style slider (mainly the slider handle is different shape)
I’m not sure how, or if, or whether I want to reconcile these styling differences yet but this new scope feature in gtl will be part of it one way or the other.
I’ve got more ideas for the theming language, but that can wait until tonight. For now it’s back to Cantabile.
Static methods work too, like Color.Blend and Color.Interpolate:
SomeControl:
{
// Blend transparent blue over dark red
BorderColor: Color.Blend(Color.DarkRed, Color.Blue.WithAlpha(0.5));
// The color 1/3 the way from Orange to Green
OtherColor: Color.Interpolate(Color.Orange, Color.Green, 0.3333);
}
I’m still not finished with GTL, but it’s daytime so back to Cantabile.
My weekend has descended into CompSci Compiler, Language and Algorithm geekiness.
If you’re into tokenizers, parsers, abstract syntax trees, execution plan optimizations and dynamic IL method generation (and who isn’t?) then I’ve got you covered:
It reminds a little of Karnaugh maps as a way of simplifying logic calcs, which I have not used since the 80s, but they came back to me when skimming your article.