From e83d44a56e6483b25f3a19bfb2558bacdfe1b4f4 Mon Sep 17 00:00:00 2001 From: root Date: Thu, 29 Aug 2019 19:59:03 -0600 Subject: [PATCH 01/20] Add Disintegrator effect --- plugins/CMakeLists.txt | 1 + plugins/Disintegrator/CMakeLists.txt | 3 + plugins/Disintegrator/Disintegrator.cpp | 279 ++++++++++++++++++ plugins/Disintegrator/Disintegrator.h | 84 ++++++ .../DisintegratorControlDialog.cpp | 97 ++++++ .../DisintegratorControlDialog.h | 60 ++++ .../Disintegrator/DisintegratorControls.cpp | 73 +++++ plugins/Disintegrator/DisintegratorControls.h | 79 +++++ plugins/Disintegrator/OLD 1/CMakeLists.txt | 3 + plugins/Disintegrator/OLD 1/Disintegrator.cpp | 245 +++++++++++++++ plugins/Disintegrator/OLD 1/Disintegrator.h | 67 +++++ .../OLD 1/DisintegratorControlDialog.cpp | 70 +++++ .../OLD 1/DisintegratorControlDialog.h | 45 +++ .../OLD 1/DisintegratorControls.cpp | 69 +++++ .../OLD 1/DisintegratorControls.h | 78 +++++ plugins/Disintegrator/OLD 1/artwork.png | Bin 0 -> 7739 bytes plugins/Disintegrator/OLD 1/logo.png | Bin 0 -> 774 bytes plugins/Disintegrator/artwork.png | Bin 0 -> 7739 bytes plugins/Disintegrator/logo.png | Bin 0 -> 774 bytes 19 files changed, 1253 insertions(+) create mode 100644 plugins/Disintegrator/CMakeLists.txt create mode 100644 plugins/Disintegrator/Disintegrator.cpp create mode 100644 plugins/Disintegrator/Disintegrator.h create mode 100644 plugins/Disintegrator/DisintegratorControlDialog.cpp create mode 100644 plugins/Disintegrator/DisintegratorControlDialog.h create mode 100644 plugins/Disintegrator/DisintegratorControls.cpp create mode 100644 plugins/Disintegrator/DisintegratorControls.h create mode 100644 plugins/Disintegrator/OLD 1/CMakeLists.txt create mode 100644 plugins/Disintegrator/OLD 1/Disintegrator.cpp create mode 100644 plugins/Disintegrator/OLD 1/Disintegrator.h create mode 100644 plugins/Disintegrator/OLD 1/DisintegratorControlDialog.cpp create mode 100644 plugins/Disintegrator/OLD 1/DisintegratorControlDialog.h create mode 100644 plugins/Disintegrator/OLD 1/DisintegratorControls.cpp create mode 100644 plugins/Disintegrator/OLD 1/DisintegratorControls.h create mode 100644 plugins/Disintegrator/OLD 1/artwork.png create mode 100644 plugins/Disintegrator/OLD 1/logo.png create mode 100644 plugins/Disintegrator/artwork.png create mode 100644 plugins/Disintegrator/logo.png diff --git a/plugins/CMakeLists.txt b/plugins/CMakeLists.txt index 4f139f8b3..e12783bab 100644 --- a/plugins/CMakeLists.txt +++ b/plugins/CMakeLists.txt @@ -49,6 +49,7 @@ IF("${PLUGIN_LIST}" STREQUAL "") carlarack CrossoverEQ Delay + Disintegrator DualFilter dynamics_processor Eq diff --git a/plugins/Disintegrator/CMakeLists.txt b/plugins/Disintegrator/CMakeLists.txt new file mode 100644 index 000000000..7642f8138 --- /dev/null +++ b/plugins/Disintegrator/CMakeLists.txt @@ -0,0 +1,3 @@ +INCLUDE(BuildPlugin) + +BUILD_PLUGIN(disintegrator Disintegrator.cpp DisintegratorControls.cpp DisintegratorControlDialog.cpp MOCFILES DisintegratorControls.h DisintegratorControlDialog.h EMBEDDED_RESOURCES artwork.png logo.png) diff --git a/plugins/Disintegrator/Disintegrator.cpp b/plugins/Disintegrator/Disintegrator.cpp new file mode 100644 index 000000000..6531f9468 --- /dev/null +++ b/plugins/Disintegrator/Disintegrator.cpp @@ -0,0 +1,279 @@ +/* + * Disintegrator.cpp + * + * Copyright (c) 2019 Lost Robot + * + * This file is part of LMMS - https://lmms.io + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public + * License along with this program (see COPYING); if not, write to the + * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301 USA. + * + */ + +#include "Disintegrator.h" + +#include "embed.h" +#include "lmms_math.h" +#include "plugin_export.h" + +extern "C" +{ + +Plugin::Descriptor PLUGIN_EXPORT disintegrator_plugin_descriptor = +{ + STRINGIFY(PLUGIN_NAME), + "Disintegrator", + QT_TRANSLATE_NOOP("pluginBrowser", "A delay modulation effect for creating very aggressive digital distortion."), + "Lost Robot ", + 0x0100, + Plugin::Effect, + new PluginPixmapLoader("logo"), + NULL, + NULL +} ; + +} + + + +DisintegratorEffect::DisintegratorEffect(Model* parent, const Descriptor::SubPluginFeatures::Key* key) : + Effect(&disintegrator_plugin_descriptor, parent, key), + m_disintegratorControls(this) +{ + for (int a = 0; a < 200; ++a) + { + for (int b = 0; b < 2; ++b) + { + m_inBuf[b].push_back(0); + } + } +} + + + + +DisintegratorEffect::~DisintegratorEffect() +{ +} + + + + +bool DisintegratorEffect::processAudioBuffer(sampleFrame* buf, const fpp_t frames) +{ + if (!isEnabled() || !isRunning ()) + { + return false; + } + + double outSum = 0.0; + const float d = dryLevel(); + const float w = wetLevel(); + + const ValueBuffer * lowCutBuf = m_disintegratorControls.m_lowCutModel.valueBuffer(); + const ValueBuffer * highCutBuf = m_disintegratorControls.m_highCutModel.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(); + + sample_rate_t sample_rate = Engine::mixer()->processingSampleRate(); + + for (fpp_t f = 0; f < frames; ++f) + { + const float lowCut = lowCutBuf ? lowCutBuf->value(f) : m_disintegratorControls.m_lowCutModel.value(); + const float highCut = highCutBuf ? highCutBuf->value(f) : m_disintegratorControls.m_highCutModel.value(); + const float amount = amountBuf ? amountBuf->value(f) : m_disintegratorControls.m_amountModel.value(); + const int type = typeBuf ? typeBuf->value(f) : m_disintegratorControls.m_typeModel.value(); + const float freq = freqBuf ? freqBuf->value(f) : m_disintegratorControls.m_freqModel.value(); + + outSum += buf[f][0]*buf[f][0] + buf[f][1]*buf[f][1]; + + sample_t s[2] = {buf[f][0], buf[f][1]}; + + ++m_inBufLoc; + if (m_inBufLoc >= 200) + { + m_inBufLoc = 0; + } + + m_inBuf[0][m_inBufLoc] = s[0]; + m_inBuf[1][m_inBufLoc] = s[1]; + + float newInBufLoc[2] = {0, 0}; + float newInBufLocFrac[2] = {0, 0}; + switch (type) + { + case 0:// Mono Noise + { + newInBufLoc[0] = fast_rand() / (float)FAST_RAND_MAX; + + calcHighpassFilter(newInBufLoc[0], newInBufLoc[0], 0, lowCut, 0.707, sample_rate); + calcLowpassFilter(newInBufLoc[0], newInBufLoc[0], 0, highCut, 0.707, sample_rate); + + newInBufLoc[0] = realfmod(m_inBufLoc - newInBufLoc[0] * amount, 200); + newInBufLoc[1] = newInBufLoc[0]; + + newInBufLocFrac[0] = fmod(newInBufLoc[0], 1); + newInBufLocFrac[1] = newInBufLocFrac[0]; + + break; + } + case 1:// Stereo Noise + { + newInBufLoc[0] = fast_rand() / (float)FAST_RAND_MAX; + newInBufLoc[1] = fast_rand() / (float)FAST_RAND_MAX; + + calcHighpassFilter(newInBufLoc[0], newInBufLoc[0], 0, lowCut, 0.707, sample_rate); + calcHighpassFilter(newInBufLoc[1], newInBufLoc[1], 1, lowCut, 0.707, sample_rate); + calcLowpassFilter(newInBufLoc[0], newInBufLoc[0], 0, highCut, 0.707, sample_rate); + calcLowpassFilter(newInBufLoc[1], newInBufLoc[1], 1, highCut, 0.707, sample_rate); + + newInBufLoc[0] = realfmod(m_inBufLoc - newInBufLoc[0] * amount, 200); + newInBufLoc[1] = realfmod(m_inBufLoc - newInBufLoc[1] * amount, 200); + + newInBufLocFrac[0] = fmod(newInBufLoc[0], 1); + newInBufLocFrac[1] = fmod(newInBufLoc[1], 1); + + break; + } + case 2:// Sine Wave + { + m_sineLoc = fmod(m_sineLoc + (freq / (float)sample_rate * F_2PI), F_2PI); + + newInBufLoc[0] = (sin(m_sineLoc) + 1) * 0.5f; + + newInBufLoc[0] = realfmod(m_inBufLoc - newInBufLoc[0] * amount, 200); + newInBufLoc[1] = newInBufLoc[0]; + + newInBufLocFrac[0] = fmod(newInBufLoc[0], 1); + newInBufLocFrac[1] = newInBufLocFrac[0]; + + break; + } + } + + for (int b = 0; b < 2; ++b) + { + if (fmod(newInBufLoc[b], 1) == 0) + { + s[b] = m_inBuf[b][newInBufLoc[b]]; + } + else + { + if (newInBufLoc[b] < 199) + { + s[b] = m_inBuf[b][floor(newInBufLoc[b])] * (1 - newInBufLocFrac[b]) + m_inBuf[b][ceil(newInBufLoc[b])] * newInBufLocFrac[b]; + } + else + { + s[b] = m_inBuf[b][199] * (1 - newInBufLocFrac[b]) + m_inBuf[b][0] * newInBufLocFrac[b]; + } + } + } + + buf[f][0] = d * buf[f][0] + w * s[0]; + buf[f][1] = d * buf[f][1] + w * s[1]; + } + + checkGate(outSum / frames); + + return isRunning(); +} + + + +inline void DisintegratorEffect::calcLowpassFilter(sample_t &outSamp, sample_t inSamp, int which, float lpCutoff, float resonance, sample_rate_t Fs) +{ + if (m_prevLPCutoff[which] != lpCutoff) + { + m_prevLPCutoff[which] = lpCutoff; + const float w0 = D_2PI * lpCutoff / Fs; + const float tempCosW0 = cos(w0); + const float alpha = sin(w0) / 0.3535f; + + m_LPa0 = 1 + alpha; + m_LPb0 = (1 - tempCosW0) * 0.5f; + m_LPb1 = 1 - tempCosW0; + m_LPa1 = -(2 * tempCosW0); + m_LPa2 = 1 - alpha; + } + + m_filtLPY[which][0] = (m_LPb0 * (inSamp + m_filtLPX[which][2]) + m_LPb1 * m_filtLPX[which][1] - m_LPa1 * m_filtLPY[which][1] - m_LPa2 * m_filtLPY[which][2]) / m_LPa0; + + m_filtLPX[which][2] = m_filtLPX[which][1]; + m_filtLPX[which][1] = inSamp; + m_filtLPY[which][2] = m_filtLPY[which][1]; + m_filtLPY[which][1] = m_filtLPY[which][0]; + + outSamp = m_filtLPY[which][0]; +} + + + +inline void DisintegratorEffect::calcHighpassFilter(sample_t &outSamp, sample_t inSamp, int which, float hpCutoff, float resonance, sample_rate_t Fs) +{ + if (m_prevHPCutoff[which] != hpCutoff) + { + m_prevHPCutoff[which] = hpCutoff; + const float w0 = D_2PI * hpCutoff / Fs; + const float tempCosW0 = cos(w0); + const float alpha = sin(w0) / 0.3535f; + + m_HPa0 = 1 + alpha; + m_HPb0 = (1 + tempCosW0) * 0.5f; + m_HPb1 = -(1 + tempCosW0); + m_HPa1 = -2 * tempCosW0; + m_HPa2 = 1 - alpha; + } + + m_filtHPY[which][0] = (m_HPb0 * (inSamp + m_filtHPX[which][2]) + m_HPb1 * m_filtHPX[which][1] - m_HPa1 * m_filtHPY[which][1] - m_HPa2 * m_filtHPY[which][2]) / m_HPa0; + + m_filtHPX[which][2] = m_filtHPX[which][1]; + m_filtHPX[which][1] = inSamp; + m_filtHPY[which][2] = m_filtHPY[which][1]; + m_filtHPY[which][1] = m_filtHPY[which][0]; + + outSamp = m_filtHPY[which][0]; +} + + + +// Takes input of original Hz and the number of cents to detune it by, and returns the detuned result in Hz. +inline float DisintegratorEffect::detuneWithOctaves(float pitchValue, float detuneValue) +{ + return pitchValue * std::exp2(detuneValue); +} + + + +// Handles negative values properly, unlike fmod. +inline float DisintegratorEffect::realfmod(float k, float n) +{ + return ((k = fmod(k,n)) < 0) ? k+n : k; +} + + + +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(data)); +} + +} + diff --git a/plugins/Disintegrator/Disintegrator.h b/plugins/Disintegrator/Disintegrator.h new file mode 100644 index 000000000..a206e4304 --- /dev/null +++ b/plugins/Disintegrator/Disintegrator.h @@ -0,0 +1,84 @@ +/* + * Disintegrator.h + * + * Copyright (c) 2019 Lost Robot + * + * This file is part of LMMS - https://lmms.io + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public + * License along with this program (see COPYING); if not, write to the + * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301 USA. + * + */ + + +#ifndef DISINTEGRATOR_H +#define DISINTEGRATOR_H + +#include "DisintegratorControls.h" + +#include "Effect.h" +#include "ValueBuffer.h" + +class DisintegratorEffect : public Effect +{ +public: + DisintegratorEffect(Model* parent, const Descriptor::SubPluginFeatures::Key* key); + virtual ~DisintegratorEffect(); + virtual bool processAudioBuffer(sampleFrame* buf, const fpp_t frames); + + virtual EffectControls* controls() + { + return &m_disintegratorControls; + } + + inline float realfmod(float k, float n); + inline float detuneWithOctaves(float pitchValue, float detuneValue); + + inline void calcLowpassFilter(sample_t &outSamp, sample_t inSamp, int which, float lpCutoff, float resonance, sample_rate_t Fs); + inline void calcHighpassFilter(sample_t &outSamp, sample_t inSamp, int which, float lpCutoff, float resonance, sample_rate_t Fs); + + float m_filtLPX[2][3] = {{0}};// [filter number][samples back in time] + float m_filtLPY[2][3] = {{0}};// [filter number][samples back in time] + float m_prevLPCutoff[2] = {0}; + + float m_LPa0; + float m_LPb0; + float m_LPb1; + float m_LPa1; + float m_LPa2; + + float m_filtHPX[2][3] = {{0}};// [filter number][samples back in time] + float m_filtHPY[2][3] = {{0}};// [filter number][samples back in time] + float m_prevHPCutoff[2] = {0}; + + float m_HPa0; + float m_HPb0; + float m_HPb1; + float m_HPa1; + float m_HPa2; + +private: + DisintegratorControls m_disintegratorControls; + + std::vector m_inBuf[2]; + int m_inBufLoc = 0; + + float m_sineLoc = 0; + + friend class DisintegratorControls; + +} ; + +#endif diff --git a/plugins/Disintegrator/DisintegratorControlDialog.cpp b/plugins/Disintegrator/DisintegratorControlDialog.cpp new file mode 100644 index 000000000..a680f3c33 --- /dev/null +++ b/plugins/Disintegrator/DisintegratorControlDialog.cpp @@ -0,0 +1,97 @@ +/* + * DisintegratorControlDialog.cpp + * + * Copyright (c) 2019 Lost Robot + * + * This file is part of LMMS - https://lmms.io + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public + * License along with this program (see COPYING); if not, write to the + * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301 USA. + * + */ + +#include + +#include "DisintegratorControlDialog.h" +#include "DisintegratorControls.h" + +#include "embed.h" +#include "gui_templates.h" + + + +DisintegratorControlDialog::DisintegratorControlDialog(DisintegratorControls* controls) : + EffectControlDialog(controls) +{ + m_controls = controls; + + 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_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_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:"), " samples"); + + 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_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"); + + connect(&m_controls->m_typeModel, SIGNAL(dataChanged()), this, SLOT(updateKnobVisibility())); + emit m_controls->m_typeModel.dataChanged();// Needed to update knobs when view is opened +} + + + +void DisintegratorControlDialog::updateKnobVisibility() +{ + if (m_controls->m_typeModel.value() == 2) + { + m_lowCutKnob->hide(); + m_highCutKnob->hide(); + m_freqKnob->show(); + } + else + { + m_lowCutKnob->show(); + m_highCutKnob->show(); + m_freqKnob->hide(); + } +} diff --git a/plugins/Disintegrator/DisintegratorControlDialog.h b/plugins/Disintegrator/DisintegratorControlDialog.h new file mode 100644 index 000000000..2c9938318 --- /dev/null +++ b/plugins/Disintegrator/DisintegratorControlDialog.h @@ -0,0 +1,60 @@ +/* + * DisintegratorControlDialog.h + * + * Copyright (c) 2019 Lost Robot + * + * This file is part of LMMS - https://lmms.io + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public + * License along with this program (see COPYING); if not, write to the + * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301 USA. + * + */ + +#ifndef DISINTEGRATOR_CONTROL_DIALOG_H +#define DISINTEGRATOR_CONTROL_DIALOG_H + +#include "ComboBox.h" +#include "EffectControlDialog.h" +#include "Knob.h" + + +class DisintegratorControls; + + +class DisintegratorControlDialog : public EffectControlDialog +{ + Q_OBJECT +public: + DisintegratorControlDialog(DisintegratorControls* controls); + DisintegratorControls * m_controls; + + virtual ~DisintegratorControlDialog() + { + } + +private slots: + void updateKnobVisibility(); + +private: + Knob * m_lowCutKnob; + Knob * m_highCutKnob; + Knob * m_amountKnob; + ComboBox * m_typeBox; + Knob * m_freqKnob; + + friend class DisintegratorControls; +}; + +#endif diff --git a/plugins/Disintegrator/DisintegratorControls.cpp b/plugins/Disintegrator/DisintegratorControls.cpp new file mode 100644 index 000000000..547b962b3 --- /dev/null +++ b/plugins/Disintegrator/DisintegratorControls.cpp @@ -0,0 +1,73 @@ +/* + * DisintegratorControls.cpp + * + * Copyright (c) 2019 Lost Robot + * + * This file is part of LMMS - https://lmms.io + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public + * License along with this program (see COPYING); if not, write to the + * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301 USA. + * + */ + + +#include + +#include "DisintegratorControls.h" +#include "Disintegrator.h" + +#include "Engine.h" +#include "Song.h" + + +DisintegratorControls::DisintegratorControls(DisintegratorEffect* effect) : + EffectControls(effect), + m_effect(effect), + m_lowCutModel(2.0f, 2.0f, 21050.0f, 0.01f, this, tr("Low Cut")), + m_highCutModel(21050.0f, 2.0f, 21050.0f, 0.01f, this, tr("High Cut")), + m_amountModel(30.0f, 0.0f, 200.0f, 0.01f, this, tr("Amount")), + m_typeModel(this, tr("Type")), + m_freqModel(100.0f, 2.0f, 21050.0f, 0.01f, this, tr("Frequency")) +{ + 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")); +} + + +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"); +} + + + +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"); +} diff --git a/plugins/Disintegrator/DisintegratorControls.h b/plugins/Disintegrator/DisintegratorControls.h new file mode 100644 index 000000000..c8611cf92 --- /dev/null +++ b/plugins/Disintegrator/DisintegratorControls.h @@ -0,0 +1,79 @@ +/* + * DisintegratorControls.h + * + * Copyright (c) 2019 Lost Robot + * + * This file is part of LMMS - https://lmms.io + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public + * License along with this program (see COPYING); if not, write to the + * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301 USA. + * + */ + +#ifndef DISINTEGRATOR_CONTROLS_H +#define DISINTEGRATOR_CONTROLS_H + +#include "DisintegratorControlDialog.h" + +#include "ComboBox.h" +#include "EffectControls.h" +#include "Knob.h" + + +class DisintegratorEffect; + + +class DisintegratorControls : public EffectControls +{ + Q_OBJECT +public: + DisintegratorControls(DisintegratorEffect* effect); + virtual ~DisintegratorControls() + { + } + + virtual void saveSettings(QDomDocument & _doc, QDomElement & _parent); + virtual void loadSettings(const QDomElement & _this); + inline virtual QString nodeName() const + { + return "DisintegratorControls"; + } + + virtual int controlCount() + { + return 5; + } + + virtual EffectControlDialog* createView() + { + m_effectView = new DisintegratorControlDialog(this); + return m_effectView; + } + +private: + DisintegratorEffect* m_effect; + DisintegratorControlDialog * m_effectView; + + FloatModel m_lowCutModel; + FloatModel m_highCutModel; + FloatModel m_amountModel; + ComboBoxModel m_typeModel; + FloatModel m_freqModel; + + friend class DisintegratorControlDialog; + friend class DisintegratorEffect; +} ; + +#endif diff --git a/plugins/Disintegrator/OLD 1/CMakeLists.txt b/plugins/Disintegrator/OLD 1/CMakeLists.txt new file mode 100644 index 000000000..7642f8138 --- /dev/null +++ b/plugins/Disintegrator/OLD 1/CMakeLists.txt @@ -0,0 +1,3 @@ +INCLUDE(BuildPlugin) + +BUILD_PLUGIN(disintegrator Disintegrator.cpp DisintegratorControls.cpp DisintegratorControlDialog.cpp MOCFILES DisintegratorControls.h DisintegratorControlDialog.h EMBEDDED_RESOURCES artwork.png logo.png) diff --git a/plugins/Disintegrator/OLD 1/Disintegrator.cpp b/plugins/Disintegrator/OLD 1/Disintegrator.cpp new file mode 100644 index 000000000..1f4139dc9 --- /dev/null +++ b/plugins/Disintegrator/OLD 1/Disintegrator.cpp @@ -0,0 +1,245 @@ +/* + * Disintegrator.cpp + * + * Copyright (c) 2019 Lost Robot + * + * This file is part of LMMS - https://lmms.io + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public + * License along with this program (see COPYING); if not, write to the + * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301 USA. + * + */ + +#include "Disintegrator.h" + +#include "embed.h" +#include "plugin_export.h" +#include "lmms_math.h" + +extern "C" +{ + +Plugin::Descriptor PLUGIN_EXPORT disintegrator_plugin_descriptor = +{ + STRINGIFY( PLUGIN_NAME ), + "Disintegrator", + QT_TRANSLATE_NOOP( "pluginBrowser", "A plugin generated by Lost Robot's LMMS Development Package. This is your plugin description. You should change this." ), + "Lost Robot ", + 0x0100, + Plugin::Effect, + new PluginPixmapLoader("logo"), + NULL, + NULL +} ; + +} + + + +DisintegratorEffect::DisintegratorEffect( Model* parent, const Descriptor::SubPluginFeatures::Key* key ) : + Effect( &disintegrator_plugin_descriptor, parent, key ), + m_disintegratorControls( this ) +{ + for( int a = 0; a < 100; ++a ) + { + for( int b = 0; b < 2; ++b ) + { + inBuf[b].push_back(0); + } + } +} + + + + +DisintegratorEffect::~DisintegratorEffect() +{ +} + + + + +bool DisintegratorEffect::processAudioBuffer( sampleFrame* buf, const fpp_t frames ) +{ + if( !isEnabled() || !isRunning () ) + { + return( false ); + } + + double outSum = 0.0; + const float d = dryLevel(); + const float w = wetLevel(); + + // ==TAG== MAKEVALUEBUFFERS ==TAG== // + const ValueBuffer * volBuf = m_disintegratorControls.m_volumeModel.valueBuffer(); + const ValueBuffer * panBuf = m_disintegratorControls.m_panModel.valueBuffer(); + const ValueBuffer * leftBuf = m_disintegratorControls.m_leftModel.valueBuffer(); + const ValueBuffer * rightBuf = m_disintegratorControls.m_rightModel.valueBuffer(); + // ==TAG== ENDMAKEVALUEBUFFERS ==TAG== // + + for( fpp_t f = 0; f < frames; ++f ) + { + // ==TAG== EVALUATEVALUEBUFFERS ==TAG== // + const float vol = volBuf ? volBuf->value( f ) : m_disintegratorControls.m_volumeModel.value(); + const float pan = panBuf ? panBuf->value( f ) : m_disintegratorControls.m_panModel.value(); + const float left = leftBuf ? leftBuf->value( f ) : m_disintegratorControls.m_leftModel.value(); + const float right = rightBuf ? rightBuf->value( f ) : m_disintegratorControls.m_rightModel.value(); + // ==TAG== ENDEVALUATEVALUEBUFFERS ==TAG== // + + outSum += buf[f][0]*buf[f][0] + buf[f][1]*buf[f][1]; + + sample_t s[2] = { buf[f][0], buf[f][1] }; + + ++inBufLoc; + if( inBufLoc >= 100 ) + { + inBufLoc = 0; + } + + inBuf[0][inBufLoc] = s[0]; + inBuf[1][inBufLoc] = s[1]; + + float newInBufLoc[2]; + newInBufLoc[0] = fast_rand() / (float)FAST_RAND_MAX; + newInBufLoc[1] = fast_rand() / (float)FAST_RAND_MAX; + + calcHighpassFilter( newInBufLoc[0], newInBufLoc[0], 0, vol, 0.707, Engine::mixer()->processingSampleRate() ); + calcHighpassFilter( newInBufLoc[1], newInBufLoc[1], 1, vol, 0.707, Engine::mixer()->processingSampleRate() ); + calcLowpassFilter( newInBufLoc[0], newInBufLoc[0], 0, pan, 0.707, Engine::mixer()->processingSampleRate() ); + calcLowpassFilter( newInBufLoc[1], newInBufLoc[1], 1, pan, 0.707, Engine::mixer()->processingSampleRate() ); + + newInBufLoc[0] = realfmod(inBufLoc - newInBufLoc[0] * left, 100); + newInBufLoc[1] = realfmod(inBufLoc - newInBufLoc[1] * left, 100); + + float newInBufLocFrac[2]; + newInBufLocFrac[0] = fmod(newInBufLoc[0], 1); + newInBufLocFrac[1] = fmod(newInBufLoc[1], 1); + + if( newInBufLoc[0] < 99 ) + { + s[0] = inBuf[0][floor(newInBufLoc[0])] * (1 - newInBufLocFrac[0]) + inBuf[0][ceil(newInBufLoc[0])] * newInBufLocFrac[0]; + } + else + { + s[0] = inBuf[0][99] * (1 - newInBufLocFrac[0]) + inBuf[0][0] * newInBufLocFrac[0]; + } + + if( newInBufLoc[1] < 99 ) + { + s[1] = inBuf[1][floor(newInBufLoc[1])] * (1 - newInBufLocFrac[1]) + inBuf[1][ceil(newInBufLoc[1])] * newInBufLocFrac[1]; + } + else + { + s[1] = inBuf[1][99] * (1 - newInBufLocFrac[1]) + inBuf[1][0] * newInBufLocFrac[1]; + } + + buf[f][0] = d * buf[f][0] + w * s[0]; + buf[f][1] = d * buf[f][1] + w * s[1]; + } + + checkGate( outSum / frames ); + + return isRunning(); +} + + + +inline void DisintegratorEffect::calcLowpassFilter( sample_t &outSamp, sample_t inSamp, int which, float lpCutoff, float resonance, sample_rate_t Fs ) +{ + const float m_w0 = D_2PI * lpCutoff / Fs; + + const float m_tempCosW0 = cos(m_w0); + const float m_alpha = sin(m_w0) / ( resonance / 2.f ); + const float m_b0 = (1 - m_tempCosW0) * 0.5f; + const float m_b1 = 1 - m_tempCosW0; + const float m_b2 = m_b0; + const float m_a0 = 1 + m_alpha; + const float m_a1 = -2 * m_tempCosW0; + const float m_a2 = 1 - m_alpha; + + const float m_temp1 = m_b0/m_a0; + const float m_temp2 = m_b1/m_a0; + const float m_temp3 = m_b2/m_a0; + const float m_temp4 = m_a1/m_a0; + const float m_temp5 = m_a2/m_a0; + filtLPY[which][0] = m_temp1*inSamp + m_temp2*filtLPX[which][1] + m_temp3*filtLPX[which][2] - m_temp4*filtLPY[which][1] - m_temp5*filtLPY[which][2]; + + filtLPX[which][2] = filtLPX[which][1]; + filtLPX[which][1] = inSamp; + filtLPY[which][2] = filtLPY[which][1]; + filtLPY[which][1] = filtLPY[which][0]; + + outSamp = filtLPY[which][0]; +} + + + +inline void DisintegratorEffect::calcHighpassFilter( sample_t &outSamp, sample_t inSamp, int which, float hpCutoff, float resonance, sample_rate_t Fs ) +{ + const float m_w0 = D_2PI * hpCutoff / Fs; + + const float m_tempCosW0 = cos(m_w0); + const float m_alpha = sin(m_w0) / ( resonance / 2.f ); + const float m_b0 = (1 + m_tempCosW0) * 0.5f; + const float m_b1 = -(1 + m_tempCosW0); + const float m_b2 = m_b0; + const float m_a0 = 1 + m_alpha; + const float m_a1 = -2 * m_tempCosW0; + const float m_a2 = 1 - m_alpha; + + const float m_temp1 = m_b0/m_a0; + const float m_temp2 = m_b1/m_a0; + const float m_temp3 = m_b2/m_a0; + const float m_temp4 = m_a1/m_a0; + const float m_temp5 = m_a2/m_a0; + filtHPY[which][0] = m_temp1*inSamp + m_temp2*filtHPX[which][1] + m_temp3*filtHPX[which][2] - m_temp4*filtHPY[which][1] - m_temp5*filtHPY[which][2]; + + filtHPX[which][2] = filtHPX[which][1]; + filtHPX[which][1] = inSamp; + filtHPY[which][2] = filtHPY[which][1]; + filtHPY[which][1] = filtHPY[which][0]; + + outSamp = filtHPY[which][0]; +} + + + +// Takes input of original Hz and the number of cents to detune it by, and returns the detuned result in Hz. +inline float DisintegratorEffect::detuneWithOctaves(float pitchValue, float detuneValue) +{ + return pitchValue * std::exp2(detuneValue); +} + + + +// Handles negative values properly, unlike fmod. +inline float DisintegratorEffect::realfmod(float k, float n) +{ + return ((k = fmod(k,n)) < 0) ? k+n : k; +} + + + +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( data ) ); +} + +} + diff --git a/plugins/Disintegrator/OLD 1/Disintegrator.h b/plugins/Disintegrator/OLD 1/Disintegrator.h new file mode 100644 index 000000000..80b1ee3cc --- /dev/null +++ b/plugins/Disintegrator/OLD 1/Disintegrator.h @@ -0,0 +1,67 @@ +/* + * Disintegrator.h + * + * Copyright (c) 2019 Lost Robot + * + * This file is part of LMMS - https://lmms.io + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public + * License along with this program (see COPYING); if not, write to the + * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301 USA. + * + */ + + +#ifndef DISINTEGRATOR_H +#define DISINTEGRATOR_H + +#include "Effect.h" +#include "DisintegratorControls.h" +#include "ValueBuffer.h" + +class DisintegratorEffect : public Effect +{ +public: + DisintegratorEffect( Model* parent, const Descriptor::SubPluginFeatures::Key* key ); + virtual ~DisintegratorEffect(); + virtual bool processAudioBuffer( sampleFrame* buf, const fpp_t frames ); + + virtual EffectControls* controls() + { + return &m_disintegratorControls; + } + + inline float realfmod(float k, float n); + inline float detuneWithOctaves(float pitchValue, float detuneValue); + + inline void calcLowpassFilter( sample_t &outSamp, sample_t inSamp, int which, float lpCutoff, float resonance, sample_rate_t Fs ); + inline void calcHighpassFilter( sample_t &outSamp, sample_t inSamp, int which, float lpCutoff, float resonance, sample_rate_t Fs ); + + float filtLPX[2][3] = {0};// [filter number][samples back in time] + float filtLPY[2][3] = {0};// [filter number][samples back in time] + + float filtHPX[2][3] = {0};// [filter number][samples back in time] + float filtHPY[2][3] = {0};// [filter number][samples back in time] + +private: + DisintegratorControls m_disintegratorControls; + + std::vector inBuf[2]; + int inBufLoc = 0; + + friend class DisintegratorControls; + +} ; + +#endif diff --git a/plugins/Disintegrator/OLD 1/DisintegratorControlDialog.cpp b/plugins/Disintegrator/OLD 1/DisintegratorControlDialog.cpp new file mode 100644 index 000000000..3dbc63c8a --- /dev/null +++ b/plugins/Disintegrator/OLD 1/DisintegratorControlDialog.cpp @@ -0,0 +1,70 @@ +/* + * DisintegratorControlDialog.cpp + * + * Copyright (c) 2019 Lost Robot + * + * This file is part of LMMS - https://lmms.io + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public + * License along with this program (see COPYING); if not, write to the + * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301 USA. + * + */ + +#include + +#include "DisintegratorControlDialog.h" +#include "DisintegratorControls.h" +#include "embed.h" + + + +DisintegratorControlDialog::DisintegratorControlDialog( DisintegratorControls* controls ) : + EffectControlDialog( controls ) +{ + setAutoFillBackground( true ); + QPalette pal; + pal.setBrush( backgroundRole(), PLUGIN_NAME::getIconPixmap( "artwork" ) ); + setPalette( pal ); + setFixedSize( 100, 110 ); + + // ==TAG== INITIALIZEWIDGETS ==TAG== // + Knob * volumeKnob = new Knob( knobBright_26, this); + volumeKnob -> move( 16, 10 ); + volumeKnob -> setVolumeKnob( true ); + volumeKnob->setModel( &controls->m_volumeModel ); + volumeKnob->setLabel( tr( "VOL" ) ); + volumeKnob->setHintText( tr( "Volume:" ) , "%" ); + + Knob * panKnob = new Knob( knobBright_26, this); + panKnob -> move( 57, 10 ); + panKnob->setModel( &controls->m_panModel ); + panKnob->setLabel( tr( "PAN" ) ); + panKnob->setHintText( tr( "Panning:" ) , "" ); + + Knob * leftKnob = new Knob( knobBright_26, this); + leftKnob -> move( 16, 65 ); + leftKnob -> setVolumeKnob( true ); + leftKnob->setModel( &controls->m_leftModel ); + leftKnob->setLabel( tr( "LEFT" ) ); + leftKnob->setHintText( tr( "Left gain:" ) , "%" ); + + Knob * rightKnob = new Knob( knobBright_26, this); + rightKnob -> move( 57, 65 ); + rightKnob -> setVolumeKnob( true ); + rightKnob->setModel( &controls->m_rightModel ); + rightKnob->setLabel( tr( "RIGHT" ) ); + rightKnob->setHintText( tr( "Right gain:" ) , "%" ); + // ==TAG== ENDINITIALIZEWIDGETS ==TAG== // +} diff --git a/plugins/Disintegrator/OLD 1/DisintegratorControlDialog.h b/plugins/Disintegrator/OLD 1/DisintegratorControlDialog.h new file mode 100644 index 000000000..89d270130 --- /dev/null +++ b/plugins/Disintegrator/OLD 1/DisintegratorControlDialog.h @@ -0,0 +1,45 @@ +/* + * DisintegratorControlDialog.h + * + * Copyright (c) 2019 Lost Robot + * + * This file is part of LMMS - https://lmms.io + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public + * License along with this program (see COPYING); if not, write to the + * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301 USA. + * + */ + +#ifndef DISINTEGRATOR_CONTROL_DIALOG_H +#define DISINTEGRATOR_CONTROL_DIALOG_H + +#include "EffectControlDialog.h" + + +class DisintegratorControls; + + +class DisintegratorControlDialog : public EffectControlDialog +{ + Q_OBJECT +public: + DisintegratorControlDialog( DisintegratorControls* controls ); + virtual ~DisintegratorControlDialog() + { + } + +} ; + +#endif diff --git a/plugins/Disintegrator/OLD 1/DisintegratorControls.cpp b/plugins/Disintegrator/OLD 1/DisintegratorControls.cpp new file mode 100644 index 000000000..47fc5d295 --- /dev/null +++ b/plugins/Disintegrator/OLD 1/DisintegratorControls.cpp @@ -0,0 +1,69 @@ +/* + * DisintegratorControls.cpp + * + * Copyright (c) 2019 Lost Robot + * + * This file is part of LMMS - https://lmms.io + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public + * License along with this program (see COPYING); if not, write to the + * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301 USA. + * + */ + + +#include + +#include "DisintegratorControls.h" +#include "Disintegrator.h" +#include "Engine.h" +#include "Song.h" + + +DisintegratorControls::DisintegratorControls( DisintegratorEffect* effect ) : + EffectControls( effect ), + m_effect( effect ), + // ==TAG== INITIALIZEMODELS ==TAG== // + m_volumeModel( 20.0f, 20.0f, 21050.0f, 0.001f, this, tr( "Volume" ) ), + m_panModel( 20.0f, 20.0f, 21050.0f, 0.001f, this, tr( "Panning" ) ), + m_leftModel( 50.0f, 0.0f, 100.0f, 0.001f, this, tr( "Left gain" ) ), + m_rightModel( 100.0f, 0.0f, 200.0f, 0.1f, this, tr( "Right gain" ) ) + // ==TAG== ENDINITIALIZEMODELS ==TAG== // +{ +} + + +void DisintegratorControls::saveSettings( QDomDocument& doc, QDomElement& _this ) +{ + // ==TAG== SAVESETTINGS ==TAG== // + m_volumeModel.saveSettings( doc, _this, "volume" ); + m_panModel.saveSettings( doc, _this, "pan" ); + m_leftModel.saveSettings( doc, _this, "left" ); + m_rightModel.saveSettings( doc, _this, "right" ); + // ==TAG== ENDSAVESETTINGS ==TAG== // +} + + + +void DisintegratorControls::loadSettings( const QDomElement& _this ) +{ + // ==TAG== LOADSETTINGS ==TAG== // + m_volumeModel.loadSettings( _this, "volume" ); + m_panModel.loadSettings( _this, "pan" ); + m_leftModel.loadSettings( _this, "left" ); + m_rightModel.loadSettings( _this, "right" ); + // ==TAG== ENDLOADSETTINGS ==TAG== // +} + + diff --git a/plugins/Disintegrator/OLD 1/DisintegratorControls.h b/plugins/Disintegrator/OLD 1/DisintegratorControls.h new file mode 100644 index 000000000..39f7f5b26 --- /dev/null +++ b/plugins/Disintegrator/OLD 1/DisintegratorControls.h @@ -0,0 +1,78 @@ +/* + * DisintegratorControls.h + * + * Copyright (c) 2019 Lost Robot + * + * This file is part of LMMS - https://lmms.io + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public + * License along with this program (see COPYING); if not, write to the + * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301 USA. + * + */ + +#ifndef DISINTEGRATOR_CONTROLS_H +#define DISINTEGRATOR_CONTROLS_H + +#include "EffectControls.h" +#include "DisintegratorControlDialog.h" +#include "Knob.h" + + +class DisintegratorEffect; + + +class DisintegratorControls : public EffectControls +{ + Q_OBJECT +public: + DisintegratorControls( DisintegratorEffect* effect ); + virtual ~DisintegratorControls() + { + } + + virtual void saveSettings( QDomDocument & _doc, QDomElement & _parent ); + virtual void loadSettings( const QDomElement & _this ); + inline virtual QString nodeName() const + { + return "DisintegratorControls"; + } + + virtual int controlCount() + { + // ==TAG== CONTROLCOUNT ==TAG== // + return 4; + } + + virtual EffectControlDialog* createView() + { + return new DisintegratorControlDialog( this ); + } + +private: + DisintegratorEffect* m_effect; + + // ==TAG== DEFINEMODELS ==TAG== // + FloatModel m_volumeModel; + FloatModel m_panModel; + FloatModel m_leftModel; + FloatModel m_rightModel; + // ==TAG== ENDDEFINEMODELS ==TAG== // + + friend class DisintegratorControlDialog; + friend class DisintegratorEffect; + +} ; + +#endif diff --git a/plugins/Disintegrator/OLD 1/artwork.png b/plugins/Disintegrator/OLD 1/artwork.png new file mode 100644 index 0000000000000000000000000000000000000000..5598b32db47134819b686a2f2e282c297fe78c06 GIT binary patch literal 7739 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 Bz%u{< literal 0 HcmV?d00001 diff --git a/plugins/Disintegrator/OLD 1/logo.png b/plugins/Disintegrator/OLD 1/logo.png new file mode 100644 index 0000000000000000000000000000000000000000..9340da708dd79ed97111eb535f51b81a91d6a15b GIT binary patch literal 774 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 Bz%u{< literal 0 HcmV?d00001 diff --git a/plugins/Disintegrator/logo.png b/plugins/Disintegrator/logo.png new file mode 100644 index 0000000000000000000000000000000000000000..9340da708dd79ed97111eb535f51b81a91d6a15b GIT binary patch literal 774 zcmV+h1Nr=kP)7WEc)VQ)zLm`B#lSD% z0Wg;#IH?7|3b0p&fj_`2;A{cm@zx+(Ge?s$@EN$6LtMjg>;+(boCbaXw;ja=b6mQ?gRp67Yf18(18niCN0v&eY^{Cr&#;#IcF{ks?!* z&o!_q>9xbSw`QytRI!M?zP_o#K-8ExJaV?vi znPt?~0KhTu23U+Gy8^Tw;^SzWSet9n Date: Thu, 29 Aug 2019 19:59:24 -0600 Subject: [PATCH 02/20] Add Disintegrator effect --- plugins/Disintegrator/OLD 1/CMakeLists.txt | 3 - plugins/Disintegrator/OLD 1/Disintegrator.cpp | 245 ------------------ plugins/Disintegrator/OLD 1/Disintegrator.h | 67 ----- .../OLD 1/DisintegratorControlDialog.cpp | 70 ----- .../OLD 1/DisintegratorControlDialog.h | 45 ---- .../OLD 1/DisintegratorControls.cpp | 69 ----- .../OLD 1/DisintegratorControls.h | 78 ------ plugins/Disintegrator/OLD 1/artwork.png | Bin 7739 -> 0 bytes plugins/Disintegrator/OLD 1/logo.png | Bin 774 -> 0 bytes 9 files changed, 577 deletions(-) delete mode 100644 plugins/Disintegrator/OLD 1/CMakeLists.txt delete mode 100644 plugins/Disintegrator/OLD 1/Disintegrator.cpp delete mode 100644 plugins/Disintegrator/OLD 1/Disintegrator.h delete mode 100644 plugins/Disintegrator/OLD 1/DisintegratorControlDialog.cpp delete mode 100644 plugins/Disintegrator/OLD 1/DisintegratorControlDialog.h delete mode 100644 plugins/Disintegrator/OLD 1/DisintegratorControls.cpp delete mode 100644 plugins/Disintegrator/OLD 1/DisintegratorControls.h delete mode 100644 plugins/Disintegrator/OLD 1/artwork.png delete mode 100644 plugins/Disintegrator/OLD 1/logo.png diff --git a/plugins/Disintegrator/OLD 1/CMakeLists.txt b/plugins/Disintegrator/OLD 1/CMakeLists.txt deleted file mode 100644 index 7642f8138..000000000 --- a/plugins/Disintegrator/OLD 1/CMakeLists.txt +++ /dev/null @@ -1,3 +0,0 @@ -INCLUDE(BuildPlugin) - -BUILD_PLUGIN(disintegrator Disintegrator.cpp DisintegratorControls.cpp DisintegratorControlDialog.cpp MOCFILES DisintegratorControls.h DisintegratorControlDialog.h EMBEDDED_RESOURCES artwork.png logo.png) diff --git a/plugins/Disintegrator/OLD 1/Disintegrator.cpp b/plugins/Disintegrator/OLD 1/Disintegrator.cpp deleted file mode 100644 index 1f4139dc9..000000000 --- a/plugins/Disintegrator/OLD 1/Disintegrator.cpp +++ /dev/null @@ -1,245 +0,0 @@ -/* - * Disintegrator.cpp - * - * Copyright (c) 2019 Lost Robot - * - * This file is part of LMMS - https://lmms.io - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * General Public License for more details. - * - * You should have received a copy of the GNU General Public - * License along with this program (see COPYING); if not, write to the - * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, - * Boston, MA 02110-1301 USA. - * - */ - -#include "Disintegrator.h" - -#include "embed.h" -#include "plugin_export.h" -#include "lmms_math.h" - -extern "C" -{ - -Plugin::Descriptor PLUGIN_EXPORT disintegrator_plugin_descriptor = -{ - STRINGIFY( PLUGIN_NAME ), - "Disintegrator", - QT_TRANSLATE_NOOP( "pluginBrowser", "A plugin generated by Lost Robot's LMMS Development Package. This is your plugin description. You should change this." ), - "Lost Robot ", - 0x0100, - Plugin::Effect, - new PluginPixmapLoader("logo"), - NULL, - NULL -} ; - -} - - - -DisintegratorEffect::DisintegratorEffect( Model* parent, const Descriptor::SubPluginFeatures::Key* key ) : - Effect( &disintegrator_plugin_descriptor, parent, key ), - m_disintegratorControls( this ) -{ - for( int a = 0; a < 100; ++a ) - { - for( int b = 0; b < 2; ++b ) - { - inBuf[b].push_back(0); - } - } -} - - - - -DisintegratorEffect::~DisintegratorEffect() -{ -} - - - - -bool DisintegratorEffect::processAudioBuffer( sampleFrame* buf, const fpp_t frames ) -{ - if( !isEnabled() || !isRunning () ) - { - return( false ); - } - - double outSum = 0.0; - const float d = dryLevel(); - const float w = wetLevel(); - - // ==TAG== MAKEVALUEBUFFERS ==TAG== // - const ValueBuffer * volBuf = m_disintegratorControls.m_volumeModel.valueBuffer(); - const ValueBuffer * panBuf = m_disintegratorControls.m_panModel.valueBuffer(); - const ValueBuffer * leftBuf = m_disintegratorControls.m_leftModel.valueBuffer(); - const ValueBuffer * rightBuf = m_disintegratorControls.m_rightModel.valueBuffer(); - // ==TAG== ENDMAKEVALUEBUFFERS ==TAG== // - - for( fpp_t f = 0; f < frames; ++f ) - { - // ==TAG== EVALUATEVALUEBUFFERS ==TAG== // - const float vol = volBuf ? volBuf->value( f ) : m_disintegratorControls.m_volumeModel.value(); - const float pan = panBuf ? panBuf->value( f ) : m_disintegratorControls.m_panModel.value(); - const float left = leftBuf ? leftBuf->value( f ) : m_disintegratorControls.m_leftModel.value(); - const float right = rightBuf ? rightBuf->value( f ) : m_disintegratorControls.m_rightModel.value(); - // ==TAG== ENDEVALUATEVALUEBUFFERS ==TAG== // - - outSum += buf[f][0]*buf[f][0] + buf[f][1]*buf[f][1]; - - sample_t s[2] = { buf[f][0], buf[f][1] }; - - ++inBufLoc; - if( inBufLoc >= 100 ) - { - inBufLoc = 0; - } - - inBuf[0][inBufLoc] = s[0]; - inBuf[1][inBufLoc] = s[1]; - - float newInBufLoc[2]; - newInBufLoc[0] = fast_rand() / (float)FAST_RAND_MAX; - newInBufLoc[1] = fast_rand() / (float)FAST_RAND_MAX; - - calcHighpassFilter( newInBufLoc[0], newInBufLoc[0], 0, vol, 0.707, Engine::mixer()->processingSampleRate() ); - calcHighpassFilter( newInBufLoc[1], newInBufLoc[1], 1, vol, 0.707, Engine::mixer()->processingSampleRate() ); - calcLowpassFilter( newInBufLoc[0], newInBufLoc[0], 0, pan, 0.707, Engine::mixer()->processingSampleRate() ); - calcLowpassFilter( newInBufLoc[1], newInBufLoc[1], 1, pan, 0.707, Engine::mixer()->processingSampleRate() ); - - newInBufLoc[0] = realfmod(inBufLoc - newInBufLoc[0] * left, 100); - newInBufLoc[1] = realfmod(inBufLoc - newInBufLoc[1] * left, 100); - - float newInBufLocFrac[2]; - newInBufLocFrac[0] = fmod(newInBufLoc[0], 1); - newInBufLocFrac[1] = fmod(newInBufLoc[1], 1); - - if( newInBufLoc[0] < 99 ) - { - s[0] = inBuf[0][floor(newInBufLoc[0])] * (1 - newInBufLocFrac[0]) + inBuf[0][ceil(newInBufLoc[0])] * newInBufLocFrac[0]; - } - else - { - s[0] = inBuf[0][99] * (1 - newInBufLocFrac[0]) + inBuf[0][0] * newInBufLocFrac[0]; - } - - if( newInBufLoc[1] < 99 ) - { - s[1] = inBuf[1][floor(newInBufLoc[1])] * (1 - newInBufLocFrac[1]) + inBuf[1][ceil(newInBufLoc[1])] * newInBufLocFrac[1]; - } - else - { - s[1] = inBuf[1][99] * (1 - newInBufLocFrac[1]) + inBuf[1][0] * newInBufLocFrac[1]; - } - - buf[f][0] = d * buf[f][0] + w * s[0]; - buf[f][1] = d * buf[f][1] + w * s[1]; - } - - checkGate( outSum / frames ); - - return isRunning(); -} - - - -inline void DisintegratorEffect::calcLowpassFilter( sample_t &outSamp, sample_t inSamp, int which, float lpCutoff, float resonance, sample_rate_t Fs ) -{ - const float m_w0 = D_2PI * lpCutoff / Fs; - - const float m_tempCosW0 = cos(m_w0); - const float m_alpha = sin(m_w0) / ( resonance / 2.f ); - const float m_b0 = (1 - m_tempCosW0) * 0.5f; - const float m_b1 = 1 - m_tempCosW0; - const float m_b2 = m_b0; - const float m_a0 = 1 + m_alpha; - const float m_a1 = -2 * m_tempCosW0; - const float m_a2 = 1 - m_alpha; - - const float m_temp1 = m_b0/m_a0; - const float m_temp2 = m_b1/m_a0; - const float m_temp3 = m_b2/m_a0; - const float m_temp4 = m_a1/m_a0; - const float m_temp5 = m_a2/m_a0; - filtLPY[which][0] = m_temp1*inSamp + m_temp2*filtLPX[which][1] + m_temp3*filtLPX[which][2] - m_temp4*filtLPY[which][1] - m_temp5*filtLPY[which][2]; - - filtLPX[which][2] = filtLPX[which][1]; - filtLPX[which][1] = inSamp; - filtLPY[which][2] = filtLPY[which][1]; - filtLPY[which][1] = filtLPY[which][0]; - - outSamp = filtLPY[which][0]; -} - - - -inline void DisintegratorEffect::calcHighpassFilter( sample_t &outSamp, sample_t inSamp, int which, float hpCutoff, float resonance, sample_rate_t Fs ) -{ - const float m_w0 = D_2PI * hpCutoff / Fs; - - const float m_tempCosW0 = cos(m_w0); - const float m_alpha = sin(m_w0) / ( resonance / 2.f ); - const float m_b0 = (1 + m_tempCosW0) * 0.5f; - const float m_b1 = -(1 + m_tempCosW0); - const float m_b2 = m_b0; - const float m_a0 = 1 + m_alpha; - const float m_a1 = -2 * m_tempCosW0; - const float m_a2 = 1 - m_alpha; - - const float m_temp1 = m_b0/m_a0; - const float m_temp2 = m_b1/m_a0; - const float m_temp3 = m_b2/m_a0; - const float m_temp4 = m_a1/m_a0; - const float m_temp5 = m_a2/m_a0; - filtHPY[which][0] = m_temp1*inSamp + m_temp2*filtHPX[which][1] + m_temp3*filtHPX[which][2] - m_temp4*filtHPY[which][1] - m_temp5*filtHPY[which][2]; - - filtHPX[which][2] = filtHPX[which][1]; - filtHPX[which][1] = inSamp; - filtHPY[which][2] = filtHPY[which][1]; - filtHPY[which][1] = filtHPY[which][0]; - - outSamp = filtHPY[which][0]; -} - - - -// Takes input of original Hz and the number of cents to detune it by, and returns the detuned result in Hz. -inline float DisintegratorEffect::detuneWithOctaves(float pitchValue, float detuneValue) -{ - return pitchValue * std::exp2(detuneValue); -} - - - -// Handles negative values properly, unlike fmod. -inline float DisintegratorEffect::realfmod(float k, float n) -{ - return ((k = fmod(k,n)) < 0) ? k+n : k; -} - - - -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( data ) ); -} - -} - diff --git a/plugins/Disintegrator/OLD 1/Disintegrator.h b/plugins/Disintegrator/OLD 1/Disintegrator.h deleted file mode 100644 index 80b1ee3cc..000000000 --- a/plugins/Disintegrator/OLD 1/Disintegrator.h +++ /dev/null @@ -1,67 +0,0 @@ -/* - * Disintegrator.h - * - * Copyright (c) 2019 Lost Robot - * - * This file is part of LMMS - https://lmms.io - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * General Public License for more details. - * - * You should have received a copy of the GNU General Public - * License along with this program (see COPYING); if not, write to the - * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, - * Boston, MA 02110-1301 USA. - * - */ - - -#ifndef DISINTEGRATOR_H -#define DISINTEGRATOR_H - -#include "Effect.h" -#include "DisintegratorControls.h" -#include "ValueBuffer.h" - -class DisintegratorEffect : public Effect -{ -public: - DisintegratorEffect( Model* parent, const Descriptor::SubPluginFeatures::Key* key ); - virtual ~DisintegratorEffect(); - virtual bool processAudioBuffer( sampleFrame* buf, const fpp_t frames ); - - virtual EffectControls* controls() - { - return &m_disintegratorControls; - } - - inline float realfmod(float k, float n); - inline float detuneWithOctaves(float pitchValue, float detuneValue); - - inline void calcLowpassFilter( sample_t &outSamp, sample_t inSamp, int which, float lpCutoff, float resonance, sample_rate_t Fs ); - inline void calcHighpassFilter( sample_t &outSamp, sample_t inSamp, int which, float lpCutoff, float resonance, sample_rate_t Fs ); - - float filtLPX[2][3] = {0};// [filter number][samples back in time] - float filtLPY[2][3] = {0};// [filter number][samples back in time] - - float filtHPX[2][3] = {0};// [filter number][samples back in time] - float filtHPY[2][3] = {0};// [filter number][samples back in time] - -private: - DisintegratorControls m_disintegratorControls; - - std::vector inBuf[2]; - int inBufLoc = 0; - - friend class DisintegratorControls; - -} ; - -#endif diff --git a/plugins/Disintegrator/OLD 1/DisintegratorControlDialog.cpp b/plugins/Disintegrator/OLD 1/DisintegratorControlDialog.cpp deleted file mode 100644 index 3dbc63c8a..000000000 --- a/plugins/Disintegrator/OLD 1/DisintegratorControlDialog.cpp +++ /dev/null @@ -1,70 +0,0 @@ -/* - * DisintegratorControlDialog.cpp - * - * Copyright (c) 2019 Lost Robot - * - * This file is part of LMMS - https://lmms.io - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * General Public License for more details. - * - * You should have received a copy of the GNU General Public - * License along with this program (see COPYING); if not, write to the - * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, - * Boston, MA 02110-1301 USA. - * - */ - -#include - -#include "DisintegratorControlDialog.h" -#include "DisintegratorControls.h" -#include "embed.h" - - - -DisintegratorControlDialog::DisintegratorControlDialog( DisintegratorControls* controls ) : - EffectControlDialog( controls ) -{ - setAutoFillBackground( true ); - QPalette pal; - pal.setBrush( backgroundRole(), PLUGIN_NAME::getIconPixmap( "artwork" ) ); - setPalette( pal ); - setFixedSize( 100, 110 ); - - // ==TAG== INITIALIZEWIDGETS ==TAG== // - Knob * volumeKnob = new Knob( knobBright_26, this); - volumeKnob -> move( 16, 10 ); - volumeKnob -> setVolumeKnob( true ); - volumeKnob->setModel( &controls->m_volumeModel ); - volumeKnob->setLabel( tr( "VOL" ) ); - volumeKnob->setHintText( tr( "Volume:" ) , "%" ); - - Knob * panKnob = new Knob( knobBright_26, this); - panKnob -> move( 57, 10 ); - panKnob->setModel( &controls->m_panModel ); - panKnob->setLabel( tr( "PAN" ) ); - panKnob->setHintText( tr( "Panning:" ) , "" ); - - Knob * leftKnob = new Knob( knobBright_26, this); - leftKnob -> move( 16, 65 ); - leftKnob -> setVolumeKnob( true ); - leftKnob->setModel( &controls->m_leftModel ); - leftKnob->setLabel( tr( "LEFT" ) ); - leftKnob->setHintText( tr( "Left gain:" ) , "%" ); - - Knob * rightKnob = new Knob( knobBright_26, this); - rightKnob -> move( 57, 65 ); - rightKnob -> setVolumeKnob( true ); - rightKnob->setModel( &controls->m_rightModel ); - rightKnob->setLabel( tr( "RIGHT" ) ); - rightKnob->setHintText( tr( "Right gain:" ) , "%" ); - // ==TAG== ENDINITIALIZEWIDGETS ==TAG== // -} diff --git a/plugins/Disintegrator/OLD 1/DisintegratorControlDialog.h b/plugins/Disintegrator/OLD 1/DisintegratorControlDialog.h deleted file mode 100644 index 89d270130..000000000 --- a/plugins/Disintegrator/OLD 1/DisintegratorControlDialog.h +++ /dev/null @@ -1,45 +0,0 @@ -/* - * DisintegratorControlDialog.h - * - * Copyright (c) 2019 Lost Robot - * - * This file is part of LMMS - https://lmms.io - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * General Public License for more details. - * - * You should have received a copy of the GNU General Public - * License along with this program (see COPYING); if not, write to the - * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, - * Boston, MA 02110-1301 USA. - * - */ - -#ifndef DISINTEGRATOR_CONTROL_DIALOG_H -#define DISINTEGRATOR_CONTROL_DIALOG_H - -#include "EffectControlDialog.h" - - -class DisintegratorControls; - - -class DisintegratorControlDialog : public EffectControlDialog -{ - Q_OBJECT -public: - DisintegratorControlDialog( DisintegratorControls* controls ); - virtual ~DisintegratorControlDialog() - { - } - -} ; - -#endif diff --git a/plugins/Disintegrator/OLD 1/DisintegratorControls.cpp b/plugins/Disintegrator/OLD 1/DisintegratorControls.cpp deleted file mode 100644 index 47fc5d295..000000000 --- a/plugins/Disintegrator/OLD 1/DisintegratorControls.cpp +++ /dev/null @@ -1,69 +0,0 @@ -/* - * DisintegratorControls.cpp - * - * Copyright (c) 2019 Lost Robot - * - * This file is part of LMMS - https://lmms.io - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * General Public License for more details. - * - * You should have received a copy of the GNU General Public - * License along with this program (see COPYING); if not, write to the - * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, - * Boston, MA 02110-1301 USA. - * - */ - - -#include - -#include "DisintegratorControls.h" -#include "Disintegrator.h" -#include "Engine.h" -#include "Song.h" - - -DisintegratorControls::DisintegratorControls( DisintegratorEffect* effect ) : - EffectControls( effect ), - m_effect( effect ), - // ==TAG== INITIALIZEMODELS ==TAG== // - m_volumeModel( 20.0f, 20.0f, 21050.0f, 0.001f, this, tr( "Volume" ) ), - m_panModel( 20.0f, 20.0f, 21050.0f, 0.001f, this, tr( "Panning" ) ), - m_leftModel( 50.0f, 0.0f, 100.0f, 0.001f, this, tr( "Left gain" ) ), - m_rightModel( 100.0f, 0.0f, 200.0f, 0.1f, this, tr( "Right gain" ) ) - // ==TAG== ENDINITIALIZEMODELS ==TAG== // -{ -} - - -void DisintegratorControls::saveSettings( QDomDocument& doc, QDomElement& _this ) -{ - // ==TAG== SAVESETTINGS ==TAG== // - m_volumeModel.saveSettings( doc, _this, "volume" ); - m_panModel.saveSettings( doc, _this, "pan" ); - m_leftModel.saveSettings( doc, _this, "left" ); - m_rightModel.saveSettings( doc, _this, "right" ); - // ==TAG== ENDSAVESETTINGS ==TAG== // -} - - - -void DisintegratorControls::loadSettings( const QDomElement& _this ) -{ - // ==TAG== LOADSETTINGS ==TAG== // - m_volumeModel.loadSettings( _this, "volume" ); - m_panModel.loadSettings( _this, "pan" ); - m_leftModel.loadSettings( _this, "left" ); - m_rightModel.loadSettings( _this, "right" ); - // ==TAG== ENDLOADSETTINGS ==TAG== // -} - - diff --git a/plugins/Disintegrator/OLD 1/DisintegratorControls.h b/plugins/Disintegrator/OLD 1/DisintegratorControls.h deleted file mode 100644 index 39f7f5b26..000000000 --- a/plugins/Disintegrator/OLD 1/DisintegratorControls.h +++ /dev/null @@ -1,78 +0,0 @@ -/* - * DisintegratorControls.h - * - * Copyright (c) 2019 Lost Robot - * - * This file is part of LMMS - https://lmms.io - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * General Public License for more details. - * - * You should have received a copy of the GNU General Public - * License along with this program (see COPYING); if not, write to the - * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, - * Boston, MA 02110-1301 USA. - * - */ - -#ifndef DISINTEGRATOR_CONTROLS_H -#define DISINTEGRATOR_CONTROLS_H - -#include "EffectControls.h" -#include "DisintegratorControlDialog.h" -#include "Knob.h" - - -class DisintegratorEffect; - - -class DisintegratorControls : public EffectControls -{ - Q_OBJECT -public: - DisintegratorControls( DisintegratorEffect* effect ); - virtual ~DisintegratorControls() - { - } - - virtual void saveSettings( QDomDocument & _doc, QDomElement & _parent ); - virtual void loadSettings( const QDomElement & _this ); - inline virtual QString nodeName() const - { - return "DisintegratorControls"; - } - - virtual int controlCount() - { - // ==TAG== CONTROLCOUNT ==TAG== // - return 4; - } - - virtual EffectControlDialog* createView() - { - return new DisintegratorControlDialog( this ); - } - -private: - DisintegratorEffect* m_effect; - - // ==TAG== DEFINEMODELS ==TAG== // - FloatModel m_volumeModel; - FloatModel m_panModel; - FloatModel m_leftModel; - FloatModel m_rightModel; - // ==TAG== ENDDEFINEMODELS ==TAG== // - - friend class DisintegratorControlDialog; - friend class DisintegratorEffect; - -} ; - -#endif diff --git a/plugins/Disintegrator/OLD 1/artwork.png b/plugins/Disintegrator/OLD 1/artwork.png deleted file mode 100644 index 5598b32db47134819b686a2f2e282c297fe78c06..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 7739 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 Bz%u{< diff --git a/plugins/Disintegrator/OLD 1/logo.png b/plugins/Disintegrator/OLD 1/logo.png deleted file mode 100644 index 9340da708dd79ed97111eb535f51b81a91d6a15b..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 774 zcmV+h1Nr=kP)7WEc)VQ)zLm`B#lSD% z0Wg;#IH?7|3b0p&fj_`2;A{cm@zx+(Ge?s$@EN$6LtMjg>;+(boCbaXw;ja=b6mQ?gRp67Yf18(18niCN0v&eY^{Cr&#;#IcF{ks?!* z&o!_q>9xbSw`QytRI!M?zP_o#K-8ExJaV?vi znPt?~0KhTu23U+Gy8^Tw;^SzWSet9n Date: Thu, 29 Aug 2019 20:44:49 -0600 Subject: [PATCH 03/20] Added comments, removed unnecessary detuneWithOctaves function. --- plugins/Disintegrator/Disintegrator.cpp | 21 +++++++++++-------- plugins/Disintegrator/Disintegrator.h | 1 - .../DisintegratorControlDialog.cpp | 3 ++- .../Disintegrator/DisintegratorControls.cpp | 1 + 4 files changed, 15 insertions(+), 11 deletions(-) diff --git a/plugins/Disintegrator/Disintegrator.cpp b/plugins/Disintegrator/Disintegrator.cpp index 6531f9468..4c2ebc000 100644 --- a/plugins/Disintegrator/Disintegrator.cpp +++ b/plugins/Disintegrator/Disintegrator.cpp @@ -52,6 +52,7 @@ DisintegratorEffect::DisintegratorEffect(Model* parent, const Descriptor::SubPlu Effect(&disintegrator_plugin_descriptor, parent, key), m_disintegratorControls(this) { + // Fill buffer with 200 samples for (int a = 0; a < 200; ++a) { for (int b = 0; b < 2; ++b) @@ -102,17 +103,22 @@ bool DisintegratorEffect::processAudioBuffer(sampleFrame* buf, const fpp_t frame sample_t s[2] = {buf[f][0], buf[f][1]}; + // Increment buffer read point ++m_inBufLoc; if (m_inBufLoc >= 200) { m_inBufLoc = 0; } + // Write dry input to buffer m_inBuf[0][m_inBufLoc] = s[0]; m_inBuf[1][m_inBufLoc] = s[1]; float newInBufLoc[2] = {0, 0}; float newInBufLocFrac[2] = {0, 0}; + + // Generate white noise or sine wave, apply filters, subtract the + // result from the buffer read point and store in a variable. switch (type) { case 0:// Mono Noise @@ -125,6 +131,7 @@ bool DisintegratorEffect::processAudioBuffer(sampleFrame* buf, const fpp_t frame newInBufLoc[0] = realfmod(m_inBufLoc - newInBufLoc[0] * amount, 200); newInBufLoc[1] = newInBufLoc[0]; + // Distance between samples newInBufLocFrac[0] = fmod(newInBufLoc[0], 1); newInBufLocFrac[1] = newInBufLocFrac[0]; @@ -143,6 +150,7 @@ bool DisintegratorEffect::processAudioBuffer(sampleFrame* buf, const fpp_t frame newInBufLoc[0] = realfmod(m_inBufLoc - newInBufLoc[0] * amount, 200); newInBufLoc[1] = realfmod(m_inBufLoc - newInBufLoc[1] * amount, 200); + // Distance between samples newInBufLocFrac[0] = fmod(newInBufLoc[0], 1); newInBufLocFrac[1] = fmod(newInBufLoc[1], 1); @@ -157,6 +165,7 @@ bool DisintegratorEffect::processAudioBuffer(sampleFrame* buf, const fpp_t frame newInBufLoc[0] = realfmod(m_inBufLoc - newInBufLoc[0] * amount, 200); newInBufLoc[1] = newInBufLoc[0]; + // Distance between samples newInBufLocFrac[0] = fmod(newInBufLoc[0], 1); newInBufLocFrac[1] = newInBufLocFrac[0]; @@ -176,7 +185,7 @@ bool DisintegratorEffect::processAudioBuffer(sampleFrame* buf, const fpp_t frame { s[b] = m_inBuf[b][floor(newInBufLoc[b])] * (1 - newInBufLocFrac[b]) + m_inBuf[b][ceil(newInBufLoc[b])] * newInBufLocFrac[b]; } - else + else// For when the interpolation wraps around to the beginning of the buffer { s[b] = m_inBuf[b][199] * (1 - newInBufLocFrac[b]) + m_inBuf[b][0] * newInBufLocFrac[b]; } @@ -196,6 +205,7 @@ bool DisintegratorEffect::processAudioBuffer(sampleFrame* buf, const fpp_t frame inline void DisintegratorEffect::calcLowpassFilter(sample_t &outSamp, sample_t inSamp, int which, float lpCutoff, float resonance, sample_rate_t Fs) { + // "if" statement is here so the filter coefficients only need to be calculated when they change if (m_prevLPCutoff[which] != lpCutoff) { m_prevLPCutoff[which] = lpCutoff; @@ -224,6 +234,7 @@ inline void DisintegratorEffect::calcLowpassFilter(sample_t &outSamp, sample_t i inline void DisintegratorEffect::calcHighpassFilter(sample_t &outSamp, sample_t inSamp, int which, float hpCutoff, float resonance, sample_rate_t Fs) { + // "if" statement is here so the filter coefficients only need to be calculated when they change if (m_prevHPCutoff[which] != hpCutoff) { m_prevHPCutoff[which] = hpCutoff; @@ -250,14 +261,6 @@ inline void DisintegratorEffect::calcHighpassFilter(sample_t &outSamp, sample_t -// Takes input of original Hz and the number of cents to detune it by, and returns the detuned result in Hz. -inline float DisintegratorEffect::detuneWithOctaves(float pitchValue, float detuneValue) -{ - return pitchValue * std::exp2(detuneValue); -} - - - // Handles negative values properly, unlike fmod. inline float DisintegratorEffect::realfmod(float k, float n) { diff --git a/plugins/Disintegrator/Disintegrator.h b/plugins/Disintegrator/Disintegrator.h index a206e4304..271cbac10 100644 --- a/plugins/Disintegrator/Disintegrator.h +++ b/plugins/Disintegrator/Disintegrator.h @@ -44,7 +44,6 @@ public: } inline float realfmod(float k, float n); - inline float detuneWithOctaves(float pitchValue, float detuneValue); inline void calcLowpassFilter(sample_t &outSamp, sample_t inSamp, int which, float lpCutoff, float resonance, sample_rate_t Fs); inline void calcHighpassFilter(sample_t &outSamp, sample_t inSamp, int which, float lpCutoff, float resonance, sample_rate_t Fs); diff --git a/plugins/Disintegrator/DisintegratorControlDialog.cpp b/plugins/Disintegrator/DisintegratorControlDialog.cpp index a680f3c33..97a8a2718 100644 --- a/plugins/Disintegrator/DisintegratorControlDialog.cpp +++ b/plugins/Disintegrator/DisintegratorControlDialog.cpp @@ -79,7 +79,8 @@ DisintegratorControlDialog::DisintegratorControlDialog(DisintegratorControls* co } - +/* Switches between the lowcut/highcut and +frequency knobs depending on the modulation type. */ void DisintegratorControlDialog::updateKnobVisibility() { if (m_controls->m_typeModel.value() == 2) diff --git a/plugins/Disintegrator/DisintegratorControls.cpp b/plugins/Disintegrator/DisintegratorControls.cpp index 547b962b3..cb403ea45 100644 --- a/plugins/Disintegrator/DisintegratorControls.cpp +++ b/plugins/Disintegrator/DisintegratorControls.cpp @@ -41,6 +41,7 @@ DisintegratorControls::DisintegratorControls(DisintegratorEffect* effect) : m_typeModel(this, tr("Type")), m_freqModel(100.0f, 2.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); From 6a44a51b5af4330a7782b548ec3be3bfd6608b33 Mon Sep 17 00:00:00 2001 From: root Date: Thu, 29 Aug 2019 21:08:52 -0600 Subject: [PATCH 04/20] Resolve code/style reviews --- plugins/Disintegrator/Disintegrator.cpp | 92 ++++++++++--------- plugins/Disintegrator/Disintegrator.h | 8 +- .../Disintegrator/DisintegratorControls.cpp | 4 +- 3 files changed, 56 insertions(+), 48 deletions(-) diff --git a/plugins/Disintegrator/Disintegrator.cpp b/plugins/Disintegrator/Disintegrator.cpp index 4c2ebc000..d4c883ada 100644 --- a/plugins/Disintegrator/Disintegrator.cpp +++ b/plugins/Disintegrator/Disintegrator.cpp @@ -52,12 +52,13 @@ DisintegratorEffect::DisintegratorEffect(Model* parent, const Descriptor::SubPlu Effect(&disintegrator_plugin_descriptor, parent, key), m_disintegratorControls(this) { - // Fill buffer with 200 samples - for (int a = 0; a < 200; ++a) + // Fill buffer with DISINTEGRATOR_BUFFER_SIZE number of samples + for (int i = 0; i < DISINTEGRATOR_BUFFER_SIZE; ++i) { - for (int b = 0; b < 2; ++b) + m_inBuf[i].reserve(DISINTEGRATOR_BUFFER_SIZE); + for (int j = 0; j < 2; ++j) { - m_inBuf[b].push_back(0); + m_inBuf[j].push_back(0); } } } @@ -89,7 +90,7 @@ bool DisintegratorEffect::processAudioBuffer(sampleFrame* buf, const fpp_t frame const ValueBuffer * typeBuf = m_disintegratorControls.m_typeModel.valueBuffer(); const ValueBuffer * freqBuf = m_disintegratorControls.m_lowCutModel.valueBuffer(); - sample_rate_t sample_rate = Engine::mixer()->processingSampleRate(); + sample_rate_t sampleRate = Engine::mixer()->processingSampleRate(); for (fpp_t f = 0; f < frames; ++f) { @@ -105,7 +106,7 @@ bool DisintegratorEffect::processAudioBuffer(sampleFrame* buf, const fpp_t frame // Increment buffer read point ++m_inBufLoc; - if (m_inBufLoc >= 200) + if (m_inBufLoc >= DISINTEGRATOR_BUFFER_SIZE) { m_inBufLoc = 0; } @@ -125,10 +126,10 @@ bool DisintegratorEffect::processAudioBuffer(sampleFrame* buf, const fpp_t frame { newInBufLoc[0] = fast_rand() / (float)FAST_RAND_MAX; - calcHighpassFilter(newInBufLoc[0], newInBufLoc[0], 0, lowCut, 0.707, sample_rate); - calcLowpassFilter(newInBufLoc[0], newInBufLoc[0], 0, highCut, 0.707, sample_rate); + calcHighpassFilter(newInBufLoc[0], newInBufLoc[0], 0, lowCut, sampleRate); + calcLowpassFilter(newInBufLoc[0], newInBufLoc[0], 0, highCut, sampleRate); - newInBufLoc[0] = realfmod(m_inBufLoc - newInBufLoc[0] * amount, 200); + newInBufLoc[0] = realfmod(m_inBufLoc - newInBufLoc[0] * amount, DISINTEGRATOR_BUFFER_SIZE); newInBufLoc[1] = newInBufLoc[0]; // Distance between samples @@ -142,13 +143,13 @@ bool DisintegratorEffect::processAudioBuffer(sampleFrame* buf, const fpp_t frame newInBufLoc[0] = fast_rand() / (float)FAST_RAND_MAX; newInBufLoc[1] = fast_rand() / (float)FAST_RAND_MAX; - calcHighpassFilter(newInBufLoc[0], newInBufLoc[0], 0, lowCut, 0.707, sample_rate); - calcHighpassFilter(newInBufLoc[1], newInBufLoc[1], 1, lowCut, 0.707, sample_rate); - calcLowpassFilter(newInBufLoc[0], newInBufLoc[0], 0, highCut, 0.707, sample_rate); - calcLowpassFilter(newInBufLoc[1], newInBufLoc[1], 1, highCut, 0.707, sample_rate); + calcHighpassFilter(newInBufLoc[0], newInBufLoc[0], 0, lowCut, sampleRate); + calcHighpassFilter(newInBufLoc[1], newInBufLoc[1], 1, lowCut, sampleRate); + calcLowpassFilter(newInBufLoc[0], newInBufLoc[0], 0, highCut, sampleRate); + calcLowpassFilter(newInBufLoc[1], newInBufLoc[1], 1, highCut, sampleRate); - newInBufLoc[0] = realfmod(m_inBufLoc - newInBufLoc[0] * amount, 200); - newInBufLoc[1] = realfmod(m_inBufLoc - newInBufLoc[1] * amount, 200); + newInBufLoc[0] = realfmod(m_inBufLoc - newInBufLoc[0] * amount, DISINTEGRATOR_BUFFER_SIZE); + newInBufLoc[1] = realfmod(m_inBufLoc - newInBufLoc[1] * amount, DISINTEGRATOR_BUFFER_SIZE); // Distance between samples newInBufLocFrac[0] = fmod(newInBufLoc[0], 1); @@ -158,11 +159,11 @@ bool DisintegratorEffect::processAudioBuffer(sampleFrame* buf, const fpp_t frame } case 2:// Sine Wave { - m_sineLoc = fmod(m_sineLoc + (freq / (float)sample_rate * F_2PI), F_2PI); + m_sineLoc = fmod(m_sineLoc + (freq / (float)sampleRate * F_2PI), F_2PI); newInBufLoc[0] = (sin(m_sineLoc) + 1) * 0.5f; - newInBufLoc[0] = realfmod(m_inBufLoc - newInBufLoc[0] * amount, 200); + newInBufLoc[0] = realfmod(m_inBufLoc - newInBufLoc[0] * amount, DISINTEGRATOR_BUFFER_SIZE); newInBufLoc[1] = newInBufLoc[0]; // Distance between samples @@ -173,21 +174,21 @@ bool DisintegratorEffect::processAudioBuffer(sampleFrame* buf, const fpp_t frame } } - for (int b = 0; b < 2; ++b) + for (int i = 0; i < 2; ++i) { - if (fmod(newInBufLoc[b], 1) == 0) + if (fmod(newInBufLoc[i], 1) == 0) { - s[b] = m_inBuf[b][newInBufLoc[b]]; + s[i] = m_inBuf[i][newInBufLoc[i]]; } else { - if (newInBufLoc[b] < 199) + if (newInBufLoc[i] < DISINTEGRATOR_BUFFER_SIZE - 1) { - s[b] = m_inBuf[b][floor(newInBufLoc[b])] * (1 - newInBufLocFrac[b]) + m_inBuf[b][ceil(newInBufLoc[b])] * newInBufLocFrac[b]; + 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[b] = m_inBuf[b][199] * (1 - newInBufLocFrac[b]) + m_inBuf[b][0] * newInBufLocFrac[b]; + s[i] = m_inBuf[i][DISINTEGRATOR_BUFFER_SIZE - 1] * (1 - newInBufLocFrac[i]) + m_inBuf[i][0] * newInBufLocFrac[i]; } } } @@ -203,13 +204,13 @@ bool DisintegratorEffect::processAudioBuffer(sampleFrame* buf, const fpp_t frame -inline void DisintegratorEffect::calcLowpassFilter(sample_t &outSamp, sample_t inSamp, int which, float lpCutoff, float resonance, sample_rate_t Fs) +inline void DisintegratorEffect::calcLowpassFilter(sample_t &outSamp, sample_t inSamp, int channel, float lpCutoff, sample_rate_t sampleRate) { // "if" statement is here so the filter coefficients only need to be calculated when they change - if (m_prevLPCutoff[which] != lpCutoff) + if (m_prevLPCutoff[channel] != lpCutoff) { - m_prevLPCutoff[which] = lpCutoff; - const float w0 = D_2PI * lpCutoff / Fs; + m_prevLPCutoff[channel] = lpCutoff; + const float w0 = D_2PI * lpCutoff / sampleRate; const float tempCosW0 = cos(w0); const float alpha = sin(w0) / 0.3535f; @@ -220,25 +221,26 @@ inline void DisintegratorEffect::calcLowpassFilter(sample_t &outSamp, sample_t i m_LPa2 = 1 - alpha; } - m_filtLPY[which][0] = (m_LPb0 * (inSamp + m_filtLPX[which][2]) + m_LPb1 * m_filtLPX[which][1] - m_LPa1 * m_filtLPY[which][1] - m_LPa2 * m_filtLPY[which][2]) / m_LPa0; + m_filtLPY[channel][0] = (m_LPb0 * (inSamp + m_filtLPX[channel][2]) + m_LPb1 * m_filtLPX[channel][1] - + m_LPa1 * m_filtLPY[channel][1] - m_LPa2 * m_filtLPY[channel][2]) / m_LPa0; - m_filtLPX[which][2] = m_filtLPX[which][1]; - m_filtLPX[which][1] = inSamp; - m_filtLPY[which][2] = m_filtLPY[which][1]; - m_filtLPY[which][1] = m_filtLPY[which][0]; + m_filtLPX[channel][2] = m_filtLPX[channel][1]; + m_filtLPX[channel][1] = inSamp; + m_filtLPY[channel][2] = m_filtLPY[channel][1]; + m_filtLPY[channel][1] = m_filtLPY[channel][0]; - outSamp = m_filtLPY[which][0]; + outSamp = m_filtLPY[channel][0]; } -inline void DisintegratorEffect::calcHighpassFilter(sample_t &outSamp, sample_t inSamp, int which, float hpCutoff, float resonance, sample_rate_t Fs) +inline void DisintegratorEffect::calcHighpassFilter(sample_t &outSamp, sample_t inSamp, int channel, float hpCutoff, sample_rate_t sampleRate) { // "if" statement is here so the filter coefficients only need to be calculated when they change - if (m_prevHPCutoff[which] != hpCutoff) + if (m_prevHPCutoff[channel] != hpCutoff) { - m_prevHPCutoff[which] = hpCutoff; - const float w0 = D_2PI * hpCutoff / Fs; + m_prevHPCutoff[channel] = hpCutoff; + const float w0 = D_2PI * hpCutoff / sampleRate; const float tempCosW0 = cos(w0); const float alpha = sin(w0) / 0.3535f; @@ -249,14 +251,15 @@ inline void DisintegratorEffect::calcHighpassFilter(sample_t &outSamp, sample_t m_HPa2 = 1 - alpha; } - m_filtHPY[which][0] = (m_HPb0 * (inSamp + m_filtHPX[which][2]) + m_HPb1 * m_filtHPX[which][1] - m_HPa1 * m_filtHPY[which][1] - m_HPa2 * m_filtHPY[which][2]) / m_HPa0; + m_filtHPY[channel][0] = (m_HPb0 * (inSamp + m_filtHPX[channel][2]) + m_HPb1 * m_filtHPX[channel][1] - + m_HPa1 * m_filtHPY[channel][1] - m_HPa2 * m_filtHPY[channel][2]) / m_HPa0; - m_filtHPX[which][2] = m_filtHPX[which][1]; - m_filtHPX[which][1] = inSamp; - m_filtHPY[which][2] = m_filtHPY[which][1]; - m_filtHPY[which][1] = m_filtHPY[which][0]; + m_filtHPX[channel][2] = m_filtHPX[channel][1]; + m_filtHPX[channel][1] = inSamp; + m_filtHPY[channel][2] = m_filtHPY[channel][1]; + m_filtHPY[channel][1] = m_filtHPY[channel][0]; - outSamp = m_filtHPY[which][0]; + outSamp = m_filtHPY[channel][0]; } @@ -264,7 +267,8 @@ inline void DisintegratorEffect::calcHighpassFilter(sample_t &outSamp, sample_t // Handles negative values properly, unlike fmod. inline float DisintegratorEffect::realfmod(float k, float n) { - return ((k = fmod(k,n)) < 0) ? k+n : k; + float r = fmod(k, n); + return r < 0 ? r + n : r; } diff --git a/plugins/Disintegrator/Disintegrator.h b/plugins/Disintegrator/Disintegrator.h index 271cbac10..04c7bdb82 100644 --- a/plugins/Disintegrator/Disintegrator.h +++ b/plugins/Disintegrator/Disintegrator.h @@ -31,6 +31,10 @@ #include "Effect.h" #include "ValueBuffer.h" + +const int DISINTEGRATOR_BUFFER_SIZE = 200; + + class DisintegratorEffect : public Effect { public: @@ -45,8 +49,8 @@ public: inline float realfmod(float k, float n); - inline void calcLowpassFilter(sample_t &outSamp, sample_t inSamp, int which, float lpCutoff, float resonance, sample_rate_t Fs); - inline void calcHighpassFilter(sample_t &outSamp, sample_t inSamp, int which, float lpCutoff, float resonance, sample_rate_t Fs); + inline void calcLowpassFilter(sample_t &outSamp, sample_t inSamp, int channel, float lpCutoff, sample_rate_t sampleRate); + inline void calcHighpassFilter(sample_t &outSamp, sample_t inSamp, int channel, float lpCutoff, sample_rate_t sampleRate); float m_filtLPX[2][3] = {{0}};// [filter number][samples back in time] float m_filtLPY[2][3] = {{0}};// [filter number][samples back in time] diff --git a/plugins/Disintegrator/DisintegratorControls.cpp b/plugins/Disintegrator/DisintegratorControls.cpp index cb403ea45..a628cfbeb 100644 --- a/plugins/Disintegrator/DisintegratorControls.cpp +++ b/plugins/Disintegrator/DisintegratorControls.cpp @@ -35,8 +35,8 @@ DisintegratorControls::DisintegratorControls(DisintegratorEffect* effect) : EffectControls(effect), m_effect(effect), - m_lowCutModel(2.0f, 2.0f, 21050.0f, 0.01f, this, tr("Low Cut")), - m_highCutModel(21050.0f, 2.0f, 21050.0f, 0.01f, this, tr("High Cut")), + m_lowCutModel(2.0f, 2.0f, 20000.0f, 0.01f, this, tr("Low Cut Frequency")), + m_highCutModel(20000.0f, 2.0f, 20000.0f, 0.01f, this, tr("High Cut Frequency")), m_amountModel(30.0f, 0.0f, 200.0f, 0.01f, this, tr("Amount")), m_typeModel(this, tr("Type")), m_freqModel(100.0f, 2.0f, 21050.0f, 0.01f, this, tr("Frequency")) From 5a4670eac2dcfd2e0387a710ac5f8164428ff553 Mon Sep 17 00:00:00 2001 From: root Date: Fri, 30 Aug 2019 07:34:36 -0600 Subject: [PATCH 05/20] Changed filters to use BasicFilters.h, fixed crashing bug (caused by last commit). --- plugins/Disintegrator/Disintegrator.cpp | 118 +++++++----------- plugins/Disintegrator/Disintegrator.h | 30 ++--- .../Disintegrator/DisintegratorControls.cpp | 12 ++ plugins/Disintegrator/DisintegratorControls.h | 3 + 4 files changed, 66 insertions(+), 97 deletions(-) diff --git a/plugins/Disintegrator/Disintegrator.cpp b/plugins/Disintegrator/Disintegrator.cpp index d4c883ada..2498591d0 100644 --- a/plugins/Disintegrator/Disintegrator.cpp +++ b/plugins/Disintegrator/Disintegrator.cpp @@ -35,7 +35,7 @@ Plugin::Descriptor PLUGIN_EXPORT disintegrator_plugin_descriptor = { STRINGIFY(PLUGIN_NAME), "Disintegrator", - QT_TRANSLATE_NOOP("pluginBrowser", "A delay modulation effect for creating very aggressive digital distortion."), + QT_TRANSLATE_NOOP("pluginBrowser", "A delay modulation effect for very aggressive digital distortion."), "Lost Robot ", 0x0100, Plugin::Effect, @@ -50,15 +50,18 @@ 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_disintegratorControls(this), + m_lp( Engine::mixer()->processingSampleRate() ), + m_hp( Engine::mixer()->processingSampleRate() ), + m_needsUpdate( true ) { // Fill buffer with DISINTEGRATOR_BUFFER_SIZE number of samples - for (int i = 0; i < DISINTEGRATOR_BUFFER_SIZE; ++i) + for (int i = 0; i < 2; ++i) { m_inBuf[i].reserve(DISINTEGRATOR_BUFFER_SIZE); - for (int j = 0; j < 2; ++j) + for (int j = 0; j < DISINTEGRATOR_BUFFER_SIZE; ++j) { - m_inBuf[j].push_back(0); + m_inBuf[i].push_back(0); } } } @@ -72,6 +75,15 @@ DisintegratorEffect::~DisintegratorEffect() +void DisintegratorEffect::sampleRateChanged() +{ + sample_rate_t sampleRate = Engine::mixer()->processingSampleRate(); + m_lp.setSampleRate( sampleRate ); + m_hp.setSampleRate( sampleRate ); + m_needsUpdate = true; +} + + bool DisintegratorEffect::processAudioBuffer(sampleFrame* buf, const fpp_t frames) { @@ -84,18 +96,26 @@ bool DisintegratorEffect::processAudioBuffer(sampleFrame* buf, const fpp_t frame const float d = dryLevel(); const float w = wetLevel(); - const ValueBuffer * lowCutBuf = m_disintegratorControls.m_lowCutModel.valueBuffer(); - const ValueBuffer * highCutBuf = m_disintegratorControls.m_highCutModel.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(); sample_rate_t sampleRate = Engine::mixer()->processingSampleRate(); + // Update filters + if( m_needsUpdate || m_disintegratorControls.m_highCutModel.isValueChanged() ) + { + m_lp.setLowpass( m_disintegratorControls.m_highCutModel.value() ); + + } + if( m_needsUpdate || m_disintegratorControls.m_lowCutModel.isValueChanged() ) + { + m_hp.setHighpass( m_disintegratorControls.m_lowCutModel.value() ); + } + m_needsUpdate = false; + for (fpp_t f = 0; f < frames; ++f) { - const float lowCut = lowCutBuf ? lowCutBuf->value(f) : m_disintegratorControls.m_lowCutModel.value(); - const float highCut = highCutBuf ? highCutBuf->value(f) : m_disintegratorControls.m_highCutModel.value(); const float amount = amountBuf ? amountBuf->value(f) : m_disintegratorControls.m_amountModel.value(); const int type = typeBuf ? typeBuf->value(f) : m_disintegratorControls.m_typeModel.value(); const float freq = freqBuf ? freqBuf->value(f) : m_disintegratorControls.m_freqModel.value(); @@ -126,8 +146,8 @@ bool DisintegratorEffect::processAudioBuffer(sampleFrame* buf, const fpp_t frame { newInBufLoc[0] = fast_rand() / (float)FAST_RAND_MAX; - calcHighpassFilter(newInBufLoc[0], newInBufLoc[0], 0, lowCut, sampleRate); - calcLowpassFilter(newInBufLoc[0], newInBufLoc[0], 0, highCut, sampleRate); + newInBufLoc[0] = m_hp.update( newInBufLoc[0], 0 ); + newInBufLoc[0] = m_lp.update( newInBufLoc[0], 0 ); newInBufLoc[0] = realfmod(m_inBufLoc - newInBufLoc[0] * amount, DISINTEGRATOR_BUFFER_SIZE); newInBufLoc[1] = newInBufLoc[0]; @@ -143,10 +163,10 @@ bool DisintegratorEffect::processAudioBuffer(sampleFrame* buf, const fpp_t frame newInBufLoc[0] = fast_rand() / (float)FAST_RAND_MAX; newInBufLoc[1] = fast_rand() / (float)FAST_RAND_MAX; - calcHighpassFilter(newInBufLoc[0], newInBufLoc[0], 0, lowCut, sampleRate); - calcHighpassFilter(newInBufLoc[1], newInBufLoc[1], 1, lowCut, sampleRate); - calcLowpassFilter(newInBufLoc[0], newInBufLoc[0], 0, highCut, sampleRate); - calcLowpassFilter(newInBufLoc[1], newInBufLoc[1], 1, highCut, sampleRate); + newInBufLoc[0] = m_hp.update( newInBufLoc[0], 0 ); + newInBufLoc[0] = m_lp.update( newInBufLoc[0], 0 ); + newInBufLoc[1] = m_hp.update( newInBufLoc[1], 1 ); + newInBufLoc[1] = m_lp.update( newInBufLoc[1], 1 ); newInBufLoc[0] = realfmod(m_inBufLoc - newInBufLoc[0] * amount, DISINTEGRATOR_BUFFER_SIZE); newInBufLoc[1] = realfmod(m_inBufLoc - newInBufLoc[1] * amount, DISINTEGRATOR_BUFFER_SIZE); @@ -204,66 +224,6 @@ bool DisintegratorEffect::processAudioBuffer(sampleFrame* buf, const fpp_t frame -inline void DisintegratorEffect::calcLowpassFilter(sample_t &outSamp, sample_t inSamp, int channel, float lpCutoff, sample_rate_t sampleRate) -{ - // "if" statement is here so the filter coefficients only need to be calculated when they change - if (m_prevLPCutoff[channel] != lpCutoff) - { - m_prevLPCutoff[channel] = lpCutoff; - const float w0 = D_2PI * lpCutoff / sampleRate; - const float tempCosW0 = cos(w0); - const float alpha = sin(w0) / 0.3535f; - - m_LPa0 = 1 + alpha; - m_LPb0 = (1 - tempCosW0) * 0.5f; - m_LPb1 = 1 - tempCosW0; - m_LPa1 = -(2 * tempCosW0); - m_LPa2 = 1 - alpha; - } - - m_filtLPY[channel][0] = (m_LPb0 * (inSamp + m_filtLPX[channel][2]) + m_LPb1 * m_filtLPX[channel][1] - - m_LPa1 * m_filtLPY[channel][1] - m_LPa2 * m_filtLPY[channel][2]) / m_LPa0; - - m_filtLPX[channel][2] = m_filtLPX[channel][1]; - m_filtLPX[channel][1] = inSamp; - m_filtLPY[channel][2] = m_filtLPY[channel][1]; - m_filtLPY[channel][1] = m_filtLPY[channel][0]; - - outSamp = m_filtLPY[channel][0]; -} - - - -inline void DisintegratorEffect::calcHighpassFilter(sample_t &outSamp, sample_t inSamp, int channel, float hpCutoff, sample_rate_t sampleRate) -{ - // "if" statement is here so the filter coefficients only need to be calculated when they change - if (m_prevHPCutoff[channel] != hpCutoff) - { - m_prevHPCutoff[channel] = hpCutoff; - const float w0 = D_2PI * hpCutoff / sampleRate; - const float tempCosW0 = cos(w0); - const float alpha = sin(w0) / 0.3535f; - - m_HPa0 = 1 + alpha; - m_HPb0 = (1 + tempCosW0) * 0.5f; - m_HPb1 = -(1 + tempCosW0); - m_HPa1 = -2 * tempCosW0; - m_HPa2 = 1 - alpha; - } - - m_filtHPY[channel][0] = (m_HPb0 * (inSamp + m_filtHPX[channel][2]) + m_HPb1 * m_filtHPX[channel][1] - - m_HPa1 * m_filtHPY[channel][1] - m_HPa2 * m_filtHPY[channel][2]) / m_HPa0; - - m_filtHPX[channel][2] = m_filtHPX[channel][1]; - m_filtHPX[channel][1] = inSamp; - m_filtHPY[channel][2] = m_filtHPY[channel][1]; - m_filtHPY[channel][1] = m_filtHPY[channel][0]; - - outSamp = m_filtHPY[channel][0]; -} - - - // Handles negative values properly, unlike fmod. inline float DisintegratorEffect::realfmod(float k, float n) { @@ -273,6 +233,14 @@ inline float DisintegratorEffect::realfmod(float k, float n) +void DisintegratorEffect::clearFilterHistories() +{ + m_lp.clearHistory(); + m_hp.clearHistory(); +} + + + extern "C" { diff --git a/plugins/Disintegrator/Disintegrator.h b/plugins/Disintegrator/Disintegrator.h index 04c7bdb82..cd7642f71 100644 --- a/plugins/Disintegrator/Disintegrator.h +++ b/plugins/Disintegrator/Disintegrator.h @@ -28,6 +28,7 @@ #include "DisintegratorControls.h" +#include "BasicFilters.h" #include "Effect.h" #include "ValueBuffer.h" @@ -47,30 +48,11 @@ public: return &m_disintegratorControls; } + void sampleRateChanged(); + inline float realfmod(float k, float n); - inline void calcLowpassFilter(sample_t &outSamp, sample_t inSamp, int channel, float lpCutoff, sample_rate_t sampleRate); - inline void calcHighpassFilter(sample_t &outSamp, sample_t inSamp, int channel, float lpCutoff, sample_rate_t sampleRate); - - float m_filtLPX[2][3] = {{0}};// [filter number][samples back in time] - float m_filtLPY[2][3] = {{0}};// [filter number][samples back in time] - float m_prevLPCutoff[2] = {0}; - - float m_LPa0; - float m_LPb0; - float m_LPb1; - float m_LPa1; - float m_LPa2; - - float m_filtHPX[2][3] = {{0}};// [filter number][samples back in time] - float m_filtHPY[2][3] = {{0}};// [filter number][samples back in time] - float m_prevHPCutoff[2] = {0}; - - float m_HPa0; - float m_HPb0; - float m_HPb1; - float m_HPa1; - float m_HPa2; + void clearFilterHistories(); private: DisintegratorControls m_disintegratorControls; @@ -80,6 +62,10 @@ private: float m_sineLoc = 0; + StereoLinkwitzRiley m_lp; + StereoLinkwitzRiley m_hp; + bool m_needsUpdate; + friend class DisintegratorControls; } ; diff --git a/plugins/Disintegrator/DisintegratorControls.cpp b/plugins/Disintegrator/DisintegratorControls.cpp index a628cfbeb..7528066f1 100644 --- a/plugins/Disintegrator/DisintegratorControls.cpp +++ b/plugins/Disintegrator/DisintegratorControls.cpp @@ -50,6 +50,8 @@ DisintegratorControls::DisintegratorControls(DisintegratorEffect* effect) : m_typeModel.addItem(tr("Mono Noise")); m_typeModel.addItem(tr("Stereo Noise")); m_typeModel.addItem(tr("Sine Wave")); + + connect( Engine::mixer(), SIGNAL( sampleRateChanged() ), this, SLOT( sampleRateChanged() ) ); } @@ -71,4 +73,14 @@ void DisintegratorControls::loadSettings(const QDomElement& _this) m_amountModel.loadSettings(_this, "amount"); m_typeModel.loadSettings(_this, "type"); m_freqModel.loadSettings(_this, "freq"); + + m_effect->m_needsUpdate = true; + m_effect->clearFilterHistories(); +} + + + +void DisintegratorControls::sampleRateChanged() +{ + m_effect->sampleRateChanged(); } diff --git a/plugins/Disintegrator/DisintegratorControls.h b/plugins/Disintegrator/DisintegratorControls.h index c8611cf92..11316cc08 100644 --- a/plugins/Disintegrator/DisintegratorControls.h +++ b/plugins/Disintegrator/DisintegratorControls.h @@ -62,6 +62,9 @@ public: return m_effectView; } +private slots: + void sampleRateChanged(); + private: DisintegratorEffect* m_effect; DisintegratorControlDialog * m_effectView; From 328c7654ab9d7513f49d014ca2c6f37683574273 Mon Sep 17 00:00:00 2001 From: root Date: Fri, 30 Aug 2019 10:23:30 -0600 Subject: [PATCH 06/20] Increase buffer size to correct amount --- plugins/Disintegrator/Disintegrator.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/plugins/Disintegrator/Disintegrator.h b/plugins/Disintegrator/Disintegrator.h index cd7642f71..153771b21 100644 --- a/plugins/Disintegrator/Disintegrator.h +++ b/plugins/Disintegrator/Disintegrator.h @@ -33,7 +33,7 @@ #include "ValueBuffer.h" -const int DISINTEGRATOR_BUFFER_SIZE = 200; +const int DISINTEGRATOR_BUFFER_SIZE = 201; class DisintegratorEffect : public Effect From 6b09fce36d2d548c6b5efb89e9c5b75996f15a7c Mon Sep 17 00:00:00 2001 From: root Date: Fri, 30 Aug 2019 11:31:26 -0600 Subject: [PATCH 07/20] Add self-modulation mode --- plugins/Disintegrator/Disintegrator.cpp | 19 +++++++++++++++++++ .../Disintegrator/DisintegratorControls.cpp | 1 + 2 files changed, 20 insertions(+) diff --git a/plugins/Disintegrator/Disintegrator.cpp b/plugins/Disintegrator/Disintegrator.cpp index 2498591d0..57aba185c 100644 --- a/plugins/Disintegrator/Disintegrator.cpp +++ b/plugins/Disintegrator/Disintegrator.cpp @@ -190,6 +190,25 @@ bool DisintegratorEffect::processAudioBuffer(sampleFrame* buf, const fpp_t frame newInBufLocFrac[0] = fmod(newInBufLoc[0], 1); newInBufLocFrac[1] = newInBufLocFrac[0]; + break; + } + case 3:// Self-Modulation + { + newInBufLoc[0] = (s[0] + 1) * 0.5f; + newInBufLoc[1] = (s[1] + 1) * 0.5f; + + newInBufLoc[0] = m_hp.update( newInBufLoc[0], 0 ); + newInBufLoc[0] = m_lp.update( newInBufLoc[0], 0 ); + newInBufLoc[1] = m_hp.update( newInBufLoc[1], 1 ); + newInBufLoc[1] = m_lp.update( newInBufLoc[1], 1 ); + + newInBufLoc[0] = realfmod(m_inBufLoc - newInBufLoc[0] * amount, DISINTEGRATOR_BUFFER_SIZE); + newInBufLoc[1] = realfmod(m_inBufLoc - newInBufLoc[1] * amount, DISINTEGRATOR_BUFFER_SIZE); + + // Distance between samples + newInBufLocFrac[0] = fmod(newInBufLoc[0], 1); + newInBufLocFrac[1] = fmod(newInBufLoc[1], 1); + break; } } diff --git a/plugins/Disintegrator/DisintegratorControls.cpp b/plugins/Disintegrator/DisintegratorControls.cpp index 7528066f1..b92a99db3 100644 --- a/plugins/Disintegrator/DisintegratorControls.cpp +++ b/plugins/Disintegrator/DisintegratorControls.cpp @@ -50,6 +50,7 @@ DisintegratorControls::DisintegratorControls(DisintegratorEffect* effect) : 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() ) ); } From 4556151c03aa68f0ca407a1cd73aaddf5e15e7b9 Mon Sep 17 00:00:00 2001 From: root Date: Fri, 30 Aug 2019 12:00:45 -0600 Subject: [PATCH 08/20] Clip modulator at 0db for self-modulation mode --- plugins/Disintegrator/Disintegrator.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/plugins/Disintegrator/Disintegrator.cpp b/plugins/Disintegrator/Disintegrator.cpp index 57aba185c..975910fab 100644 --- a/plugins/Disintegrator/Disintegrator.cpp +++ b/plugins/Disintegrator/Disintegrator.cpp @@ -194,8 +194,8 @@ bool DisintegratorEffect::processAudioBuffer(sampleFrame* buf, const fpp_t frame } case 3:// Self-Modulation { - newInBufLoc[0] = (s[0] + 1) * 0.5f; - newInBufLoc[1] = (s[1] + 1) * 0.5f; + newInBufLoc[0] = (qBound(-1.f, s[0], 1.f) + 1) * 0.5f; + newInBufLoc[1] = (qBound(-1.f, s[1], 1.f) + 1) * 0.5f; newInBufLoc[0] = m_hp.update( newInBufLoc[0], 0 ); newInBufLoc[0] = m_lp.update( newInBufLoc[0], 0 ); From 02b9a2e6d6b43ac0b0ab171d5d05bcc0427790d6 Mon Sep 17 00:00:00 2001 From: root Date: Tue, 3 Sep 2019 21:12:45 -0600 Subject: [PATCH 09/20] Minor CPU boost I missed --- plugins/Disintegrator/Disintegrator.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/plugins/Disintegrator/Disintegrator.cpp b/plugins/Disintegrator/Disintegrator.cpp index 975910fab..24cf5fbb9 100644 --- a/plugins/Disintegrator/Disintegrator.cpp +++ b/plugins/Disintegrator/Disintegrator.cpp @@ -215,7 +215,7 @@ bool DisintegratorEffect::processAudioBuffer(sampleFrame* buf, const fpp_t frame for (int i = 0; i < 2; ++i) { - if (fmod(newInBufLoc[i], 1) == 0) + if (newInBufLocFrac[i] == 0) { s[i] = m_inBuf[i][newInBufLoc[i]]; } From d2cb54f6e623f731fa5e60fb059423774678a8a7 Mon Sep 17 00:00:00 2001 From: Lost Robot <34612565+DouglasDGI@users.noreply.github.com> Date: Sat, 23 Nov 2019 17:45:19 -0700 Subject: [PATCH 10/20] Hippity hoppity squash and merge hides this probably --- cmake/modules/PluginList.cmake | 1 + 1 file changed, 1 insertion(+) diff --git a/cmake/modules/PluginList.cmake b/cmake/modules/PluginList.cmake index c82bba329..3e69f4ddf 100644 --- a/cmake/modules/PluginList.cmake +++ b/cmake/modules/PluginList.cmake @@ -32,6 +32,7 @@ SET(LMMS_PLUGIN_LIST carlarack CrossoverEQ Delay + Disintegrator DualFilter dynamics_processor Eq From 06024b85e78c2b5a5cd5a6d5f6c6c2c3f11c0be5 Mon Sep 17 00:00:00 2001 From: Lost Robot <34612565+DouglasDGI@users.noreply.github.com> Date: Sat, 23 Nov 2019 18:06:03 -0700 Subject: [PATCH 11/20] Fix knob ranges --- plugins/Disintegrator/DisintegratorControls.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/plugins/Disintegrator/DisintegratorControls.cpp b/plugins/Disintegrator/DisintegratorControls.cpp index b92a99db3..d0207d721 100644 --- a/plugins/Disintegrator/DisintegratorControls.cpp +++ b/plugins/Disintegrator/DisintegratorControls.cpp @@ -35,11 +35,11 @@ DisintegratorControls::DisintegratorControls(DisintegratorEffect* effect) : EffectControls(effect), m_effect(effect), - m_lowCutModel(2.0f, 2.0f, 20000.0f, 0.01f, this, tr("Low Cut Frequency")), - m_highCutModel(20000.0f, 2.0f, 20000.0f, 0.01f, this, tr("High Cut Frequency")), + 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(30.0f, 0.0f, 200.0f, 0.01f, this, tr("Amount")), m_typeModel(this, tr("Type")), - m_freqModel(100.0f, 2.0f, 21050.0f, 0.01f, this, tr("Frequency")) + 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); From 89f05018c339e2c49b37f37a839be0c8ca9d8484 Mon Sep 17 00:00:00 2001 From: root Date: Sat, 18 Apr 2020 14:43:26 -0600 Subject: [PATCH 12/20] Resolve code/style reviews --- plugins/Disintegrator/Disintegrator.cpp | 49 ++++++++----------- plugins/Disintegrator/Disintegrator.h | 7 ++- .../DisintegratorControlDialog.cpp | 5 +- .../DisintegratorControlDialog.h | 4 -- .../Disintegrator/DisintegratorControls.cpp | 2 +- plugins/Disintegrator/DisintegratorControls.h | 17 +++---- 6 files changed, 33 insertions(+), 51 deletions(-) diff --git a/plugins/Disintegrator/Disintegrator.cpp b/plugins/Disintegrator/Disintegrator.cpp index 24cf5fbb9..89c4a43f2 100644 --- a/plugins/Disintegrator/Disintegrator.cpp +++ b/plugins/Disintegrator/Disintegrator.cpp @@ -51,9 +51,9 @@ 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_lp( Engine::mixer()->processingSampleRate() ), - m_hp( Engine::mixer()->processingSampleRate() ), - m_needsUpdate( true ) + m_lp(Engine::mixer()->processingSampleRate()), + m_hp(Engine::mixer()->processingSampleRate()), + m_needsUpdate(true) { // Fill buffer with DISINTEGRATOR_BUFFER_SIZE number of samples for (int i = 0; i < 2; ++i) @@ -68,18 +68,11 @@ DisintegratorEffect::DisintegratorEffect(Model* parent, const Descriptor::SubPlu - -DisintegratorEffect::~DisintegratorEffect() -{ -} - - - void DisintegratorEffect::sampleRateChanged() { sample_rate_t sampleRate = Engine::mixer()->processingSampleRate(); - m_lp.setSampleRate( sampleRate ); - m_hp.setSampleRate( sampleRate ); + m_lp.setSampleRate(sampleRate); + m_hp.setSampleRate(sampleRate); m_needsUpdate = true; } @@ -103,14 +96,14 @@ bool DisintegratorEffect::processAudioBuffer(sampleFrame* buf, const fpp_t frame sample_rate_t sampleRate = Engine::mixer()->processingSampleRate(); // Update filters - if( m_needsUpdate || m_disintegratorControls.m_highCutModel.isValueChanged() ) + if(m_needsUpdate || m_disintegratorControls.m_highCutModel.isValueChanged()) { - m_lp.setLowpass( m_disintegratorControls.m_highCutModel.value() ); + m_lp.setLowpass(m_disintegratorControls.m_highCutModel.value()); } - if( m_needsUpdate || m_disintegratorControls.m_lowCutModel.isValueChanged() ) + if(m_needsUpdate || m_disintegratorControls.m_lowCutModel.isValueChanged()) { - m_hp.setHighpass( m_disintegratorControls.m_lowCutModel.value() ); + m_hp.setHighpass(m_disintegratorControls.m_lowCutModel.value()); } m_needsUpdate = false; @@ -119,8 +112,6 @@ bool DisintegratorEffect::processAudioBuffer(sampleFrame* buf, const fpp_t frame const float amount = amountBuf ? amountBuf->value(f) : m_disintegratorControls.m_amountModel.value(); const int type = typeBuf ? typeBuf->value(f) : m_disintegratorControls.m_typeModel.value(); const float freq = freqBuf ? freqBuf->value(f) : m_disintegratorControls.m_freqModel.value(); - - outSum += buf[f][0]*buf[f][0] + buf[f][1]*buf[f][1]; sample_t s[2] = {buf[f][0], buf[f][1]}; @@ -146,8 +137,8 @@ bool DisintegratorEffect::processAudioBuffer(sampleFrame* buf, const fpp_t frame { newInBufLoc[0] = fast_rand() / (float)FAST_RAND_MAX; - newInBufLoc[0] = m_hp.update( newInBufLoc[0], 0 ); - newInBufLoc[0] = m_lp.update( newInBufLoc[0], 0 ); + newInBufLoc[0] = m_hp.update(newInBufLoc[0], 0); + newInBufLoc[0] = m_lp.update(newInBufLoc[0], 0); newInBufLoc[0] = realfmod(m_inBufLoc - newInBufLoc[0] * amount, DISINTEGRATOR_BUFFER_SIZE); newInBufLoc[1] = newInBufLoc[0]; @@ -163,10 +154,10 @@ bool DisintegratorEffect::processAudioBuffer(sampleFrame* buf, const fpp_t frame newInBufLoc[0] = fast_rand() / (float)FAST_RAND_MAX; newInBufLoc[1] = fast_rand() / (float)FAST_RAND_MAX; - newInBufLoc[0] = m_hp.update( newInBufLoc[0], 0 ); - newInBufLoc[0] = m_lp.update( newInBufLoc[0], 0 ); - newInBufLoc[1] = m_hp.update( newInBufLoc[1], 1 ); - newInBufLoc[1] = m_lp.update( newInBufLoc[1], 1 ); + newInBufLoc[0] = m_hp.update(newInBufLoc[0], 0); + newInBufLoc[0] = m_lp.update(newInBufLoc[0], 0); + newInBufLoc[1] = m_hp.update(newInBufLoc[1], 1); + newInBufLoc[1] = m_lp.update(newInBufLoc[1], 1); newInBufLoc[0] = realfmod(m_inBufLoc - newInBufLoc[0] * amount, DISINTEGRATOR_BUFFER_SIZE); newInBufLoc[1] = realfmod(m_inBufLoc - newInBufLoc[1] * amount, DISINTEGRATOR_BUFFER_SIZE); @@ -197,10 +188,10 @@ bool DisintegratorEffect::processAudioBuffer(sampleFrame* buf, const fpp_t frame newInBufLoc[0] = (qBound(-1.f, s[0], 1.f) + 1) * 0.5f; newInBufLoc[1] = (qBound(-1.f, s[1], 1.f) + 1) * 0.5f; - newInBufLoc[0] = m_hp.update( newInBufLoc[0], 0 ); - newInBufLoc[0] = m_lp.update( newInBufLoc[0], 0 ); - newInBufLoc[1] = m_hp.update( newInBufLoc[1], 1 ); - newInBufLoc[1] = m_lp.update( newInBufLoc[1], 1 ); + newInBufLoc[0] = m_hp.update(newInBufLoc[0], 0); + newInBufLoc[0] = m_lp.update(newInBufLoc[0], 0); + newInBufLoc[1] = m_hp.update(newInBufLoc[1], 1); + newInBufLoc[1] = m_lp.update(newInBufLoc[1], 1); newInBufLoc[0] = realfmod(m_inBufLoc - newInBufLoc[0] * amount, DISINTEGRATOR_BUFFER_SIZE); newInBufLoc[1] = realfmod(m_inBufLoc - newInBufLoc[1] * amount, DISINTEGRATOR_BUFFER_SIZE); @@ -234,6 +225,8 @@ bool DisintegratorEffect::processAudioBuffer(sampleFrame* buf, const fpp_t frame 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); diff --git a/plugins/Disintegrator/Disintegrator.h b/plugins/Disintegrator/Disintegrator.h index 153771b21..e3ff28cbc 100644 --- a/plugins/Disintegrator/Disintegrator.h +++ b/plugins/Disintegrator/Disintegrator.h @@ -33,17 +33,16 @@ #include "ValueBuffer.h" -const int DISINTEGRATOR_BUFFER_SIZE = 201; +constexpr int DISINTEGRATOR_BUFFER_SIZE = 201; class DisintegratorEffect : public Effect { public: DisintegratorEffect(Model* parent, const Descriptor::SubPluginFeatures::Key* key); - virtual ~DisintegratorEffect(); - virtual bool processAudioBuffer(sampleFrame* buf, const fpp_t frames); + bool processAudioBuffer(sampleFrame* buf, const fpp_t frames) override; - virtual EffectControls* controls() + EffectControls* controls() override { return &m_disintegratorControls; } diff --git a/plugins/Disintegrator/DisintegratorControlDialog.cpp b/plugins/Disintegrator/DisintegratorControlDialog.cpp index 97a8a2718..d7f0be5ca 100644 --- a/plugins/Disintegrator/DisintegratorControlDialog.cpp +++ b/plugins/Disintegrator/DisintegratorControlDialog.cpp @@ -33,10 +33,9 @@ DisintegratorControlDialog::DisintegratorControlDialog(DisintegratorControls* controls) : - EffectControlDialog(controls) + EffectControlDialog(controls), + m_controls(controls) { - m_controls = controls; - setAutoFillBackground(true); QPalette pal; pal.setBrush(backgroundRole(), PLUGIN_NAME::getIconPixmap("artwork")); diff --git a/plugins/Disintegrator/DisintegratorControlDialog.h b/plugins/Disintegrator/DisintegratorControlDialog.h index 2c9938318..9ce4bc667 100644 --- a/plugins/Disintegrator/DisintegratorControlDialog.h +++ b/plugins/Disintegrator/DisintegratorControlDialog.h @@ -40,10 +40,6 @@ public: DisintegratorControlDialog(DisintegratorControls* controls); DisintegratorControls * m_controls; - virtual ~DisintegratorControlDialog() - { - } - private slots: void updateKnobVisibility(); diff --git a/plugins/Disintegrator/DisintegratorControls.cpp b/plugins/Disintegrator/DisintegratorControls.cpp index d0207d721..a2a213c0c 100644 --- a/plugins/Disintegrator/DisintegratorControls.cpp +++ b/plugins/Disintegrator/DisintegratorControls.cpp @@ -52,7 +52,7 @@ DisintegratorControls::DisintegratorControls(DisintegratorEffect* effect) : m_typeModel.addItem(tr("Sine Wave")); m_typeModel.addItem(tr("Self-Modulation")); - connect( Engine::mixer(), SIGNAL( sampleRateChanged() ), this, SLOT( sampleRateChanged() ) ); + connect(Engine::mixer(), SIGNAL(sampleRateChanged()), this, SLOT(sampleRateChanged())); } diff --git a/plugins/Disintegrator/DisintegratorControls.h b/plugins/Disintegrator/DisintegratorControls.h index 11316cc08..0be62c570 100644 --- a/plugins/Disintegrator/DisintegratorControls.h +++ b/plugins/Disintegrator/DisintegratorControls.h @@ -40,26 +40,22 @@ class DisintegratorControls : public EffectControls Q_OBJECT public: DisintegratorControls(DisintegratorEffect* effect); - virtual ~DisintegratorControls() - { - } - virtual void saveSettings(QDomDocument & _doc, QDomElement & _parent); - virtual void loadSettings(const QDomElement & _this); - inline virtual QString nodeName() const + void saveSettings(QDomDocument & _doc, QDomElement & _parent) override; + void loadSettings(const QDomElement & _this) override; + inline QString nodeName() const override { return "DisintegratorControls"; } - virtual int controlCount() + int controlCount() override { return 5; } - virtual EffectControlDialog* createView() + EffectControlDialog* createView() override { - m_effectView = new DisintegratorControlDialog(this); - return m_effectView; + return new DisintegratorControlDialog(this); } private slots: @@ -67,7 +63,6 @@ private slots: private: DisintegratorEffect* m_effect; - DisintegratorControlDialog * m_effectView; FloatModel m_lowCutModel; FloatModel m_highCutModel; From 624b2f24dfdf8bcc2b28cf0dcb2444117a35f324 Mon Sep 17 00:00:00 2001 From: root Date: Sat, 18 Apr 2020 14:48:29 -0600 Subject: [PATCH 13/20] Put some duplicate code into for loops --- plugins/Disintegrator/Disintegrator.cpp | 40 +++++++++++-------------- 1 file changed, 18 insertions(+), 22 deletions(-) diff --git a/plugins/Disintegrator/Disintegrator.cpp b/plugins/Disintegrator/Disintegrator.cpp index 89c4a43f2..92dffeb6c 100644 --- a/plugins/Disintegrator/Disintegrator.cpp +++ b/plugins/Disintegrator/Disintegrator.cpp @@ -151,20 +151,18 @@ bool DisintegratorEffect::processAudioBuffer(sampleFrame* buf, const fpp_t frame } case 1:// Stereo Noise { - newInBufLoc[0] = fast_rand() / (float)FAST_RAND_MAX; - newInBufLoc[1] = fast_rand() / (float)FAST_RAND_MAX; + for (int i = 0; i < 2; ++i) + { + newInBufLoc[i] = fast_rand() / (float)FAST_RAND_MAX; - newInBufLoc[0] = m_hp.update(newInBufLoc[0], 0); - newInBufLoc[0] = m_lp.update(newInBufLoc[0], 0); - newInBufLoc[1] = m_hp.update(newInBufLoc[1], 1); - newInBufLoc[1] = m_lp.update(newInBufLoc[1], 1); + newInBufLoc[i] = m_hp.update(newInBufLoc[i], 0); + newInBufLoc[i] = m_lp.update(newInBufLoc[i], 0); - newInBufLoc[0] = realfmod(m_inBufLoc - newInBufLoc[0] * amount, DISINTEGRATOR_BUFFER_SIZE); - newInBufLoc[1] = realfmod(m_inBufLoc - newInBufLoc[1] * amount, DISINTEGRATOR_BUFFER_SIZE); + newInBufLoc[i] = realfmod(m_inBufLoc - newInBufLoc[i] * amount, DISINTEGRATOR_BUFFER_SIZE); - // Distance between samples - newInBufLocFrac[0] = fmod(newInBufLoc[0], 1); - newInBufLocFrac[1] = fmod(newInBufLoc[1], 1); + // Distance between samples + newInBufLocFrac[i] = fmod(newInBufLoc[i], 1); + } break; } @@ -185,20 +183,18 @@ bool DisintegratorEffect::processAudioBuffer(sampleFrame* buf, const fpp_t frame } case 3:// Self-Modulation { - newInBufLoc[0] = (qBound(-1.f, s[0], 1.f) + 1) * 0.5f; - newInBufLoc[1] = (qBound(-1.f, s[1], 1.f) + 1) * 0.5f; + for (int i = 0; i < 2; ++i) + { + newInBufLoc[i] = (qBound(-1.f, s[i], 1.f) + 1) * 0.5f; - newInBufLoc[0] = m_hp.update(newInBufLoc[0], 0); - newInBufLoc[0] = m_lp.update(newInBufLoc[0], 0); - newInBufLoc[1] = m_hp.update(newInBufLoc[1], 1); - newInBufLoc[1] = m_lp.update(newInBufLoc[1], 1); + newInBufLoc[i] = m_hp.update(newInBufLoc[i], 0); + newInBufLoc[i] = m_lp.update(newInBufLoc[i], 0); - newInBufLoc[0] = realfmod(m_inBufLoc - newInBufLoc[0] * amount, DISINTEGRATOR_BUFFER_SIZE); - newInBufLoc[1] = realfmod(m_inBufLoc - newInBufLoc[1] * amount, DISINTEGRATOR_BUFFER_SIZE); + newInBufLoc[i] = realfmod(m_inBufLoc - newInBufLoc[i] * amount, DISINTEGRATOR_BUFFER_SIZE); - // Distance between samples - newInBufLocFrac[0] = fmod(newInBufLoc[0], 1); - newInBufLocFrac[1] = fmod(newInBufLoc[1], 1); + // Distance between samples + newInBufLocFrac[i] = fmod(newInBufLoc[i], 1); + } break; } From 7e231b8b2d8a60adf6953cf06b88aac3ce40e908 Mon Sep 17 00:00:00 2001 From: root Date: Sat, 18 Apr 2020 14:50:16 -0600 Subject: [PATCH 14/20] Remove newline in untouched file --- plugins/CMakeLists.txt | 1 - 1 file changed, 1 deletion(-) diff --git a/plugins/CMakeLists.txt b/plugins/CMakeLists.txt index 77f7aa223..a4e56921f 100644 --- a/plugins/CMakeLists.txt +++ b/plugins/CMakeLists.txt @@ -14,7 +14,6 @@ INCLUDE_DIRECTORIES( "${CMAKE_BINARY_DIR}/src" ) - # See cmake/modules/PluginList.cmake FOREACH(PLUGIN ${PLUGIN_LIST}) ADD_SUBDIRECTORY(${PLUGIN}) From ee0420a67fad312b809058b966a9d3ba7681e270 Mon Sep 17 00:00:00 2001 From: root Date: Sun, 19 Apr 2020 08:21:23 -0600 Subject: [PATCH 15/20] Make effect work correctly with sample rate changes --- plugins/Disintegrator/Disintegrator.cpp | 41 ++++++++++++------------- plugins/Disintegrator/Disintegrator.h | 7 +++-- 2 files changed, 23 insertions(+), 25 deletions(-) diff --git a/plugins/Disintegrator/Disintegrator.cpp b/plugins/Disintegrator/Disintegrator.cpp index 92dffeb6c..d121485b7 100644 --- a/plugins/Disintegrator/Disintegrator.cpp +++ b/plugins/Disintegrator/Disintegrator.cpp @@ -55,25 +55,24 @@ DisintegratorEffect::DisintegratorEffect(Model* parent, const Descriptor::SubPlu m_hp(Engine::mixer()->processingSampleRate()), m_needsUpdate(true) { - // Fill buffer with DISINTEGRATOR_BUFFER_SIZE number of samples - for (int i = 0; i < 2; ++i) - { - m_inBuf[i].reserve(DISINTEGRATOR_BUFFER_SIZE); - for (int j = 0; j < DISINTEGRATOR_BUFFER_SIZE; ++j) - { - m_inBuf[i].push_back(0); - } - } + emit sampleRateChanged(); } void DisintegratorEffect::sampleRateChanged() { - sample_rate_t sampleRate = Engine::mixer()->processingSampleRate(); - m_lp.setSampleRate(sampleRate); - m_hp.setSampleRate(sampleRate); + m_sampleRate = Engine::mixer()->processingSampleRate(); + m_sampleRateMult = m_sampleRate / 44100.f; + m_lp.setSampleRate(m_sampleRate); + m_hp.setSampleRate(m_sampleRate); m_needsUpdate = true; + + m_bufferSize = (m_sampleRate / 44100.f) * 200.f + 1.f; + for (int i = 0; i < 2; ++i) + { + m_inBuf[i].resize(m_bufferSize); + } } @@ -93,8 +92,6 @@ bool DisintegratorEffect::processAudioBuffer(sampleFrame* buf, const fpp_t frame const ValueBuffer * typeBuf = m_disintegratorControls.m_typeModel.valueBuffer(); const ValueBuffer * freqBuf = m_disintegratorControls.m_lowCutModel.valueBuffer(); - sample_rate_t sampleRate = Engine::mixer()->processingSampleRate(); - // Update filters if(m_needsUpdate || m_disintegratorControls.m_highCutModel.isValueChanged()) { @@ -117,7 +114,7 @@ bool DisintegratorEffect::processAudioBuffer(sampleFrame* buf, const fpp_t frame // Increment buffer read point ++m_inBufLoc; - if (m_inBufLoc >= DISINTEGRATOR_BUFFER_SIZE) + if (m_inBufLoc >= m_bufferSize) { m_inBufLoc = 0; } @@ -140,7 +137,7 @@ bool DisintegratorEffect::processAudioBuffer(sampleFrame* buf, const fpp_t frame newInBufLoc[0] = m_hp.update(newInBufLoc[0], 0); newInBufLoc[0] = m_lp.update(newInBufLoc[0], 0); - newInBufLoc[0] = realfmod(m_inBufLoc - newInBufLoc[0] * amount, DISINTEGRATOR_BUFFER_SIZE); + newInBufLoc[0] = realfmod(m_inBufLoc - newInBufLoc[0] * amount * m_sampleRateMult, m_bufferSize); newInBufLoc[1] = newInBufLoc[0]; // Distance between samples @@ -158,7 +155,7 @@ bool DisintegratorEffect::processAudioBuffer(sampleFrame* buf, const fpp_t frame newInBufLoc[i] = m_hp.update(newInBufLoc[i], 0); newInBufLoc[i] = m_lp.update(newInBufLoc[i], 0); - newInBufLoc[i] = realfmod(m_inBufLoc - newInBufLoc[i] * amount, DISINTEGRATOR_BUFFER_SIZE); + newInBufLoc[i] = realfmod(m_inBufLoc - newInBufLoc[i] * amount * m_sampleRateMult, m_bufferSize); // Distance between samples newInBufLocFrac[i] = fmod(newInBufLoc[i], 1); @@ -168,11 +165,11 @@ bool DisintegratorEffect::processAudioBuffer(sampleFrame* buf, const fpp_t frame } case 2:// Sine Wave { - m_sineLoc = fmod(m_sineLoc + (freq / (float)sampleRate * F_2PI), F_2PI); + m_sineLoc = fmod(m_sineLoc + (freq / m_sampleRate * F_2PI), F_2PI); newInBufLoc[0] = (sin(m_sineLoc) + 1) * 0.5f; - newInBufLoc[0] = realfmod(m_inBufLoc - newInBufLoc[0] * amount, DISINTEGRATOR_BUFFER_SIZE); + newInBufLoc[0] = realfmod(m_inBufLoc - newInBufLoc[0] * amount * m_sampleRateMult, m_bufferSize); newInBufLoc[1] = newInBufLoc[0]; // Distance between samples @@ -190,7 +187,7 @@ bool DisintegratorEffect::processAudioBuffer(sampleFrame* buf, const fpp_t frame newInBufLoc[i] = m_hp.update(newInBufLoc[i], 0); newInBufLoc[i] = m_lp.update(newInBufLoc[i], 0); - newInBufLoc[i] = realfmod(m_inBufLoc - newInBufLoc[i] * amount, DISINTEGRATOR_BUFFER_SIZE); + newInBufLoc[i] = realfmod(m_inBufLoc - newInBufLoc[i] * amount * m_sampleRateMult, m_bufferSize); // Distance between samples newInBufLocFrac[i] = fmod(newInBufLoc[i], 1); @@ -208,13 +205,13 @@ bool DisintegratorEffect::processAudioBuffer(sampleFrame* buf, const fpp_t frame } else { - if (newInBufLoc[i] < DISINTEGRATOR_BUFFER_SIZE - 1) + 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][DISINTEGRATOR_BUFFER_SIZE - 1] * (1 - newInBufLocFrac[i]) + m_inBuf[i][0] * newInBufLocFrac[i]; + s[i] = m_inBuf[i][m_bufferSize - 1] * (1 - newInBufLocFrac[i]) + m_inBuf[i][0] * newInBufLocFrac[i]; } } } diff --git a/plugins/Disintegrator/Disintegrator.h b/plugins/Disintegrator/Disintegrator.h index e3ff28cbc..f9750626c 100644 --- a/plugins/Disintegrator/Disintegrator.h +++ b/plugins/Disintegrator/Disintegrator.h @@ -33,9 +33,6 @@ #include "ValueBuffer.h" -constexpr int DISINTEGRATOR_BUFFER_SIZE = 201; - - class DisintegratorEffect : public Effect { public: @@ -65,6 +62,10 @@ private: StereoLinkwitzRiley m_hp; bool m_needsUpdate; + float m_sampleRate; + float m_sampleRateMult; + int m_bufferSize = 201; + friend class DisintegratorControls; } ; From fa0f4366833afc9d7cab22870703c57504fbd684 Mon Sep 17 00:00:00 2001 From: Hyunjin Song Date: Thu, 10 Dec 2020 13:18:48 +0900 Subject: [PATCH 16/20] Apply suggestions from code review --- plugins/Disintegrator/Disintegrator.cpp | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/plugins/Disintegrator/Disintegrator.cpp b/plugins/Disintegrator/Disintegrator.cpp index d121485b7..ebc2b1fc5 100644 --- a/plugins/Disintegrator/Disintegrator.cpp +++ b/plugins/Disintegrator/Disintegrator.cpp @@ -55,7 +55,7 @@ DisintegratorEffect::DisintegratorEffect(Model* parent, const Descriptor::SubPlu m_hp(Engine::mixer()->processingSampleRate()), m_needsUpdate(true) { - emit sampleRateChanged(); + sampleRateChanged(); } @@ -93,12 +93,11 @@ bool DisintegratorEffect::processAudioBuffer(sampleFrame* buf, const fpp_t frame const ValueBuffer * freqBuf = m_disintegratorControls.m_lowCutModel.valueBuffer(); // Update filters - if(m_needsUpdate || m_disintegratorControls.m_highCutModel.isValueChanged()) + if (m_needsUpdate || m_disintegratorControls.m_highCutModel.isValueChanged()) { m_lp.setLowpass(m_disintegratorControls.m_highCutModel.value()); - } - if(m_needsUpdate || m_disintegratorControls.m_lowCutModel.isValueChanged()) + if (m_needsUpdate || m_disintegratorControls.m_lowCutModel.isValueChanged()) { m_hp.setHighpass(m_disintegratorControls.m_lowCutModel.value()); } @@ -256,4 +255,3 @@ PLUGIN_EXPORT Plugin * lmms_plugin_main(Model* parent, void* data) } } - From 1235e419d33ef49d2ab771f7373306fba3ee4be2 Mon Sep 17 00:00:00 2001 From: Robert Daniel Black Date: Sun, 27 Dec 2020 11:21:51 -0700 Subject: [PATCH 17/20] Fix stuff --- plugins/Disintegrator/Disintegrator.cpp | 112 ++++++++---------- plugins/Disintegrator/Disintegrator.h | 6 +- .../Disintegrator/DisintegratorControls.cpp | 2 +- 3 files changed, 51 insertions(+), 69 deletions(-) diff --git a/plugins/Disintegrator/Disintegrator.cpp b/plugins/Disintegrator/Disintegrator.cpp index ebc2b1fc5..0be7d5c06 100644 --- a/plugins/Disintegrator/Disintegrator.cpp +++ b/plugins/Disintegrator/Disintegrator.cpp @@ -51,11 +51,9 @@ 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_lp(Engine::mixer()->processingSampleRate()), - m_hp(Engine::mixer()->processingSampleRate()), m_needsUpdate(true) { - sampleRateChanged(); + emit sampleRateChanged(); } @@ -63,12 +61,13 @@ DisintegratorEffect::DisintegratorEffect(Model* parent, const Descriptor::SubPlu void DisintegratorEffect::sampleRateChanged() { m_sampleRate = Engine::mixer()->processingSampleRate(); - m_sampleRateMult = m_sampleRate / 44100.f; - m_lp.setSampleRate(m_sampleRate); - m_hp.setSampleRate(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_bufferSize = (m_sampleRate / 44100.f) * 200.f + 1.f; + m_bufferSize = m_sampleRate * 0.01f + 1.f; for (int i = 0; i < 2; ++i) { m_inBuf[i].resize(m_bufferSize); @@ -93,19 +92,20 @@ bool DisintegratorEffect::processAudioBuffer(sampleFrame* buf, const fpp_t frame const ValueBuffer * freqBuf = m_disintegratorControls.m_lowCutModel.valueBuffer(); // Update filters - if (m_needsUpdate || m_disintegratorControls.m_highCutModel.isValueChanged()) + if(m_needsUpdate || m_disintegratorControls.m_highCutModel.isValueChanged()) { - m_lp.setLowpass(m_disintegratorControls.m_highCutModel.value()); + m_lp->calcFilterCoeffs(m_disintegratorControls.m_highCutModel.value(), 0.5); + } - if (m_needsUpdate || m_disintegratorControls.m_lowCutModel.isValueChanged()) + if(m_needsUpdate || m_disintegratorControls.m_lowCutModel.isValueChanged()) { - m_hp.setHighpass(m_disintegratorControls.m_lowCutModel.value()); + m_hp->calcFilterCoeffs(m_disintegratorControls.m_lowCutModel.value(), 0.5); } m_needsUpdate = false; for (fpp_t f = 0; f < frames; ++f) { - const float amount = amountBuf ? amountBuf->value(f) : m_disintegratorControls.m_amountModel.value(); + 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(); @@ -127,75 +127,56 @@ bool DisintegratorEffect::processAudioBuffer(sampleFrame* buf, const fpp_t frame // 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 + case 0://Mono Noise { - newInBufLoc[0] = fast_rand() / (float)FAST_RAND_MAX; - - newInBufLoc[0] = m_hp.update(newInBufLoc[0], 0); - newInBufLoc[0] = m_lp.update(newInBufLoc[0], 0); - - newInBufLoc[0] = realfmod(m_inBufLoc - newInBufLoc[0] * amount * m_sampleRateMult, m_bufferSize); - newInBufLoc[1] = newInBufLoc[0]; - - // Distance between samples - newInBufLocFrac[0] = fmod(newInBufLoc[0], 1); - newInBufLocFrac[1] = newInBufLocFrac[0]; - + delayModInput[0] = fast_rand() / (float)FAST_RAND_MAX * 2.f - 1.f; + delayModInput[1] = delayModInput[0]; break; } - case 1:// Stereo Noise + case 1://Stereo Noise { - for (int i = 0; i < 2; ++i) - { - newInBufLoc[i] = fast_rand() / (float)FAST_RAND_MAX; - - newInBufLoc[i] = m_hp.update(newInBufLoc[i], 0); - newInBufLoc[i] = m_lp.update(newInBufLoc[i], 0); - - newInBufLoc[i] = realfmod(m_inBufLoc - newInBufLoc[i] * amount * m_sampleRateMult, m_bufferSize); - - // Distance between samples - newInBufLocFrac[i] = fmod(newInBufLoc[i], 1); - } - + 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 + case 2://Sine Wave { m_sineLoc = fmod(m_sineLoc + (freq / m_sampleRate * F_2PI), F_2PI); - - newInBufLoc[0] = (sin(m_sineLoc) + 1) * 0.5f; - - newInBufLoc[0] = realfmod(m_inBufLoc - newInBufLoc[0] * amount * m_sampleRateMult, m_bufferSize); - newInBufLoc[1] = newInBufLoc[0]; - - // Distance between samples - newInBufLocFrac[0] = fmod(newInBufLoc[0], 1); - newInBufLocFrac[1] = newInBufLocFrac[0]; - + delayModInput[0] = sin(m_sineLoc); + delayModInput[1] = delayModInput[0]; break; } case 3:// Self-Modulation { - for (int i = 0; i < 2; ++i) - { - newInBufLoc[i] = (qBound(-1.f, s[i], 1.f) + 1) * 0.5f; - - newInBufLoc[i] = m_hp.update(newInBufLoc[i], 0); - newInBufLoc[i] = m_lp.update(newInBufLoc[i], 0); - - newInBufLoc[i] = realfmod(m_inBufLoc - newInBufLoc[i] * amount * m_sampleRateMult, m_bufferSize); - - // Distance between samples - newInBufLocFrac[i] = fmod(newInBufLoc[i], 1); - } - + delayModInput[0] = qBound(-1.f, s[0], 1.f); + delayModInput[1] = qBound(-1.f, s[1], 1.f); break; } } + for (int i = 0; i < 2; ++i) + { + newInBufLoc[i] = delayModInput[i]; + + 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); + } + + newInBufLoc[i] = (newInBufLoc[i] + 1) * 0.5f; + + newInBufLoc[i] = realfmod(m_inBufLoc - newInBufLoc[i] * amount, m_bufferSize); + + // Distance between samples + newInBufLocFrac[i] = fmod(newInBufLoc[i], 1); + } + + + for (int i = 0; i < 2; ++i) { if (newInBufLocFrac[i] == 0) @@ -239,8 +220,8 @@ inline float DisintegratorEffect::realfmod(float k, float n) void DisintegratorEffect::clearFilterHistories() { - m_lp.clearHistory(); - m_hp.clearHistory(); + m_lp->clearHistory(); + m_hp->clearHistory(); } @@ -255,3 +236,4 @@ PLUGIN_EXPORT Plugin * lmms_plugin_main(Model* parent, void* data) } } + diff --git a/plugins/Disintegrator/Disintegrator.h b/plugins/Disintegrator/Disintegrator.h index f9750626c..356f46b89 100644 --- a/plugins/Disintegrator/Disintegrator.h +++ b/plugins/Disintegrator/Disintegrator.h @@ -58,13 +58,13 @@ private: float m_sineLoc = 0; - StereoLinkwitzRiley m_lp; - StereoLinkwitzRiley m_hp; + BasicFilters<2> * m_lp; + BasicFilters<2> * m_hp; bool m_needsUpdate; float m_sampleRate; float m_sampleRateMult; - int m_bufferSize = 201; + int m_bufferSize = 500; friend class DisintegratorControls; diff --git a/plugins/Disintegrator/DisintegratorControls.cpp b/plugins/Disintegrator/DisintegratorControls.cpp index a2a213c0c..4cd54b5e7 100644 --- a/plugins/Disintegrator/DisintegratorControls.cpp +++ b/plugins/Disintegrator/DisintegratorControls.cpp @@ -37,7 +37,7 @@ DisintegratorControls::DisintegratorControls(DisintegratorEffect* 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(30.0f, 0.0f, 200.0f, 0.01f, this, tr("Amount")), + 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")) { From 5665902ce03d0b9beaf7b51951875dccdff56ac6 Mon Sep 17 00:00:00 2001 From: Robert Daniel Black Date: Sun, 27 Dec 2020 11:59:32 -0700 Subject: [PATCH 18/20] Fix Amount knob units --- plugins/Disintegrator/DisintegratorControlDialog.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/plugins/Disintegrator/DisintegratorControlDialog.cpp b/plugins/Disintegrator/DisintegratorControlDialog.cpp index d7f0be5ca..53b46ca64 100644 --- a/plugins/Disintegrator/DisintegratorControlDialog.cpp +++ b/plugins/Disintegrator/DisintegratorControlDialog.cpp @@ -59,7 +59,7 @@ DisintegratorControlDialog::DisintegratorControlDialog(DisintegratorControls* co m_amountKnob -> setVolumeKnob(true); m_amountKnob->setModel(&m_controls->m_amountModel); m_amountKnob->setLabel(tr("AMOUNT")); - m_amountKnob->setHintText(tr("Amount:"), " samples"); + m_amountKnob->setHintText(tr("Amount:"), " ms"); m_typeBox = new ComboBox(this); m_typeBox->setGeometry(1000, 5, 149, 22); From 5384c5d2866c2f184ce58881fa98c9bdc3e38843 Mon Sep 17 00:00:00 2001 From: Robert Daniel Black Date: Sun, 27 Dec 2020 20:05:58 -0700 Subject: [PATCH 19/20] Fix more stuff --- plugins/Disintegrator/Disintegrator.cpp | 2 +- plugins/Disintegrator/DisintegratorControlDialog.cpp | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/plugins/Disintegrator/Disintegrator.cpp b/plugins/Disintegrator/Disintegrator.cpp index 0be7d5c06..a8a1e9a8d 100644 --- a/plugins/Disintegrator/Disintegrator.cpp +++ b/plugins/Disintegrator/Disintegrator.cpp @@ -53,7 +53,7 @@ DisintegratorEffect::DisintegratorEffect(Model* parent, const Descriptor::SubPlu m_disintegratorControls(this), m_needsUpdate(true) { - emit sampleRateChanged(); + sampleRateChanged(); } diff --git a/plugins/Disintegrator/DisintegratorControlDialog.cpp b/plugins/Disintegrator/DisintegratorControlDialog.cpp index 53b46ca64..a75e838d6 100644 --- a/plugins/Disintegrator/DisintegratorControlDialog.cpp +++ b/plugins/Disintegrator/DisintegratorControlDialog.cpp @@ -82,7 +82,7 @@ DisintegratorControlDialog::DisintegratorControlDialog(DisintegratorControls* co frequency knobs depending on the modulation type. */ void DisintegratorControlDialog::updateKnobVisibility() { - if (m_controls->m_typeModel.value() == 2) + if (m_controls->m_typeModel.value() == 2)// Sine Mode { m_lowCutKnob->hide(); m_highCutKnob->hide(); From 88ea50dd3e2812efd1d71dc1158de5691eb0a098 Mon Sep 17 00:00:00 2001 From: Robert Daniel Black Date: Sun, 27 Dec 2020 20:10:19 -0700 Subject: [PATCH 20/20] Optimize --- plugins/Disintegrator/Disintegrator.cpp | 3 ++- plugins/Disintegrator/Disintegrator.h | 1 + 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/plugins/Disintegrator/Disintegrator.cpp b/plugins/Disintegrator/Disintegrator.cpp index a8a1e9a8d..0eb3d1ae4 100644 --- a/plugins/Disintegrator/Disintegrator.cpp +++ b/plugins/Disintegrator/Disintegrator.cpp @@ -61,6 +61,7 @@ DisintegratorEffect::DisintegratorEffect(Model* parent, const Descriptor::SubPlu 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); @@ -144,7 +145,7 @@ bool DisintegratorEffect::processAudioBuffer(sampleFrame* buf, const fpp_t frame } case 2://Sine Wave { - m_sineLoc = fmod(m_sineLoc + (freq / m_sampleRate * F_2PI), F_2PI); + m_sineLoc = fmod(m_sineLoc + (freq * m_2PiOverSR), F_2PI); delayModInput[0] = sin(m_sineLoc); delayModInput[1] = delayModInput[0]; break; diff --git a/plugins/Disintegrator/Disintegrator.h b/plugins/Disintegrator/Disintegrator.h index 356f46b89..5a79420b9 100644 --- a/plugins/Disintegrator/Disintegrator.h +++ b/plugins/Disintegrator/Disintegrator.h @@ -63,6 +63,7 @@ private: bool m_needsUpdate; float m_sampleRate; + float m_2PiOverSR; float m_sampleRateMult; int m_bufferSize = 500;