From 5c0db46a609fd9245ba90c24244b50ea7a0c44fb Mon Sep 17 00:00:00 2001 From: Michael Gregorius Date: Sat, 27 Apr 2024 17:45:55 +0200 Subject: [PATCH] Streamline instrument flags (#7227) ## Instrument flags as a property of an instrument The instruments flags (single streamed, MIDI based, not bendable) are properties of an instrument that do not change over time. Therefore the flags are made a property of the instrument which is initialized at construction time. Adjust the constructors of all instruments which overrode the `flags` method to pass their flags into the `Instrument` constructor. ## Add helper methods for flags Add helper methods for the flags. This makes the code more concise and readable and clients do not need to know the technical details on how to evaluate a flag. ## Remove the flags methods Remove the flags methods to make it an implementation detail on how the flags are managed. --- include/Instrument.h | 21 +++++++++++++++----- plugins/CarlaBase/Carla.cpp | 7 +------ plugins/CarlaBase/Carla.h | 1 - plugins/GigPlayer/GigPlayer.cpp | 2 +- plugins/GigPlayer/GigPlayer.h | 5 ----- plugins/Kicker/Kicker.cpp | 2 +- plugins/Kicker/Kicker.h | 5 ----- plugins/Lb302/Lb302.cpp | 2 +- plugins/Lb302/Lb302.h | 5 ----- plugins/Lv2Instrument/Lv2Instrument.cpp | 8 +++++++- plugins/Lv2Instrument/Lv2Instrument.h | 8 -------- plugins/OpulenZ/OpulenZ.cpp | 2 +- plugins/OpulenZ/OpulenZ.h | 5 ----- plugins/Sf2Player/Sf2Player.cpp | 2 +- plugins/Sf2Player/Sf2Player.h | 5 ----- plugins/Vestige/Vestige.cpp | 2 +- plugins/Vestige/Vestige.h | 5 ----- plugins/Vibed/Vibed.cpp | 2 +- plugins/Vibed/Vibed.h | 2 -- plugins/ZynAddSubFx/ZynAddSubFx.cpp | 2 +- plugins/ZynAddSubFx/ZynAddSubFx.h | 5 ----- src/core/Instrument.cpp | 6 ++++-- src/core/InstrumentSoundShaping.cpp | 2 +- src/core/NotePlayHandle.cpp | 2 +- src/gui/instrument/InstrumentTrackWindow.cpp | 6 +++--- src/tracks/InstrumentTrack.cpp | 5 ++--- 26 files changed, 43 insertions(+), 76 deletions(-) diff --git a/include/Instrument.h b/include/Instrument.h index 0c28e7f3a..e2e980372 100644 --- a/include/Instrument.h +++ b/include/Instrument.h @@ -62,7 +62,8 @@ public: Instrument(InstrumentTrack * _instrument_track, const Descriptor * _descriptor, - const Descriptor::SubPluginFeatures::Key * key = nullptr); + const Descriptor::SubPluginFeatures::Key * key = nullptr, + Flags flags = Flag::NoFlags); ~Instrument() override = default; // -------------------------------------------------------------------- @@ -114,9 +115,19 @@ public: sample_rate_t getSampleRate() const; - virtual Flags flags() const + bool isSingleStreamed() const { - return Flag::NoFlags; + return m_flags.testFlag(Instrument::Flag::IsSingleStreamed); + } + + bool isMidiBased() const + { + return m_flags.testFlag(Instrument::Flag::IsMidiBased); + } + + bool isBendable() const + { + return !m_flags.testFlag(Instrument::Flag::IsNotBendable); } // sub-classes can re-implement this for receiving all incoming @@ -161,8 +172,8 @@ protected: private: InstrumentTrack * m_instrumentTrack; - -} ; + Flags m_flags; +}; LMMS_DECLARE_OPERATORS_FOR_FLAGS(Instrument::Flag) diff --git a/plugins/CarlaBase/Carla.cpp b/plugins/CarlaBase/Carla.cpp index c95a965c9..d96a1e4d4 100644 --- a/plugins/CarlaBase/Carla.cpp +++ b/plugins/CarlaBase/Carla.cpp @@ -150,7 +150,7 @@ static const char* host_ui_save_file(NativeHostHandle, bool isDir, const char* t CarlaInstrument::CarlaInstrument(InstrumentTrack* const instrumentTrack, const Descriptor* const descriptor, const bool isPatchbay) - : Instrument(instrumentTrack, descriptor), + : Instrument(instrumentTrack, descriptor, nullptr, Flag::IsSingleStreamed | Flag::IsMidiBased | Flag::IsNotBendable), kIsPatchbay(isPatchbay), fHandle(nullptr), fDescriptor(isPatchbay ? carla_get_native_patchbay_plugin() : carla_get_native_rack_plugin()), @@ -343,11 +343,6 @@ intptr_t CarlaInstrument::handleDispatcher(const NativeHostDispatcherOpcode opco // ------------------------------------------------------------------- -Instrument::Flags CarlaInstrument::flags() const -{ - return Flag::IsSingleStreamed | Flag::IsMidiBased | Flag::IsNotBendable; -} - QString CarlaInstrument::nodeName() const { return descriptor()->name; diff --git a/plugins/CarlaBase/Carla.h b/plugins/CarlaBase/Carla.h index 3d0e424a2..76a9b45b7 100644 --- a/plugins/CarlaBase/Carla.h +++ b/plugins/CarlaBase/Carla.h @@ -190,7 +190,6 @@ public: intptr_t handleDispatcher(const NativeHostDispatcherOpcode opcode, const int32_t index, const intptr_t value, void* const ptr, const float opt); // LMMS functions - Flags flags() const override; QString nodeName() const override; void saveSettings(QDomDocument& doc, QDomElement& parent) override; void loadSettings(const QDomElement& elem) override; diff --git a/plugins/GigPlayer/GigPlayer.cpp b/plugins/GigPlayer/GigPlayer.cpp index 2d67f0ddf..ecde81461 100644 --- a/plugins/GigPlayer/GigPlayer.cpp +++ b/plugins/GigPlayer/GigPlayer.cpp @@ -81,7 +81,7 @@ Plugin::Descriptor PLUGIN_EXPORT gigplayer_plugin_descriptor = GigInstrument::GigInstrument( InstrumentTrack * _instrument_track ) : - Instrument( _instrument_track, &gigplayer_plugin_descriptor ), + Instrument(_instrument_track, &gigplayer_plugin_descriptor, nullptr, Flag::IsSingleStreamed | Flag::IsNotBendable), m_instance( nullptr ), m_instrument( nullptr ), m_filename( "" ), diff --git a/plugins/GigPlayer/GigPlayer.h b/plugins/GigPlayer/GigPlayer.h index 85b1736a0..50d1acd40 100644 --- a/plugins/GigPlayer/GigPlayer.h +++ b/plugins/GigPlayer/GigPlayer.h @@ -259,11 +259,6 @@ public: QString nodeName() const override; - Flags flags() const override - { - return Flag::IsSingleStreamed | Flag::IsNotBendable; - } - gui::PluginView* instantiateView( QWidget * _parent ) override; QString getCurrentPatchName(); diff --git a/plugins/Kicker/Kicker.cpp b/plugins/Kicker/Kicker.cpp index e6418e2da..85fbf8e2b 100644 --- a/plugins/Kicker/Kicker.cpp +++ b/plugins/Kicker/Kicker.cpp @@ -64,7 +64,7 @@ Plugin::Descriptor PLUGIN_EXPORT kicker_plugin_descriptor = KickerInstrument::KickerInstrument( InstrumentTrack * _instrument_track ) : - Instrument( _instrument_track, &kicker_plugin_descriptor ), + Instrument(_instrument_track, &kicker_plugin_descriptor, nullptr, Flag::IsNotBendable), m_startFreqModel( 150.0f, 5.0f, 1000.0f, 1.0f, this, tr( "Start frequency" ) ), m_endFreqModel( 40.0f, 5.0f, 1000.0f, 1.0f, this, tr( "End frequency" ) ), m_decayModel( 440.0f, 5.0f, 5000.0f, 1.0f, 5000.0f, this, tr( "Length" ) ), diff --git a/plugins/Kicker/Kicker.h b/plugins/Kicker/Kicker.h index 820265dd5..508787707 100644 --- a/plugins/Kicker/Kicker.h +++ b/plugins/Kicker/Kicker.h @@ -64,11 +64,6 @@ public: QString nodeName() const override; - Flags flags() const override - { - return Flag::IsNotBendable; - } - float desiredReleaseTimeMs() const override { return 12.f; diff --git a/plugins/Lb302/Lb302.cpp b/plugins/Lb302/Lb302.cpp index e0b31360f..b0a6490b2 100644 --- a/plugins/Lb302/Lb302.cpp +++ b/plugins/Lb302/Lb302.cpp @@ -269,7 +269,7 @@ float Lb302Filter3Pole::process(const float& samp) // Lb302Synth::Lb302Synth( InstrumentTrack * _instrumentTrack ) : - Instrument( _instrumentTrack, &lb302_plugin_descriptor ), + Instrument(_instrumentTrack, &lb302_plugin_descriptor, nullptr, Flag::IsSingleStreamed), vcf_cut_knob( 0.75f, 0.0f, 1.5f, 0.005f, this, tr( "VCF Cutoff Frequency" ) ), vcf_res_knob( 0.75f, 0.0f, 1.25f, 0.005f, this, tr( "VCF Resonance" ) ), vcf_mod_knob( 0.1f, 0.0f, 1.0f, 0.005f, this, tr( "VCF Envelope Mod" ) ), diff --git a/plugins/Lb302/Lb302.h b/plugins/Lb302/Lb302.h index 2f4f64dcb..086b78a8a 100644 --- a/plugins/Lb302/Lb302.h +++ b/plugins/Lb302/Lb302.h @@ -163,11 +163,6 @@ public: QString nodeName() const override; - Flags flags() const override - { - return Flag::IsSingleStreamed; - } - gui::PluginView* instantiateView( QWidget * _parent ) override; private: diff --git a/plugins/Lv2Instrument/Lv2Instrument.cpp b/plugins/Lv2Instrument/Lv2Instrument.cpp index 316829327..766790cc1 100644 --- a/plugins/Lv2Instrument/Lv2Instrument.cpp +++ b/plugins/Lv2Instrument/Lv2Instrument.cpp @@ -73,7 +73,13 @@ Plugin::Descriptor PLUGIN_EXPORT lv2instrument_plugin_descriptor = Lv2Instrument::Lv2Instrument(InstrumentTrack *instrumentTrackArg, Descriptor::SubPluginFeatures::Key *key) : - Instrument(instrumentTrackArg, &lv2instrument_plugin_descriptor, key), + Instrument(instrumentTrackArg, &lv2instrument_plugin_descriptor, key, +#ifdef LV2_INSTRUMENT_USE_MIDI + Flag::IsSingleStreamed | Flag::IsMidiBased +#else + Flag::IsSingleStreamed +#endif + ), Lv2ControlBase(this, key->attributes["uri"]) { clearRunningNotes(); diff --git a/plugins/Lv2Instrument/Lv2Instrument.h b/plugins/Lv2Instrument/Lv2Instrument.h index de41dc958..9ae48c64c 100644 --- a/plugins/Lv2Instrument/Lv2Instrument.h +++ b/plugins/Lv2Instrument/Lv2Instrument.h @@ -84,14 +84,6 @@ public: /* misc */ - Flags flags() const override - { -#ifdef LV2_INSTRUMENT_USE_MIDI - return Flag::IsSingleStreamed | Flag::IsMidiBased; -#else - return Flag::IsSingleStreamed; -#endif - } gui::PluginView* instantiateView(QWidget *parent) override; private slots: diff --git a/plugins/OpulenZ/OpulenZ.cpp b/plugins/OpulenZ/OpulenZ.cpp index f0571ba5c..bf1459d6f 100644 --- a/plugins/OpulenZ/OpulenZ.cpp +++ b/plugins/OpulenZ/OpulenZ.cpp @@ -95,7 +95,7 @@ QMutex OpulenzInstrument::emulatorMutex; const auto adlib_opadd = std::array{0x00, 0x01, 0x02, 0x08, 0x09, 0x0A, 0x10, 0x11, 0x12}; OpulenzInstrument::OpulenzInstrument( InstrumentTrack * _instrument_track ) : - Instrument( _instrument_track, &opulenz_plugin_descriptor ), + Instrument(_instrument_track, &opulenz_plugin_descriptor, nullptr, Flag::IsSingleStreamed | Flag::IsMidiBased), m_patchModel( 0, 0, 127, this, tr( "Patch" ) ), op1_a_mdl(14.0, 0.0, 15.0, 1.0, this, tr( "Op 1 attack" ) ), op1_d_mdl(14.0, 0.0, 15.0, 1.0, this, tr( "Op 1 decay" ) ), diff --git a/plugins/OpulenZ/OpulenZ.h b/plugins/OpulenZ/OpulenZ.h index a3e11a6c0..a245b03ad 100644 --- a/plugins/OpulenZ/OpulenZ.h +++ b/plugins/OpulenZ/OpulenZ.h @@ -64,11 +64,6 @@ public: QString nodeName() const override; gui::PluginView* instantiateView( QWidget * _parent ) override; - Flags flags() const override - { - return Flag::IsSingleStreamed | Flag::IsMidiBased; - } - bool handleMidiEvent( const MidiEvent& event, const TimePos& time, f_cnt_t offset = 0 ) override; void play( sampleFrame * _working_buffer ) override; diff --git a/plugins/Sf2Player/Sf2Player.cpp b/plugins/Sf2Player/Sf2Player.cpp index 7795671c5..9ded939d7 100644 --- a/plugins/Sf2Player/Sf2Player.cpp +++ b/plugins/Sf2Player/Sf2Player.cpp @@ -122,7 +122,7 @@ struct Sf2PluginData Sf2Instrument::Sf2Instrument( InstrumentTrack * _instrument_track ) : - Instrument( _instrument_track, &sf2player_plugin_descriptor ), + Instrument(_instrument_track, &sf2player_plugin_descriptor, nullptr, Flag::IsSingleStreamed), m_srcState( nullptr ), m_synth(nullptr), m_font( nullptr ), diff --git a/plugins/Sf2Player/Sf2Player.h b/plugins/Sf2Player/Sf2Player.h index 4760d572e..ec7ace47f 100644 --- a/plugins/Sf2Player/Sf2Player.h +++ b/plugins/Sf2Player/Sf2Player.h @@ -80,11 +80,6 @@ public: QString nodeName() const override; - Flags flags() const override - { - return Flag::IsSingleStreamed; - } - gui::PluginView* instantiateView( QWidget * _parent ) override; QString getCurrentPatchName(); diff --git a/plugins/Vestige/Vestige.cpp b/plugins/Vestige/Vestige.cpp index 834b583ed..1de713960 100644 --- a/plugins/Vestige/Vestige.cpp +++ b/plugins/Vestige/Vestige.cpp @@ -152,7 +152,7 @@ private: VestigeInstrument::VestigeInstrument( InstrumentTrack * _instrument_track ) : - Instrument( _instrument_track, &vestige_plugin_descriptor ), + Instrument(_instrument_track, &vestige_plugin_descriptor, nullptr, Flag::IsSingleStreamed | Flag::IsMidiBased), m_plugin( nullptr ), m_pluginMutex(), m_subWindow( nullptr ), diff --git a/plugins/Vestige/Vestige.h b/plugins/Vestige/Vestige.h index 9ac66f74d..529893ba0 100644 --- a/plugins/Vestige/Vestige.h +++ b/plugins/Vestige/Vestige.h @@ -70,11 +70,6 @@ public: virtual void loadFile( const QString & _file ); - virtual Flags flags() const - { - return Flag::IsSingleStreamed | Flag::IsMidiBased; - } - virtual bool handleMidiEvent( const MidiEvent& event, const TimePos& time, f_cnt_t offset = 0 ); virtual gui::PluginView* instantiateView( QWidget * _parent ); diff --git a/plugins/Vibed/Vibed.cpp b/plugins/Vibed/Vibed.cpp index ddf9097a5..3dc4bfa56 100644 --- a/plugins/Vibed/Vibed.cpp +++ b/plugins/Vibed/Vibed.cpp @@ -97,7 +97,7 @@ private: }; Vibed::Vibed(InstrumentTrack* instrumentTrack) : - Instrument(instrumentTrack, &vibedstrings_plugin_descriptor) + Instrument(instrumentTrack, &vibedstrings_plugin_descriptor, nullptr, Flag::IsNotBendable) { for (int harm = 0; harm < s_stringCount; ++harm) { diff --git a/plugins/Vibed/Vibed.h b/plugins/Vibed/Vibed.h index 18d334c4d..ec8395da1 100644 --- a/plugins/Vibed/Vibed.h +++ b/plugins/Vibed/Vibed.h @@ -65,8 +65,6 @@ public: QString nodeName() const override; - Flags flags() const override { return Flag::IsNotBendable; } - gui::PluginView* instantiateView(QWidget* parent) override; private: diff --git a/plugins/ZynAddSubFx/ZynAddSubFx.cpp b/plugins/ZynAddSubFx/ZynAddSubFx.cpp index c406e04e0..85b240380 100644 --- a/plugins/ZynAddSubFx/ZynAddSubFx.cpp +++ b/plugins/ZynAddSubFx/ZynAddSubFx.cpp @@ -103,7 +103,7 @@ bool ZynAddSubFxRemotePlugin::processMessage( const message & _m ) ZynAddSubFxInstrument::ZynAddSubFxInstrument( InstrumentTrack * _instrumentTrack ) : - Instrument( _instrumentTrack, &zynaddsubfx_plugin_descriptor ), + Instrument(_instrumentTrack, &zynaddsubfx_plugin_descriptor, nullptr, Flag::IsSingleStreamed | Flag::IsMidiBased), m_hasGUI( false ), m_plugin( nullptr ), m_remotePlugin( nullptr ), diff --git a/plugins/ZynAddSubFx/ZynAddSubFx.h b/plugins/ZynAddSubFx/ZynAddSubFx.h index a391203f3..b4f7c434c 100644 --- a/plugins/ZynAddSubFx/ZynAddSubFx.h +++ b/plugins/ZynAddSubFx/ZynAddSubFx.h @@ -86,11 +86,6 @@ public: QString nodeName() const override; - Flags flags() const override - { - return Flag::IsSingleStreamed | Flag::IsMidiBased; - } - gui::PluginView* instantiateView( QWidget * _parent ) override; diff --git a/src/core/Instrument.cpp b/src/core/Instrument.cpp index 2dfdc78f5..3e884eaca 100644 --- a/src/core/Instrument.cpp +++ b/src/core/Instrument.cpp @@ -37,9 +37,11 @@ namespace lmms Instrument::Instrument(InstrumentTrack * _instrument_track, const Descriptor * _descriptor, - const Descriptor::SubPluginFeatures::Key *key) : + const Descriptor::SubPluginFeatures::Key *key, + Flags flags) : Plugin(_descriptor, nullptr/* _instrument_track*/, key), - m_instrumentTrack( _instrument_track ) + m_instrumentTrack( _instrument_track ), + m_flags(flags) { } diff --git a/src/core/InstrumentSoundShaping.cpp b/src/core/InstrumentSoundShaping.cpp index 07c3bbf7c..2e00760cc 100644 --- a/src/core/InstrumentSoundShaping.cpp +++ b/src/core/InstrumentSoundShaping.cpp @@ -303,7 +303,7 @@ f_cnt_t InstrumentSoundShaping::releaseFrames() const f_cnt_t ret_val = m_instrumentTrack->instrument()->desiredReleaseFrames(); - if( m_instrumentTrack->instrument()->flags().testFlag( Instrument::Flag::IsSingleStreamed ) ) + if (m_instrumentTrack->instrument()->isSingleStreamed()) { return ret_val; } diff --git a/src/core/NotePlayHandle.cpp b/src/core/NotePlayHandle.cpp index 2c1c21931..d7882b525 100644 --- a/src/core/NotePlayHandle.cpp +++ b/src/core/NotePlayHandle.cpp @@ -109,7 +109,7 @@ NotePlayHandle::NotePlayHandle( InstrumentTrack* instrumentTrack, m_instrumentTrack->midiNoteOn( *this ); } - if(m_instrumentTrack->instrument() && m_instrumentTrack->instrument()->flags() & Instrument::Flag::IsSingleStreamed ) + if (m_instrumentTrack->instrument() && m_instrumentTrack->instrument()->isSingleStreamed()) { setUsesBuffer( false ); } diff --git a/src/gui/instrument/InstrumentTrackWindow.cpp b/src/gui/instrument/InstrumentTrackWindow.cpp index 86d9086c8..8b868bb50 100644 --- a/src/gui/instrument/InstrumentTrackWindow.cpp +++ b/src/gui/instrument/InstrumentTrackWindow.cpp @@ -350,7 +350,7 @@ void InstrumentTrackWindow::modelChanged() m_mixerChannelNumber->setModel( &m_track->m_mixerChannelModel ); m_pianoView->setModel( &m_track->m_piano ); - if( m_track->instrument() && m_track->instrument()->flags().testFlag( Instrument::Flag::IsNotBendable ) == false ) + if (m_track->instrument() && m_track->instrument()->isBendable()) { m_pitchKnob->setModel( &m_track->m_pitchModel ); m_pitchRangeSpinBox->setModel( &m_track->m_pitchRangeModel ); @@ -368,7 +368,7 @@ void InstrumentTrackWindow::modelChanged() m_pitchRangeLabel->hide(); } - if (m_track->instrument() && m_track->instrument()->flags().testFlag(Instrument::Flag::IsMidiBased)) + if (m_track->instrument() && m_track->instrument()->isMidiBased()) { m_tuningView->microtunerNotSupportedLabel()->show(); m_tuningView->microtunerGroupBox()->hide(); @@ -462,7 +462,7 @@ void InstrumentTrackWindow::updateInstrumentView() m_tabWidget->addTab( m_instrumentView, tr( "Plugin" ), "plugin_tab", 0 ); m_tabWidget->setActiveTab( 0 ); - m_ssView->setFunctionsHidden( m_track->m_instrument->flags().testFlag( Instrument::Flag::IsSingleStreamed ) ); + m_ssView->setFunctionsHidden(m_track->m_instrument->isSingleStreamed()); modelChanged(); // Get the instrument window to refresh m_track->dataChanged(); // Get the text on the trackButton to change diff --git a/src/tracks/InstrumentTrack.cpp b/src/tracks/InstrumentTrack.cpp index a32d301c4..3317ea71b 100644 --- a/src/tracks/InstrumentTrack.cpp +++ b/src/tracks/InstrumentTrack.cpp @@ -233,8 +233,7 @@ void InstrumentTrack::processAudioBuffer( sampleFrame* buf, const fpp_t frames, // We could do that in all other cases as well but the overhead for silence test is bigger than // what we potentially save. While playing a note, a NotePlayHandle-driven instrument will produce sound in // 99 of 100 cases so that test would be a waste of time. - if( m_instrument->flags().testFlag( Instrument::Flag::IsSingleStreamed ) && - MixHelpers::isSilent( buf, frames ) ) + if (m_instrument->isSingleStreamed() && MixHelpers::isSilent(buf, frames)) { // at least pass one silent buffer to allow if( m_silentBuffersProcessed ) @@ -263,7 +262,7 @@ void InstrumentTrack::processAudioBuffer( sampleFrame* buf, const fpp_t frames, // instruments using instrument-play-handles will call this method // without any knowledge about notes, so they pass NULL for n, which // is no problem for us since we just bypass the envelopes+LFOs - if( m_instrument->flags().testFlag( Instrument::Flag::IsSingleStreamed ) == false && n != nullptr ) + if (!m_instrument->isSingleStreamed() && n != nullptr) { const f_cnt_t offset = n->noteOffset(); m_soundShaping.processAudioBuffer( buf + offset, frames - offset, n );