I'm not saying sample-accurate, because it turns out, Fluidsynth has an internal buffer size and thus timing granularity of 64 frames. So 64 frames is the max. accuracy attainable for SF2. But it's better than nothing. Big thanks to David Henningsson of the Fluidsynth dev team, who very helpfully answered questions. A great guy.
In addition, there are some fixes to earlier commits here, which I ran into while working on the SF2 timing.
- Remove the redundant hasSampleExactData() function. Instead, signal lack of s.ex.data by returning a NULL in valueBuffer()
- Cache s.ex.buffers and only update them once per period
- Make valueBuffer() in AutomatableModel threadsafe so that it can be used for NPH's sharing the same model
- Add sample-exactness to instrumenttrack's vol & pan knobs
Change in handling of frameoffset for multistreamed instruments and sampletracks.
- Instead of holding the offset for the lifetime of the playhandle, negate the offset in the first period
- Multistream-instruments require some small changes: they have to now check for the offset and accordingly leave empty space in the start of the period (already done in this commit)
- There are possibly optimizations that can be done later
- This change is necessary so that we can have sample-exact models, and sample-exact vol/pan knobs for all instruments. Earlier multistream instruments were always rendering some frames ahead-of-time, so applying sample-exact data for them would have been impossible, since we don't have the future-values yet...
Fixes#865. Added a check so we don't add subnotes to a note that is already released (can happen with very short midinotes, eg. sliding the mouse accross the gui piano).
I also added a mutex to incoming midievent handling in instrumenttrack. Not sure if strictly necessary, but seems like this would prevent problems in the long run.
Also fixed a glitch in noteplayhandle where silent master notes got stuck playing indefinitely ( isMasternote() returns true even if the nph just hadChildren, so it never gets ended if it did - instead we check if we still have subnotes).
There's no need to ever link a model to itself, allowing it can cause weird issues and crashes, plus it's easy to do by accident if you start a ctrl-drag and end it while still on the same widget
Apparently, we can use QBrush -typed properties in the CSS. This just never occured to me before!
So, this has several benefits. A QColor property only allows a singular RGB value, but a QBrush allows the same plus also qgradients, RGBA-colours and maybe even bitmap patterns. So I'm changing some properties to QBrush, where it makes sense to allow this additional functionality - no need to enable it for simple things like text colours or such.
- Song editor background: instead of the earlier hack with 7 qproperties just to set a limited background gradient, we can use only 2 properties and allow much more flexibility with Qt's own qgradient syntax
- Automation editor: background, graph colour, and the sidebar colour - @musikBear recently complained not seeing the grid through the graph, so transparency can help there, and qlineargradients in the graph can produce very cool visual effects. Grid is pointless to change, it should stay single-colour for now.
- Piano roll: here, I only made the background use QBrush - we don't really have much else here that can utilize QBrush, the notes have their own gradient system... maybe the 2nd colour of the note gradient could be customizable though.
There are probably more places where this change makes sense...
- This allows defining a default colour for BB-track patterns in the CSS
- The default colour is used for all bb-patterns which don't have a custom colour set by the user: in other words, the colour of a pattern can be any rgb-value OR "style colour"
- By default, all created bb-patterns use the style colour
- You can also reset colourized patterns to use style colour again
- Backwards compatibility: old projects will be loaded so that any pattern using either of the old default colours will be converted to use style colour
TODO: add a settings option that can disable custom colours (ie. always use style colour), and/or an option to reset all patterns in a project to style colour. This is needed, since themes can now change the song editor background, which can lead to unfortunate colour combinations with custom colours...
Implements a ring buffer class for LMMS, which is designed to be flexible, efficient and thread-safe.
Due to flexible design, it supports various methods of operation:
- set delays/sizes in absolute frame values, ignoring samplerate
- set delays/sizes in milliseconds with samplerate-awareness
- multiple inputs -> single output
- single input -> multiple outputs
Efficiency is achieved by working in buffers and using memcpy/memset for audio operations, except when additive mixing is needed: then MixHelpers are used
Thread-safety is guaranteed with QMutex
- currently only affects Vestige
- no idea whether this can also be used for Zyn and OpulenZ, I'm not sure if Zyn has any kind of mechanism for communicating frame offset to the synth, as for OpulenZ, @softrabbit would know the answer better
- basically, I made it happen by simply adding an extra parameter in the processMidi{In|Out} functions, which is 0 by default, and made the necessary changes in instrumentTrack and nph to utilize it
- I based this against 1.1 because I didn't think it's a very big change, and I don't see much possibility for things going wrong here, since we're basically just using the existing functionality in Vestige (there already was a frame offset being communicated to the remote plugin, just that it was always set to 0). However, if @tobydox thinks this is better to bump up to 1.2, I can rebase it for master...