Lmms: Anormal CPU usage by VST's in 1.2.0-RC's

Created on 28 Aug 2018  路  11Comments  路  Source: LMMS/lmms

Steps to reproduce :
1) Launch LMMS 1.2.0 RC-5 or 6 (audio interface : SDL, plugin embedding : Native Win32 API)
2) Put 10*EasyQ VST on the master channel (for the sake of simplicity, I took EasyQ as an example, it's and I load it 10 times to simulate big projects)
3) Put a Vestige instrument from the instrument plugin tab (just put vestige on the project, no need to load a VSTi)
4) Look at the CPU meter
image

1) Launch LMMS 1.1.3 (audio interface : SDL)
2) Put 10*EasyQ VST on the master channel
3) Put a Vestige instrument from the instrument plugin tab
4) Look at the CPU meter
image

More Infos :
I'm not sure where the error could be, I don't even know if it's only me or if it's a real bug, but the result is that I can't open my biggest projects in LMMS 1.2.0-RC's because the CPU overload too quickly compared to LMMS 1.1.3
Seems like a regression to me.

System config :
Windows 7 64bits

If you need more informations, please let me know, I will do everything I can to help.

Thanks in advance,

T0NIT0 RMX

bug core performance

Most helpful comment

This only seems to happen when the VeSTige is being sent to a channel with VST effects.

I can reproduce this with other instruments with IsSingleStreamed flag, e.g. LB302. It means this issue is not VST-specific.

I think it's related to the CPU saving feature. Single-streamed instruments use InstrumentPlayHandle which always use buffers. It makes AudioPort::doProcessing always route signals to the FX mixer and makes effects always run.
https://github.com/LMMS/lmms/blob/4bb6586c66fdeb0ef2f84667958d340a8355c5fe/src/core/audio/AudioPort.cpp#L120-L124
https://github.com/LMMS/lmms/blob/4bb6586c66fdeb0ef2f84667958d340a8355c5fe/src/core/audio/AudioPort.cpp#L221-L224

All 11 comments

@T0NIT0RMX

no need to load a VSTi

Yes there is. Weirdly empty VSTi containers on their own, make CPU spike-out, and make noise -Related #3798
Also 10 identical EQs on Master, is a very artificial situation, but i will try..

@musikBear #3798 says it's fixed, but imo it's not, as I'm still experiencing it in the lastest RC.
I mean, if I put a VSTi in Vestige, the memory spike is still present

Yes I agree, it's artificial. But, as I said I put 10 EasyQ for the sake of simplicity... I could have described all my mastering chain for example, Mequalizer, ReaXcomp, OTT, MSaturator, Gclip etc.. but it's not related to 1 vst in particular so I took EasyQ as an example, to make it easy to reproduce !

Okay, this is really interesting. I'm using SerumFX for this test.

I put 5 instances of SerumFX on master. This didn't seem to affect my CPU usage.

However, when I added an empty VeSTige, my CPU usage increased as described. In addition, when I removed the effects from master, the CPU usage went back down.


What's even more interesting is this: This only seems to happen when the VeSTige is being sent to a channel with VST effects.

Steps to reproduce this specific case:

  1. Add a new channel
  2. Add 5 copies of some VST effect to the channel
  3. Route the tripleoscillator to the channel. The CPU usage shouldn't increase.
  4. Add a copy of VeSTige. The CPU usage still shouldn't increase.
  5. Finally, route the VeSTige to the new channel. The CPU usage should noticeably jump.

Tagging @DomClark because I think that's what you're supposed to do when there's VST issues 馃槃

This only seems to happen when the VeSTige is being sent to a channel with VST effects.

I can reproduce this with other instruments with IsSingleStreamed flag, e.g. LB302. It means this issue is not VST-specific.

I think it's related to the CPU saving feature. Single-streamed instruments use InstrumentPlayHandle which always use buffers. It makes AudioPort::doProcessing always route signals to the FX mixer and makes effects always run.
https://github.com/LMMS/lmms/blob/4bb6586c66fdeb0ef2f84667958d340a8355c5fe/src/core/audio/AudioPort.cpp#L120-L124
https://github.com/LMMS/lmms/blob/4bb6586c66fdeb0ef2f84667958d340a8355c5fe/src/core/audio/AudioPort.cpp#L221-L224

It may still be VST-specific - certainly it seems VeSTige is not necessary to reproduce this, but that doesn't rule out VST effects. Is the performance drop from 1.1.3 to 1.2 present for all effects, or only VSTs?

I believe it can be reproduced with a bunch of native EQ effects. However, many VSTs will use more CPU.

@DomClark I tried with native effects, like Equalizer as suggested by @PhysSong.
And I don't notice any issue, but again native effect don't use lot's of CPU compared to VST's

Hey guys,
just tried with the new RC7 and it's still the same, is it planned to be fixed for the 2.0 release ?
Thanks in advance,

I'll try to address it in the 1.2 series.

Here's a diff for a possible approach. Thoughts?

diff --git a/include/InstrumentPlayHandle.h b/include/InstrumentPlayHandle.h
index 02d6fc69c..1d1248ebd 100644
--- a/include/InstrumentPlayHandle.h
+++ b/include/InstrumentPlayHandle.h
@@ -25,9 +25,12 @@
 #ifndef INSTRUMENT_PLAY_HANDLE_H
 #define INSTRUMENT_PLAY_HANDLE_H

-#include "PlayHandle.h"
+#include "Engine.h"
 #include "Instrument.h"
+#include "MixHelpers.h"
+#include "Mixer.h"
 #include "NotePlayHandle.h"
+#include "PlayHandle.h"
 #include "export.h"

 class EXPORT InstrumentPlayHandle : public PlayHandle
@@ -69,6 +72,11 @@ public:
        return false;
    }

+   virtual bool isSilent() const
+   {
+       return MixHelpers::isSilent( buffer(), Engine::mixer()->framesPerPeriod() );
+   }
+
    virtual bool isFromTrack( const Track* _track ) const
    {
        return m_instrument->isFromTrack( _track );
diff --git a/include/PlayHandle.h b/include/PlayHandle.h
index 329a8f766..6bc01710c 100644
--- a/include/PlayHandle.h
+++ b/include/PlayHandle.h
@@ -107,6 +107,11 @@ public:
    virtual void play( sampleFrame* buffer ) = 0;
    virtual bool isFinished() const = 0;

+   virtual bool isSilent() const
+   {
+       return false;
+   }
+
    // returns the frameoffset at the start of the playhandle,
    // ie. how many empty frames should be inserted at the start of the first period
    f_cnt_t offset() const
@@ -145,6 +150,7 @@ public:
    void releaseBuffer();

    sampleFrame * buffer();
+   const sampleFrame * buffer() const;

 private:
    Type m_type;
diff --git a/src/core/PlayHandle.cpp b/src/core/PlayHandle.cpp
index 9e92019a6..6d37d3005 100644
--- a/src/core/PlayHandle.cpp
+++ b/src/core/PlayHandle.cpp
@@ -71,5 +71,10 @@ void PlayHandle::releaseBuffer()

 sampleFrame* PlayHandle::buffer()
 {
-   return m_bufferReleased ? nullptr : reinterpret_cast<sampleFrame*>(m_playHandleBuffer);
+   return m_bufferReleased ? nullptr : m_playHandleBuffer;
+};
+
+const sampleFrame* PlayHandle::buffer() const
+{
+   return m_bufferReleased ? nullptr : m_playHandleBuffer;
 };
diff --git a/src/core/audio/AudioPort.cpp b/src/core/audio/AudioPort.cpp
index 868f9f64f..b567fe897 100644
--- a/src/core/audio/AudioPort.cpp
+++ b/src/core/audio/AudioPort.cpp
@@ -119,7 +119,7 @@ void AudioPort::doProcessing()
    {
        if( ph->buffer() )
        {
-           if( ph->usesBuffer() )
+           if( ph->usesBuffer() && !ph->isSilent() )
            {
                m_bufferUsage = true;
                MixHelpers::add( m_portBuffer, ph->buffer(), fpp );

Looks good to me.

Was this page helpful?
0 / 5 - 0 ratings