Add Disintegrator effect

This commit is contained in:
root
2019-08-29 19:59:24 -06:00
parent e83d44a56e
commit a630f32f21
9 changed files with 0 additions and 577 deletions

View File

@@ -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)

View File

@@ -1,245 +0,0 @@
/*
* Disintegrator.cpp
*
* Copyright (c) 2019 Lost Robot <r94231@gmail.com>
*
* 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 <r94231@gmail.com>",
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<const Plugin::Descriptor::SubPluginFeatures::Key *>( data ) );
}
}

View File

@@ -1,67 +0,0 @@
/*
* Disintegrator.h
*
* Copyright (c) 2019 Lost Robot <r94231@gmail.com>
*
* 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<float> inBuf[2];
int inBufLoc = 0;
friend class DisintegratorControls;
} ;
#endif

View File

@@ -1,70 +0,0 @@
/*
* DisintegratorControlDialog.cpp
*
* Copyright (c) 2019 Lost Robot <r94231@gmail.com>
*
* 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 <QLayout>
#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== //
}

View File

@@ -1,45 +0,0 @@
/*
* DisintegratorControlDialog.h
*
* Copyright (c) 2019 Lost Robot <r94231@gmail.com>
*
* 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

View File

@@ -1,69 +0,0 @@
/*
* DisintegratorControls.cpp
*
* Copyright (c) 2019 Lost Robot <r94231@gmail.com>
*
* 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 <QDomElement>
#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== //
}

View File

@@ -1,78 +0,0 @@
/*
* DisintegratorControls.h
*
* Copyright (c) 2019 Lost Robot <r94231@gmail.com>
*
* 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

Binary file not shown.

Before

Width:  |  Height:  |  Size: 7.6 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 774 B