vibefix disintegrator
Some checks failed
build / linux-arm64 (push) Has been cancelled
build / macos-arm64 (push) Has been cancelled
build / macos-x86_64 (push) Has been cancelled
build / mingw64 (push) Has been cancelled
checks / scripted-checks (push) Has been cancelled
build / linux-x86_64 (push) Has been cancelled
build / msvc-x64 (push) Has been cancelled
checks / shellcheck (push) Has been cancelled
build / windows-arm64 (push) Has been cancelled
checks / yamllint (push) Has been cancelled

This commit is contained in:
Your Name
2026-03-15 04:50:00 +01:00
parent bec763a179
commit c39da2f8cc
6 changed files with 302 additions and 279 deletions

View File

@@ -24,24 +24,30 @@
#include "Disintegrator.h"
#include "Engine.h"
#include "embed.h"
#include "lmms_math.h"
#include "plugin_export.h"
#include <numbers>
namespace lmms
{
extern "C"
{
Plugin::Descriptor PLUGIN_EXPORT disintegrator_plugin_descriptor =
{
STRINGIFY(PLUGIN_NAME),
"Disintegrator",
QT_TRANSLATE_NOOP("pluginBrowser", "A delay modulation effect for very aggressive digital distortion."),
"Lost Robot <r94231@gmail.com>",
0x0100,
Plugin::Effect,
new PluginPixmapLoader("logo"),
NULL,
NULL
LMMS_STRINGIFY(PLUGIN_NAME),
"Disintegrator",
QT_TRANSLATE_NOOP("PluginBrowser", "A delay modulation effect for very aggressive digital distortion."),
"Lost Robot <r94231@gmail.com>",
0x0100,
Plugin::Type::Effect,
new PixmapLoader("logo"),
nullptr,
nullptr
} ;
}
@@ -49,163 +55,153 @@ Plugin::Descriptor PLUGIN_EXPORT disintegrator_plugin_descriptor =
DisintegratorEffect::DisintegratorEffect(Model* parent, const Descriptor::SubPluginFeatures::Key* key) :
Effect(&disintegrator_plugin_descriptor, parent, key),
m_disintegratorControls(this),
m_needsUpdate(true)
Effect(&disintegrator_plugin_descriptor, parent, key),
m_disintegratorControls(this),
m_needsUpdate(true)
{
sampleRateChanged();
sampleRateChanged();
}
void DisintegratorEffect::sampleRateChanged()
{
m_sampleRate = Engine::mixer()->processingSampleRate();
m_2PiOverSR = F_2PI / m_sampleRate;
m_lp = new BasicFilters<2>(Engine::mixer()->processingSampleRate());
m_hp = new BasicFilters<2>(Engine::mixer()->processingSampleRate());
m_lp->setFilterType(0);
m_hp->setFilterType(1);
m_needsUpdate = true;
m_sampleRate = Engine::audioEngine()->outputSampleRate();
m_2PiOverSR = 2.0f * std::numbers::pi_v<float> / m_sampleRate;
m_lp = new BasicFilters<2>(Engine::audioEngine()->outputSampleRate());
m_hp = new BasicFilters<2>(Engine::audioEngine()->outputSampleRate());
m_lp->setFilterType(BasicFilters<2>::FilterType::LowPass);
m_hp->setFilterType(BasicFilters<2>::FilterType::HiPass);
m_needsUpdate = true;
m_bufferSize = m_sampleRate * 0.01f + 1.f;
for (int i = 0; i < 2; ++i)
{
m_inBuf[i].resize(m_bufferSize);
}
m_bufferSize = m_sampleRate * 0.01f + 1.f;
for (int i = 0; i < 2; ++i)
{
m_inBuf[i].resize(m_bufferSize);
}
}
bool DisintegratorEffect::processAudioBuffer(sampleFrame* buf, const fpp_t frames)
Effect::ProcessStatus DisintegratorEffect::processImpl(SampleFrame* buf, const fpp_t frames)
{
if (!isEnabled() || !isRunning ())
{
return false;
}
const float d = dryLevel();
const float w = wetLevel();
double outSum = 0.0;
const float d = dryLevel();
const float w = wetLevel();
const ValueBuffer * amountBuf = m_disintegratorControls.m_amountModel.valueBuffer();
const ValueBuffer * typeBuf = m_disintegratorControls.m_typeModel.valueBuffer();
const ValueBuffer * freqBuf = m_disintegratorControls.m_lowCutModel.valueBuffer();
const ValueBuffer * amountBuf = m_disintegratorControls.m_amountModel.valueBuffer();
const ValueBuffer * typeBuf = m_disintegratorControls.m_typeModel.valueBuffer();
const ValueBuffer * freqBuf = m_disintegratorControls.m_lowCutModel.valueBuffer();
// Update filters
if(m_needsUpdate || m_disintegratorControls.m_highCutModel.isValueChanged())
{
m_lp->calcFilterCoeffs(m_disintegratorControls.m_highCutModel.value(), 0.5);
}
if(m_needsUpdate || m_disintegratorControls.m_lowCutModel.isValueChanged())
{
m_hp->calcFilterCoeffs(m_disintegratorControls.m_lowCutModel.value(), 0.5);
}
m_needsUpdate = false;
// Update filters
if(m_needsUpdate || m_disintegratorControls.m_highCutModel.isValueChanged())
{
m_lp->calcFilterCoeffs(m_disintegratorControls.m_highCutModel.value(), 0.5);
for (fpp_t f = 0; f < frames; ++f)
{
const float amount = (amountBuf ? amountBuf->value(f) : m_disintegratorControls.m_amountModel.value()) * 0.001f * m_sampleRate;
const int type = typeBuf ? typeBuf->value(f) : m_disintegratorControls.m_typeModel.value();
const float freq = freqBuf ? freqBuf->value(f) : m_disintegratorControls.m_freqModel.value();
sample_t s[2] = {buf[f][0], buf[f][1]};
}
if(m_needsUpdate || m_disintegratorControls.m_lowCutModel.isValueChanged())
{
m_hp->calcFilterCoeffs(m_disintegratorControls.m_lowCutModel.value(), 0.5);
}
m_needsUpdate = false;
// Increment buffer read point
++m_inBufLoc;
if (m_inBufLoc >= m_bufferSize)
{
m_inBufLoc = 0;
}
for (fpp_t f = 0; f < frames; ++f)
{
const float amount = (amountBuf ? amountBuf->value(f) : m_disintegratorControls.m_amountModel.value()) * 0.001f * m_sampleRate;
const int type = typeBuf ? typeBuf->value(f) : m_disintegratorControls.m_typeModel.value();
const float freq = freqBuf ? freqBuf->value(f) : m_disintegratorControls.m_freqModel.value();
// Write dry input to buffer
m_inBuf[0][m_inBufLoc] = s[0];
m_inBuf[1][m_inBufLoc] = s[1];
sample_t s[2] = {buf[f][0], buf[f][1]};
float newInBufLoc[2] = {0, 0};
float newInBufLocFrac[2] = {0, 0};
// Increment buffer read point
++m_inBufLoc;
if (m_inBufLoc >= m_bufferSize)
{
m_inBufLoc = 0;
}
// Generate white noise or sine wave, apply filters, subtract the
// result from the buffer read point and store in a variable.
sampleFrame delayModInput = {0, 0};
switch (type)
{
case 0://Mono Noise
{
delayModInput[0] = fast_rand() / (float)FAST_RAND_MAX * 2.f - 1.f;
delayModInput[1] = delayModInput[0];
break;
}
case 1://Stereo Noise
{
delayModInput[0] = fast_rand() / (float)FAST_RAND_MAX * 2.f - 1.f;
delayModInput[1] = fast_rand() / (float)FAST_RAND_MAX * 2.f - 1.f;
break;
}
case 2://Sine Wave
{
m_sineLoc = fmod(m_sineLoc + (freq * m_2PiOverSR), F_2PI);
delayModInput[0] = sin(m_sineLoc);
delayModInput[1] = delayModInput[0];
break;
}
case 3:// Self-Modulation
{
delayModInput[0] = qBound(-1.f, s[0], 1.f);
delayModInput[1] = qBound(-1.f, s[1], 1.f);
break;
}
}
// Write dry input to buffer
m_inBuf[0][m_inBufLoc] = s[0];
m_inBuf[1][m_inBufLoc] = s[1];
for (int i = 0; i < 2; ++i)
{
newInBufLoc[i] = delayModInput[i];
float newInBufLoc[2] = {0, 0};
float newInBufLocFrac[2] = {0, 0};
if (type != 2)// Sine mode doesn't use filters
{
newInBufLoc[i] = m_hp->update(newInBufLoc[i], i);
newInBufLoc[i] = m_lp->update(newInBufLoc[i], i);
}
// Generate white noise or sine wave, apply filters, subtract the
// result from the buffer read point and store in a variable.
SampleFrame delayModInput;
switch (type)
{
case 0://Mono Noise
{
delayModInput[0] = fastRand(2.0f) - 1.0f;
delayModInput[1] = delayModInput[0];
break;
}
case 1://Stereo Noise
{
delayModInput[0] = fastRand(2.0f) - 1.0f;
delayModInput[1] = fastRand(2.0f) - 1.0f;
break;
}
case 2://Sine Wave
{
m_sineLoc = fmod(m_sineLoc + (freq * m_2PiOverSR), 2.0f * std::numbers::pi_v<float>);
delayModInput[0] = sin(m_sineLoc);
delayModInput[1] = delayModInput[0];
break;
}
case 3:// Self-Modulation
{
delayModInput[0] = qBound(-1.f, s[0], 1.f);
delayModInput[1] = qBound(-1.f, s[1], 1.f);
break;
}
}
newInBufLoc[i] = (newInBufLoc[i] + 1) * 0.5f;
for (int i = 0; i < 2; ++i)
{
newInBufLoc[i] = delayModInput[i];
newInBufLoc[i] = realfmod(m_inBufLoc - newInBufLoc[i] * amount, m_bufferSize);
if (type != 2)// Sine mode doesn't use filters
{
newInBufLoc[i] = m_hp->update(newInBufLoc[i], i);
newInBufLoc[i] = m_lp->update(newInBufLoc[i], i);
}
// Distance between samples
newInBufLocFrac[i] = fmod(newInBufLoc[i], 1);
}
newInBufLoc[i] = (newInBufLoc[i] + 1) * 0.5f;
newInBufLoc[i] = realfmod(m_inBufLoc - newInBufLoc[i] * amount, m_bufferSize);
for (int i = 0; i < 2; ++i)
{
if (newInBufLocFrac[i] == 0)
{
s[i] = m_inBuf[i][newInBufLoc[i]];
}
else
{
if (newInBufLoc[i] < m_bufferSize - 1)
{
s[i] = m_inBuf[i][floor(newInBufLoc[i])] * (1 - newInBufLocFrac[i]) + m_inBuf[i][ceil(newInBufLoc[i])] * newInBufLocFrac[i];
}
else// For when the interpolation wraps around to the beginning of the buffer
{
s[i] = m_inBuf[i][m_bufferSize - 1] * (1 - newInBufLocFrac[i]) + m_inBuf[i][0] * newInBufLocFrac[i];
}
}
}
// Distance between samples
newInBufLocFrac[i] = fmod(newInBufLoc[i], 1);
}
buf[f][0] = d * buf[f][0] + w * s[0];
buf[f][1] = d * buf[f][1] + w * s[1];
outSum += buf[f][0] + buf[f][1];
}
checkGate(outSum / frames);
for (int i = 0; i < 2; ++i)
{
if (newInBufLocFrac[i] == 0)
{
s[i] = m_inBuf[i][newInBufLoc[i]];
}
else
{
if (newInBufLoc[i] < m_bufferSize - 1)
{
s[i] = m_inBuf[i][floor(newInBufLoc[i])] * (1 - newInBufLocFrac[i]) + m_inBuf[i][ceil(newInBufLoc[i])] * newInBufLocFrac[i];
}
else// For when the interpolation wraps around to the beginning of the buffer
{
s[i] = m_inBuf[i][m_bufferSize - 1] * (1 - newInBufLocFrac[i]) + m_inBuf[i][0] * newInBufLocFrac[i];
}
}
}
return isRunning();
buf[f][0] = d * buf[f][0] + w * s[0];
buf[f][1] = d * buf[f][1] + w * s[1];
}
return ProcessStatus::ContinueIfNotQuiet;
}
@@ -213,16 +209,16 @@ bool DisintegratorEffect::processAudioBuffer(sampleFrame* buf, const fpp_t frame
// Handles negative values properly, unlike fmod.
inline float DisintegratorEffect::realfmod(float k, float n)
{
float r = fmod(k, n);
return r < 0 ? r + n : r;
float r = fmod(k, n);
return r < 0 ? r + n : r;
}
void DisintegratorEffect::clearFilterHistories()
{
m_lp->clearHistory();
m_hp->clearHistory();
m_lp->clearHistory();
m_hp->clearHistory();
}
@@ -233,8 +229,9 @@ extern "C"
// necessary for getting instance out of shared lib
PLUGIN_EXPORT Plugin * lmms_plugin_main(Model* parent, void* data)
{
return new DisintegratorEffect(parent, static_cast<const Plugin::Descriptor::SubPluginFeatures::Key *>(data));
return new DisintegratorEffect(parent, static_cast<const Plugin::Descriptor::SubPluginFeatures::Key *>(data));
}
}
} // namespace lmms

View File

@@ -32,43 +32,47 @@
#include "Effect.h"
#include "ValueBuffer.h"
namespace lmms
{
class DisintegratorEffect : public Effect
{
public:
DisintegratorEffect(Model* parent, const Descriptor::SubPluginFeatures::Key* key);
bool processAudioBuffer(sampleFrame* buf, const fpp_t frames) override;
DisintegratorEffect(Model* parent, const Descriptor::SubPluginFeatures::Key* key);
ProcessStatus processImpl(SampleFrame* buf, const fpp_t frames) override;
EffectControls* controls() override
{
return &m_disintegratorControls;
}
EffectControls* controls() override
{
return &m_disintegratorControls;
}
void sampleRateChanged();
void sampleRateChanged();
inline float realfmod(float k, float n);
inline float realfmod(float k, float n);
void clearFilterHistories();
void clearFilterHistories();
private:
DisintegratorControls m_disintegratorControls;
DisintegratorControls m_disintegratorControls;
std::vector<float> m_inBuf[2];
int m_inBufLoc = 0;
std::vector<float> m_inBuf[2];
int m_inBufLoc = 0;
float m_sineLoc = 0;
float m_sineLoc = 0;
BasicFilters<2> * m_lp;
BasicFilters<2> * m_hp;
bool m_needsUpdate;
BasicFilters<2> * m_lp;
BasicFilters<2> * m_hp;
bool m_needsUpdate;
float m_sampleRate;
float m_2PiOverSR;
float m_sampleRateMult;
int m_bufferSize = 500;
float m_sampleRate;
float m_2PiOverSR;
float m_sampleRateMult;
int m_bufferSize = 500;
friend class DisintegratorControls;
friend class DisintegratorControls;
} ;
} // namespace lmms
#endif

View File

@@ -27,54 +27,58 @@
#include "DisintegratorControlDialog.h"
#include "DisintegratorControls.h"
#include "ComboBox.h"
#include "embed.h"
#include "gui_templates.h"
#include "Knob.h"
namespace lmms::gui
{
DisintegratorControlDialog::DisintegratorControlDialog(DisintegratorControls* controls) :
EffectControlDialog(controls),
m_controls(controls)
EffectControlDialog(controls),
m_controls(controls)
{
setAutoFillBackground(true);
QPalette pal;
pal.setBrush(backgroundRole(), PLUGIN_NAME::getIconPixmap("artwork"));
setPalette(pal);
setFixedSize(179, 97);
setAutoFillBackground(true);
QPalette pal;
pal.setBrush(backgroundRole(), PLUGIN_NAME::getIconPixmap("artwork"));
setPalette(pal);
setFixedSize(179, 97);
m_lowCutKnob = new Knob(knobBright_26, this);
m_lowCutKnob -> move(70, 10);
m_lowCutKnob->setModel(&m_controls->m_lowCutModel);
m_lowCutKnob->setLabel(tr("LOW CUT"));
m_lowCutKnob->setHintText(tr("Low Cut:"), " Hz");
m_lowCutKnob = new Knob(KnobType::Bright26, this);
m_lowCutKnob -> move(70, 10);
m_lowCutKnob->setModel(&m_controls->m_lowCutModel);
m_lowCutKnob->setLabel(tr("LOW CUT"));
m_lowCutKnob->setHintText(tr("Low Cut:"), " Hz");
m_highCutKnob = new Knob(knobBright_26, this);
m_highCutKnob -> move(125, 10);
m_highCutKnob->setModel(&m_controls->m_highCutModel);
m_highCutKnob->setLabel(tr("HIGH CUT"));
m_highCutKnob->setHintText(tr("High Cut:"), " Hz");
m_highCutKnob = new Knob(KnobType::Bright26, this);
m_highCutKnob -> move(125, 10);
m_highCutKnob->setModel(&m_controls->m_highCutModel);
m_highCutKnob->setLabel(tr("HIGH CUT"));
m_highCutKnob->setHintText(tr("High Cut:"), " Hz");
m_amountKnob = new Knob(knobBright_26, this);
m_amountKnob -> move(15, 10);
m_amountKnob -> setVolumeKnob(true);
m_amountKnob->setModel(&m_controls->m_amountModel);
m_amountKnob->setLabel(tr("AMOUNT"));
m_amountKnob->setHintText(tr("Amount:"), " ms");
m_amountKnob = new Knob(KnobType::Bright26, this);
m_amountKnob -> move(15, 10);
m_amountKnob -> setVolumeKnob(true);
m_amountKnob->setModel(&m_controls->m_amountModel);
m_amountKnob->setLabel(tr("AMOUNT"));
m_amountKnob->setHintText(tr("Amount:"), " ms");
m_typeBox = new ComboBox(this);
m_typeBox->setGeometry(1000, 5, 149, 22);
m_typeBox->setFont(pointSize<8>(m_typeBox->font()));
m_typeBox->move(14, 65);
m_typeBox->setModel(&m_controls->m_typeModel);
m_typeBox = new ComboBox(this);
m_typeBox->setGeometry(1000, 5, 149, 22);
QFont f = m_typeBox->font();
f.setPointSize(8);
m_typeBox->setFont(f);
m_typeBox->move(14, 65);
m_typeBox->setModel(&m_controls->m_typeModel);
m_freqKnob = new Knob(knobBright_26, this);
m_freqKnob -> move(132, 10);
m_freqKnob->setModel(&m_controls->m_freqModel);
m_freqKnob->setLabel(tr("FREQ"));
m_freqKnob->setHintText(tr("Frequency:"), " Hz");
m_freqKnob = new Knob(KnobType::Bright26, this);
m_freqKnob -> move(132, 10);
m_freqKnob->setModel(&m_controls->m_freqModel);
m_freqKnob->setLabel(tr("FREQ"));
m_freqKnob->setHintText(tr("Frequency:"), " Hz");
connect(&m_controls->m_typeModel, SIGNAL(dataChanged()), this, SLOT(updateKnobVisibility()));
emit m_controls->m_typeModel.dataChanged();// Needed to update knobs when view is opened
connect(&m_controls->m_typeModel, SIGNAL(dataChanged()), this, SLOT(updateKnobVisibility()));
emit m_controls->m_typeModel.dataChanged();// Needed to update knobs when view is opened
}
@@ -82,16 +86,18 @@ DisintegratorControlDialog::DisintegratorControlDialog(DisintegratorControls* co
frequency knobs depending on the modulation type. */
void DisintegratorControlDialog::updateKnobVisibility()
{
if (m_controls->m_typeModel.value() == 2)// Sine Mode
{
m_lowCutKnob->hide();
m_highCutKnob->hide();
m_freqKnob->show();
}
else
{
m_lowCutKnob->show();
m_highCutKnob->show();
m_freqKnob->hide();
}
if (m_controls->m_typeModel.value() == 2)// Sine Mode
{
m_lowCutKnob->hide();
m_highCutKnob->hide();
m_freqKnob->show();
}
else
{
m_lowCutKnob->show();
m_highCutKnob->show();
m_freqKnob->hide();
}
}
} // namespace lmms::gui

View File

@@ -25,32 +25,41 @@
#ifndef DISINTEGRATOR_CONTROL_DIALOG_H
#define DISINTEGRATOR_CONTROL_DIALOG_H
#include "ComboBox.h"
#include "EffectControlDialog.h"
#include "Knob.h"
namespace lmms
{
class DisintegratorControls;
namespace gui
{
class ComboBox;
class Knob;
class DisintegratorControlDialog : public EffectControlDialog
{
Q_OBJECT
Q_OBJECT
public:
DisintegratorControlDialog(DisintegratorControls* controls);
DisintegratorControls * m_controls;
DisintegratorControlDialog(DisintegratorControls* controls);
DisintegratorControls * m_controls;
private slots:
void updateKnobVisibility();
void updateKnobVisibility();
private:
Knob * m_lowCutKnob;
Knob * m_highCutKnob;
Knob * m_amountKnob;
ComboBox * m_typeBox;
Knob * m_freqKnob;
Knob * m_lowCutKnob;
Knob * m_highCutKnob;
Knob * m_amountKnob;
ComboBox * m_typeBox;
Knob * m_freqKnob;
friend class DisintegratorControls;
friend class DisintegratorControls;
};
} // namespace gui
} // namespace lmms
#endif

View File

@@ -31,57 +31,61 @@
#include "Engine.h"
#include "Song.h"
namespace lmms
{
DisintegratorControls::DisintegratorControls(DisintegratorEffect* effect) :
EffectControls(effect),
m_effect(effect),
m_lowCutModel(20.0f, 20.0f, 20000.0f, 0.01f, this, tr("Low Cut Frequency")),
m_highCutModel(20000.0f, 20.0f, 20000.0f, 0.01f, this, tr("High Cut Frequency")),
m_amountModel(1.6f, 0.0f, 10.0f, 0.001f, this, tr("Amount")),
m_typeModel(this, tr("Type")),
m_freqModel(100.0f, 1.0f, 21050.0f, 0.01f, this, tr("Frequency"))
EffectControls(effect),
m_effect(effect),
m_lowCutModel(20.0f, 20.0f, 20000.0f, 0.01f, this, tr("Low Cut Frequency")),
m_highCutModel(20000.0f, 20.0f, 20000.0f, 0.01f, this, tr("High Cut Frequency")),
m_amountModel(1.6f, 0.0f, 10.0f, 0.001f, this, tr("Amount")),
m_typeModel(this, tr("Type")),
m_freqModel(100.0f, 1.0f, 21050.0f, 0.01f, this, tr("Frequency"))
{
// All of these are much easier to tweak when logarithmic
m_lowCutModel.setScaleLogarithmic(true);
m_highCutModel.setScaleLogarithmic(true);
m_amountModel.setScaleLogarithmic(true);
m_freqModel.setScaleLogarithmic(true);
// All of these are much easier to tweak when logarithmic
m_lowCutModel.setScaleLogarithmic(true);
m_highCutModel.setScaleLogarithmic(true);
m_amountModel.setScaleLogarithmic(true);
m_freqModel.setScaleLogarithmic(true);
m_typeModel.addItem(tr("Mono Noise"));
m_typeModel.addItem(tr("Stereo Noise"));
m_typeModel.addItem(tr("Sine Wave"));
m_typeModel.addItem(tr("Self-Modulation"));
m_typeModel.addItem(tr("Mono Noise"));
m_typeModel.addItem(tr("Stereo Noise"));
m_typeModel.addItem(tr("Sine Wave"));
m_typeModel.addItem(tr("Self-Modulation"));
connect(Engine::mixer(), SIGNAL(sampleRateChanged()), this, SLOT(sampleRateChanged()));
connect(Engine::audioEngine(), SIGNAL(sampleRateChanged()), this, SLOT(sampleRateChanged()));
}
void DisintegratorControls::saveSettings(QDomDocument& doc, QDomElement& _this)
{
m_lowCutModel.saveSettings(doc, _this, "lowCut");
m_highCutModel.saveSettings(doc, _this, "highCut");
m_amountModel.saveSettings(doc, _this, "amount");
m_typeModel.saveSettings(doc, _this, "type");
m_freqModel.saveSettings(doc, _this, "freq");
m_lowCutModel.saveSettings(doc, _this, "lowCut");
m_highCutModel.saveSettings(doc, _this, "highCut");
m_amountModel.saveSettings(doc, _this, "amount");
m_typeModel.saveSettings(doc, _this, "type");
m_freqModel.saveSettings(doc, _this, "freq");
}
void DisintegratorControls::loadSettings(const QDomElement& _this)
{
m_lowCutModel.loadSettings(_this, "lowCut");
m_highCutModel.loadSettings(_this, "highCut");
m_amountModel.loadSettings(_this, "amount");
m_typeModel.loadSettings(_this, "type");
m_freqModel.loadSettings(_this, "freq");
m_lowCutModel.loadSettings(_this, "lowCut");
m_highCutModel.loadSettings(_this, "highCut");
m_amountModel.loadSettings(_this, "amount");
m_typeModel.loadSettings(_this, "type");
m_freqModel.loadSettings(_this, "freq");
m_effect->m_needsUpdate = true;
m_effect->clearFilterHistories();
m_effect->m_needsUpdate = true;
m_effect->clearFilterHistories();
}
void DisintegratorControls::sampleRateChanged()
{
m_effect->sampleRateChanged();
m_effect->sampleRateChanged();
}
} // namespace lmms

View File

@@ -27,51 +27,54 @@
#include "DisintegratorControlDialog.h"
#include "ComboBox.h"
#include "ComboBoxModel.h"
#include "EffectControls.h"
#include "Knob.h"
namespace lmms
{
class DisintegratorEffect;
class DisintegratorControls : public EffectControls
{
Q_OBJECT
Q_OBJECT
public:
DisintegratorControls(DisintegratorEffect* effect);
DisintegratorControls(DisintegratorEffect* effect);
void saveSettings(QDomDocument & _doc, QDomElement & _parent) override;
void loadSettings(const QDomElement & _this) override;
inline QString nodeName() const override
{
return "DisintegratorControls";
}
void saveSettings(QDomDocument & _doc, QDomElement & _parent) override;
void loadSettings(const QDomElement & _this) override;
inline QString nodeName() const override
{
return "DisintegratorControls";
}
int controlCount() override
{
return 5;
}
int controlCount() override
{
return 5;
}
EffectControlDialog* createView() override
{
return new DisintegratorControlDialog(this);
}
gui::EffectControlDialog* createView() override
{
return new gui::DisintegratorControlDialog(this);
}
private slots:
void sampleRateChanged();
void sampleRateChanged();
private:
DisintegratorEffect* m_effect;
DisintegratorEffect* m_effect;
FloatModel m_lowCutModel;
FloatModel m_highCutModel;
FloatModel m_amountModel;
ComboBoxModel m_typeModel;
FloatModel m_freqModel;
FloatModel m_lowCutModel;
FloatModel m_highCutModel;
FloatModel m_amountModel;
ComboBoxModel m_typeModel;
FloatModel m_freqModel;
friend class DisintegratorControlDialog;
friend class DisintegratorEffect;
friend class gui::DisintegratorControlDialog;
friend class DisintegratorEffect;
} ;
} // namespace lmms
#endif