It's a bad style to manage global instances of an object in the object
itself. Therefore introduced a nested helper class which manages all
instances of EnvelopeAndLfoParameters globally. It is now responsible
for global reset/triggers of LFOs. In contrast to previous state, this
is now done thread-safe. Fixes crashes for example while importing
MIDI files.
The new deleteHelper() template function takes a pointer, saves it
to a temporary, sets the passed pointer to NULL and then deletes the
object it was referring to before. This way we can spot bugs caused by
undesired references to global objects at shutdown more easily.
It was not safe to immediately delete the AutomationPattern attached to
an InlineAutomation object before commit "InlineAutomation: delete
attached AutomationPattern immediately" as the AutomationPattern
destructor sometimes fiddles around with AutomationEditor (GUI!).
However this has changed now and this enables us to delete the
AutomationPattern immediately. This fixes some random crashes with
scheduling AutomationPatterns for later deletion.
Closes#2982696.
It was not possible to call any of the functions of AutomationEditor
from threads other than the main GUI thread as the m_pattern pointer
was not protected by a mutex. It is however desired to be able to call
for example AutomationEditor::setCurrentPattern(...) from different
threads (mainly required when deleting AutomationPatterns in other
threads). Thus made this method and all accesses to the m_pattern
pointer thread-safe.
Due to the FxMixer improvements some plugins such as the FLP import
filter now directly access the FxMixer and its view. Therefore the
symbols of the FxMixer and FxMixerView classes need to be exported for
the win32 builds.
For some effects it is helpful to know whether their attached EffectView
is visible or not. This mainly concerns effects that actually do not
touch the sound data but analyze it and display the results.
In Base64::decode() we mess around with pointers so it's more type-safe
to realize everything as a template function. This also silences compiler
warning about dereferencing type-punned pointer in Vibed plugin.
* auto-save:
don't change the current project when auto-saving
auto-saves every minute and recovers upon crash
don't show WelcomeScreen when importing/loading
Conflicts:
src/gui/MainWindow.cpp
Renamed the ProjectRenderer::OutputSettings structure to
ProjectRenderer::EncoderSettings to better reflect its meaning.
Additionally added some basic Doxygen comments.
Until now, Mixer not only was responsible for rendering audio buffers
but also managed writing them to audio backend (through a FIFO) and
handled various quality related parameters.
All this functionality has been moved into the new AudioOutputContext
class. It glues together AudioBackend (formerly called AudioDevice),
global quality settings and the Mixer.
The AudioOutputContext class creates a FifoWriter which calls
Mixer::renderNextBuffer() and writes the output into the BufferFifo of
the AudioOutputContext it belongs to. The BufferFifo is read by the
according AudioBackend which belongs to the AudioOutputContext as well.
The AudioOutputContext also handles resampling in case the AudioBackend
wants the buffers in a different samplerate.
During this rewrite the Mixer class and the according source files have
been renamed from "mixer" to "Mixer". This results in small changes
all over LMMS' code base.
This reverts commit c517f1fa5a.
The commit was not very helpful and introduced new xrun problems.
Instead I'll be rewriting the part of LMMS where Mixer, Mixer's
quality settings, Buffer FIFO and AudioDevice are sticked together.
There's really no need to allocate a buffer each period, push it to the
FifoBuffer and free it when fetching the buffer in
AudioDevice::getNextBuffer(). Instead keep the pointer in FifoBuffer's
pool and reuse it.
There have been some problems with the threading logic in the
AudioPulseAudio backend resulting in an endless loop when quitting LMMS.
Furthermore allocated PulseAudio resources were not freed properly.
Thanks to Armin Kazmi <armin.kazmi@tu-dortmund.de> for pointing out
this issue.
every time auto-save ran, it would change the current project to
"recover.mmp". Now it doesn't do this because Song has
guiSaveProject(), guiSaveProjectAs(), and saveProjectFile().
(the latter is used for auto-save)
auto-save time is not configurable yet. saves "recover.mmp" to
WORKING_DIR every 60 seconds. Deletes recover.mmp on successful
close of LMMS. If recover.mmp is found upon start, it loads that
project.
Rewrote implementation of class SideBar to use QToolBar instead of
KMultiTabBar. We can style the SideBar now easily via CSS and do not
have to ship 3rd party KDE code with LMMS. Also the QToolBar based
SideBar integrates much better into the according widget style.
Furthermore renamed SideBar related classes and files to match new
coding style.
Functionality from QuickLoadDialog which can be used in similiar dialogs
for selecting resources has been moved into generic and highly flexible
base class ResourceSelectDialog.
Again there's no need for duplicated functionality. Adding a
ResourceAction::defaultTrigger() method allows to separate all
functionality from ResourceBrowser and possibly use it in other places
as well.
There's absolutely no need for duplicating the Action enumeration
in ResourceBrowser as there's already one in ResourceAction class.
Replacing the enumeration with ResourceAction's one makes code clearer
and reduces redundancy.
Added another buffer operation BufMixCoeff allowing to mix a certain
buffer to another at a given amount (coeff). CpuX86 has been extended
by an according SSE implementation.
This should resolve the remaining issues. OSS has auto-complete with
the filesystem. Alsa has an editable combobox for PCM and MIDI-raw.
The DEVICE box for Alsa MIDI-seq should be obsoleted
JobQueues can now operate in JobQueue::Static and JobQueue::Dynamic mode.
In static mode it operates the way it always used to while in dynamic
mode a changing job queue is supported. This is particularly important
for FX mixer sends.
There were also heavy improvements regarding the overall structure
and functionality of MixerWorkerThread and MixerWorkerThread::JobQueue.
There's now a clean distinction between multi-threaded processing
and actual (thread-safe) job queue processing. MixerWorkerThread does
not need to be a friend class of Mixer anymore.
Declarations and implementations of MixerWorkerThread and ThreadableJob
have been moved into separate source files.
Furthermore there were some improvements to MixerWorkerThreads.
MixerWorkerThread::processJobQueue() does not return until the job
queue completely has been processed. This way each thread can "help"
to finish processing the queue and does not get back to sleep until
all of the work is done.
Management of the queue is now done via an array of QAtomicPointers.
Items that are non-NULL still need to be processed while NULL-items
were taken from the queue (i.e. in progress or done). Thus we do not
need to deal with ThreadableJob-states within MixerWorkerThread anymore.
The FxMixer now uses job threads to accomplish its mixing. It's
theoretically efficient, but there is a horrible thread bug
preventing the code from working. I've spent 5 hours debugging and
need some external help!
In Mixer, the old C-macro based code has been replaced by an OOP-like
design. Management of job queue now happens via some static member
methods of MixerWorkerThread. All the moved code still needs to be
splitted into some new files but here's a first dirty version.
All objects that are intended to be processed by MixerWorkerThreads
have to inherit ThreadableJob (name of class is subject of change).
One can add jobs to the job queue even if the queue is already being
processed. This is merely important for multithreading with upcoming
FX sends support.
In the Fx Mixer View, you can select a channel and press Alt+Left
and Alt+Right respectively to re-order Fx Channels. This should be
made more easily available in the GUI eventually.
* lock fx mixer height
Done. channelArea->setFixedHeight and proper sizeConstraints
* width: pick a good min. size. keep max. size off.
Done. Set to 6 fx-lines.
* effects chain should align to the right
Done.
* get rid of padding in mixer
Done. setSpacing and setMargin on chLayout
* scroll area so that vert scrollbar is never seen.
Done. setVerticalScrollBarPolicy and proper height calculation
* Get rid of scroll bar area border
Done. FrameStyle.
The biggest change, however, was removing the multiple EffectRackViews
that were being used. Now just a single EffectRackView exists and it is
shared by all models.