Dynamics processor, first commit
@@ -1,6 +1,7 @@
|
||||
ADD_SUBDIRECTORY(audio_file_processor)
|
||||
ADD_SUBDIRECTORY(bass_booster)
|
||||
ADD_SUBDIRECTORY(bit_invader)
|
||||
ADD_SUBDIRECTORY(dynamics_processor)
|
||||
ADD_SUBDIRECTORY(flp_import)
|
||||
ADD_SUBDIRECTORY(HydrogenImport)
|
||||
ADD_SUBDIRECTORY(kicker)
|
||||
|
||||
3
plugins/dynamics_processor/CMakeLists.txt
Normal file
@@ -0,0 +1,3 @@
|
||||
INCLUDE(BuildPlugin)
|
||||
|
||||
BUILD_PLUGIN(dynamics_processor dynamics_processor.cpp dynamics_processor_controls.cpp dynamics_processor_control_dialog.cpp MOCFILES dynamics_processor_controls.h EMBEDDED_RESOURCES "${CMAKE_CURRENT_SOURCE_DIR}/*.png")
|
||||
BIN
plugins/dynamics_processor/add1_active.png
Normal file
|
After Width: | Height: | Size: 959 B |
BIN
plugins/dynamics_processor/add1_inactive.png
Normal file
|
After Width: | Height: | Size: 928 B |
BIN
plugins/dynamics_processor/artwork.png
Normal file
|
After Width: | Height: | Size: 73 KiB |
BIN
plugins/dynamics_processor/avg_active.png
Normal file
|
After Width: | Height: | Size: 1.5 KiB |
BIN
plugins/dynamics_processor/avg_inactive.png
Normal file
|
After Width: | Height: | Size: 1.1 KiB |
201
plugins/dynamics_processor/dynamics_processor.cpp
Normal file
@@ -0,0 +1,201 @@
|
||||
/*
|
||||
* dynamics_processor.cpp - dynamics_processor effect-plugin
|
||||
*
|
||||
* Copyright (c) 2014 Vesa Kivimäki <contact/dot/diizy/at/nbl/dot/fi>
|
||||
* Copyright (c) 2006-2009 Tobias Doerffel <tobydox/at/users.sourceforge.net>
|
||||
*
|
||||
* This file is part of Linux MultiMedia Studio - http://lmms.sourceforge.net
|
||||
*
|
||||
* 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 "dynamics_processor.h"
|
||||
#include "embed.cpp"
|
||||
|
||||
|
||||
extern "C"
|
||||
{
|
||||
|
||||
Plugin::Descriptor PLUGIN_EXPORT dynamics_processor_plugin_descriptor =
|
||||
{
|
||||
STRINGIFY( PLUGIN_NAME ),
|
||||
"Dynamics Processor",
|
||||
QT_TRANSLATE_NOOP( "pluginBrowser",
|
||||
"plugin for processing dynamics in a flexible way" ),
|
||||
"Vesa Kivimäki <contact/dot/diizy/at/nbl/dot/fi>",
|
||||
0x0100,
|
||||
Plugin::Effect,
|
||||
new PluginPixmapLoader( "logo" ),
|
||||
NULL,
|
||||
NULL
|
||||
} ;
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
dynProcEffect::dynProcEffect( Model * _parent,
|
||||
const Descriptor::SubPluginFeatures::Key * _key ) :
|
||||
Effect( &dynamics_processor_plugin_descriptor, _parent, _key ),
|
||||
m_dpControls( this )
|
||||
{
|
||||
currentPeak[0] = 0.0f;
|
||||
currentPeak[1] = 0.0f;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
dynProcEffect::~dynProcEffect()
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
bool dynProcEffect::processAudioBuffer( sampleFrame * _buf,
|
||||
const fpp_t _frames )
|
||||
{
|
||||
if( !isEnabled() || !isRunning () )
|
||||
{
|
||||
return( false );
|
||||
}
|
||||
|
||||
// variables for effect
|
||||
int i = 0;
|
||||
float lookup;
|
||||
float frac;
|
||||
float sm_peak[2] = { 0.0f, 0.0f };
|
||||
float gain;
|
||||
|
||||
double out_sum = 0.0;
|
||||
const float d = dryLevel();
|
||||
const float w = wetLevel();
|
||||
|
||||
float att_tmp = ( 1.0f / ( m_dpControls.m_attackModel.value() / 1000.0f ) ) / engine::mixer()->processingSampleRate();
|
||||
float rel_tmp = ( 1.0f / ( m_dpControls.m_releaseModel.value() / 1000.0f ) ) / engine::mixer()->processingSampleRate();
|
||||
|
||||
for( fpp_t f = 0; f < _frames; ++f )
|
||||
{
|
||||
sample_t s[2] = { _buf[f][0], _buf[f][1] };
|
||||
|
||||
// update peak values
|
||||
for ( i=0; i <= 1; i++ )
|
||||
{
|
||||
if( qAbs( s[i] ) > currentPeak[i] )
|
||||
{
|
||||
currentPeak[i] = qMin ( currentPeak[i] + att_tmp, qAbs( s[i] ) );
|
||||
}
|
||||
else
|
||||
if( qAbs( s[i] ) < currentPeak[i] )
|
||||
{
|
||||
currentPeak[i] = qMax ( currentPeak[i] - rel_tmp, qAbs( s[i] ) );
|
||||
}
|
||||
}
|
||||
|
||||
// account for stereo mode
|
||||
switch( m_dpControls.m_stereomodeModel.value() )
|
||||
{
|
||||
case dynProcControls::SM_Maximum:
|
||||
{
|
||||
sm_peak[0] = qMax( currentPeak[0], currentPeak[1] );
|
||||
sm_peak[1] = qMax( currentPeak[0], currentPeak[1] );
|
||||
break;
|
||||
}
|
||||
case dynProcControls::SM_Average:
|
||||
{
|
||||
sm_peak[0] = ( currentPeak[0] + currentPeak[1] ) / 2;
|
||||
sm_peak[1] = ( currentPeak[0] + currentPeak[1] ) / 2;
|
||||
break;
|
||||
}
|
||||
case dynProcControls::SM_Unlinked:
|
||||
{
|
||||
sm_peak[0] = currentPeak[0];
|
||||
sm_peak[1] = currentPeak[1];
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// apply input gain
|
||||
if( m_dpControls.m_inputModel.value() != 1.0f )
|
||||
{
|
||||
s[0] *= m_dpControls.m_inputModel.value();
|
||||
s[1] *= m_dpControls.m_inputModel.value();
|
||||
}
|
||||
|
||||
|
||||
// start effect
|
||||
|
||||
for ( i=0; i <= 1; i++ )
|
||||
{
|
||||
lookup = sm_peak[i] * 200.0f;
|
||||
|
||||
if ( lookup < 1 )
|
||||
{
|
||||
frac = lookup - truncf(lookup);
|
||||
gain = frac * m_dpControls.m_wavegraphModel.samples()[0];
|
||||
}
|
||||
else
|
||||
if ( lookup < 200 )
|
||||
{
|
||||
frac = lookup - truncf(lookup);
|
||||
gain =
|
||||
(( (1.0f-frac) * m_dpControls.m_wavegraphModel.samples()[ (int)truncf(lookup) - 1 ] ) +
|
||||
( frac * m_dpControls.m_wavegraphModel.samples()[ (int)truncf(lookup) ] ));
|
||||
}
|
||||
else
|
||||
{
|
||||
gain = m_dpControls.m_wavegraphModel.samples()[199];
|
||||
};
|
||||
|
||||
s[i] = ( s[i] / sm_peak[i] ) * gain;
|
||||
}
|
||||
|
||||
// apply output gain
|
||||
s[0] *= m_dpControls.m_outputModel.value();
|
||||
s[1] *= m_dpControls.m_outputModel.value();
|
||||
|
||||
// mix wet/dry signals
|
||||
_buf[f][0] = d * _buf[f][0] + w * s[0];
|
||||
_buf[f][1] = d * _buf[f][1] + w * s[1];
|
||||
|
||||
out_sum += _buf[f][0]*_buf[f][0] + _buf[f][1]*_buf[f][1];
|
||||
}
|
||||
|
||||
checkGate( out_sum / _frames );
|
||||
|
||||
return( isRunning() );
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
extern "C"
|
||||
{
|
||||
|
||||
// necessary for getting instance out of shared lib
|
||||
Plugin * PLUGIN_EXPORT lmms_plugin_main( Model * _parent, void * _data )
|
||||
{
|
||||
return( new dynProcEffect( _parent,
|
||||
static_cast<const Plugin::Descriptor::SubPluginFeatures::Key *>(
|
||||
_data ) ) );
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
66
plugins/dynamics_processor/dynamics_processor.h
Normal file
@@ -0,0 +1,66 @@
|
||||
/*
|
||||
* dynamics_processor.h - dynamics_processor effect-plugin
|
||||
*
|
||||
* Copyright (c) 2014 Vesa Kivimäki <contact/dot/diizy/at/nbl/dot/fi>
|
||||
* Copyright (c) 2006-2008 Tobias Doerffel <tobydox/at/users.sourceforge.net>
|
||||
*
|
||||
* This file is part of Linux MultiMedia Studio - http://lmms.sourceforge.net
|
||||
*
|
||||
* 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 _DYNPROC_H
|
||||
#define _DYNPROC_H
|
||||
|
||||
#include "Effect.h"
|
||||
#include "effect_lib.h"
|
||||
#include "dynamics_processor_controls.h"
|
||||
|
||||
|
||||
|
||||
class dynProcEffect : public Effect
|
||||
{
|
||||
public:
|
||||
dynProcEffect( Model * _parent,
|
||||
const Descriptor::SubPluginFeatures::Key * _key );
|
||||
virtual ~dynProcEffect();
|
||||
virtual bool processAudioBuffer( sampleFrame * _buf,
|
||||
const fpp_t _frames );
|
||||
|
||||
virtual EffectControls * controls()
|
||||
{
|
||||
return( &m_dpControls );
|
||||
}
|
||||
|
||||
|
||||
private:
|
||||
|
||||
dynProcControls m_dpControls;
|
||||
|
||||
// this member array is needed for peak detection
|
||||
float currentPeak[2];
|
||||
|
||||
friend class dynProcControls;
|
||||
|
||||
} ;
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
#endif
|
||||
150
plugins/dynamics_processor/dynamics_processor_control_dialog.cpp
Normal file
@@ -0,0 +1,150 @@
|
||||
/*
|
||||
* dynamics_processor_control_dialog.cpp - control-dialog for dynamics_processor-effect
|
||||
*
|
||||
* Copyright (c) 2014 Vesa Kivimäki <contact/dot/diizy/at/nbl/dot/fi>
|
||||
* Copyright (c) 2006-2008 Tobias Doerffel <tobydox/at/users.sourceforge.net>
|
||||
*
|
||||
* This file is part of Linux MultiMedia Studio - http://lmms.sourceforge.net
|
||||
*
|
||||
* 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 <QtGui/QLayout>
|
||||
|
||||
#include "dynamics_processor_control_dialog.h"
|
||||
#include "dynamics_processor_controls.h"
|
||||
#include "embed.h"
|
||||
#include "graph.h"
|
||||
#include "pixmap_button.h"
|
||||
#include "tooltip.h"
|
||||
#include "led_checkbox.h"
|
||||
|
||||
|
||||
dynProcControlDialog::dynProcControlDialog(
|
||||
dynProcControls * _controls ) :
|
||||
EffectControlDialog( _controls )
|
||||
{
|
||||
setAutoFillBackground( true );
|
||||
QPalette pal;
|
||||
pal.setBrush( backgroundRole(),
|
||||
PLUGIN_NAME::getIconPixmap( "artwork" ) );
|
||||
setPalette( pal );
|
||||
setFixedSize( 224, 340 );
|
||||
|
||||
graph * waveGraph = new graph( this, graph::LinearNonCyclicStyle, 204, 205 );
|
||||
waveGraph -> move( 10, 32 );
|
||||
waveGraph -> setModel( &_controls -> m_wavegraphModel );
|
||||
waveGraph -> setAutoFillBackground( true );
|
||||
pal = QPalette();
|
||||
pal.setBrush( backgroundRole(),
|
||||
PLUGIN_NAME::getIconPixmap("wavegraph") );
|
||||
waveGraph->setPalette( pal );
|
||||
waveGraph->setGraphColor( QColor( 170, 255, 255 ) );
|
||||
waveGraph -> setMaximumSize( 204, 205 );
|
||||
|
||||
knob * inputKnob = new knob( knobBright_26, this);
|
||||
inputKnob -> move( 14, 251 );
|
||||
inputKnob->setModel( &_controls->m_inputModel );
|
||||
inputKnob->setLabel( tr( "INPUT" ) );
|
||||
inputKnob->setHintText( tr( "Input gain:" ) + " ", "" );
|
||||
|
||||
knob * outputKnob = new knob( knobBright_26, this );
|
||||
outputKnob -> move( 54, 251 );
|
||||
outputKnob->setModel( &_controls->m_outputModel );
|
||||
outputKnob->setLabel( tr( "OUTPUT" ) );
|
||||
outputKnob->setHintText( tr( "Output gain:" ) + " ", "" );
|
||||
|
||||
knob * attackKnob = new knob( knobBright_26, this);
|
||||
attackKnob -> move( 14, 291 );
|
||||
attackKnob->setModel( &_controls->m_attackModel );
|
||||
attackKnob->setLabel( tr( "ATTACK" ) );
|
||||
attackKnob->setHintText( tr( "Peak attack time:" ) + " ", "ms" );
|
||||
|
||||
knob * releaseKnob = new knob( knobBright_26, this );
|
||||
releaseKnob -> move( 54, 291 );
|
||||
releaseKnob->setModel( &_controls->m_releaseModel );
|
||||
releaseKnob->setLabel( tr( "RELEASE" ) );
|
||||
releaseKnob->setHintText( tr( "Peak release time:" ) + " ", "ms" );
|
||||
|
||||
//waveform control buttons
|
||||
|
||||
pixmapButton * resetButton = new pixmapButton( this, tr("Reset waveform") );
|
||||
resetButton -> move( 164, 251 );
|
||||
resetButton -> resize( 12, 48 );
|
||||
resetButton -> setActiveGraphic( PLUGIN_NAME::getIconPixmap( "reset_active" ) );
|
||||
resetButton -> setInactiveGraphic( PLUGIN_NAME::getIconPixmap( "reset_inactive" ) );
|
||||
toolTip::add( resetButton, tr( "Click here to reset the wavegraph back to default" ) );
|
||||
|
||||
pixmapButton * smoothButton = new pixmapButton( this, tr("Smooth waveform") );
|
||||
smoothButton -> move( 164, 267 );
|
||||
smoothButton -> resize( 12, 48 );
|
||||
smoothButton -> setActiveGraphic( PLUGIN_NAME::getIconPixmap( "smooth_active" ) );
|
||||
smoothButton -> setInactiveGraphic( PLUGIN_NAME::getIconPixmap( "smooth_inactive" ) );
|
||||
toolTip::add( smoothButton, tr( "Click here to apply smoothing to wavegraph" ) );
|
||||
|
||||
pixmapButton * addOneButton = new pixmapButton( this, tr("Increase wavegraph amplitude by 1dB") );
|
||||
addOneButton -> move( 133, 251 );
|
||||
addOneButton -> resize( 12, 29 );
|
||||
addOneButton -> setActiveGraphic( PLUGIN_NAME::getIconPixmap( "add1_active" ) );
|
||||
addOneButton -> setInactiveGraphic( PLUGIN_NAME::getIconPixmap( "add1_inactive" ) );
|
||||
toolTip::add( addOneButton, tr( "Click here to increase wavegraph amplitude by 1dB" ) );
|
||||
|
||||
pixmapButton * subOneButton = new pixmapButton( this, tr("Decrease wavegraph amplitude by 1dB") );
|
||||
subOneButton -> move( 133, 267 );
|
||||
subOneButton -> resize( 12, 29 );
|
||||
subOneButton -> setActiveGraphic( PLUGIN_NAME::getIconPixmap( "sub1_active" ) );
|
||||
subOneButton -> setInactiveGraphic( PLUGIN_NAME::getIconPixmap( "sub1_inactive" ) );
|
||||
toolTip::add( subOneButton, tr( "Click here to decrease wavegraph amplitude by 1dB" ) );
|
||||
|
||||
//stereomode switches
|
||||
pixmapButton * smMaxButton = new pixmapButton( this, tr( "Stereomode Maximum" ) );
|
||||
smMaxButton -> move( 165, 290 );
|
||||
smMaxButton -> resize( 48, 13 );
|
||||
smMaxButton -> setActiveGraphic( PLUGIN_NAME::getIconPixmap( "max_active" ) );
|
||||
smMaxButton -> setInactiveGraphic( PLUGIN_NAME::getIconPixmap( "max_inactive" ) );
|
||||
toolTip::add( smMaxButton, tr( "Process based on the maximum of both stereo channels" ) );
|
||||
|
||||
pixmapButton * smAvgButton = new pixmapButton( this, tr( "Stereomode Average" ) );
|
||||
smAvgButton -> move( 165, 290 + 13 );
|
||||
smAvgButton -> resize( 48, 13 );
|
||||
smAvgButton -> setActiveGraphic( PLUGIN_NAME::getIconPixmap( "avg_active" ) );
|
||||
smAvgButton -> setInactiveGraphic( PLUGIN_NAME::getIconPixmap( "avg_inactive" ) );
|
||||
toolTip::add( smAvgButton, tr( "Process based on the average of both stereo channels" ) );
|
||||
|
||||
pixmapButton * smUnlButton = new pixmapButton( this, tr( "Stereomode Unlinked" ) );
|
||||
smUnlButton -> move( 165, 290 + (13*2) );
|
||||
smUnlButton -> resize( 48, 13 );
|
||||
smUnlButton -> setActiveGraphic( PLUGIN_NAME::getIconPixmap( "unl_active" ) );
|
||||
smUnlButton -> setInactiveGraphic( PLUGIN_NAME::getIconPixmap( "unl_inactive" ) );
|
||||
toolTip::add( smUnlButton, tr( "Process each stereo channel independently" ) );
|
||||
|
||||
automatableButtonGroup * smGroup = new automatableButtonGroup( this );
|
||||
smGroup -> addButton( smMaxButton );
|
||||
smGroup -> addButton( smAvgButton );
|
||||
smGroup -> addButton( smUnlButton );
|
||||
smGroup -> setModel( &_controls -> m_stereomodeModel );
|
||||
|
||||
connect( resetButton, SIGNAL (clicked () ),
|
||||
_controls, SLOT ( resetClicked() ) );
|
||||
connect( smoothButton, SIGNAL (clicked () ),
|
||||
_controls, SLOT ( smoothClicked() ) );
|
||||
connect( addOneButton, SIGNAL( clicked() ),
|
||||
_controls, SLOT( addOneClicked() ) );
|
||||
connect( subOneButton, SIGNAL( clicked() ),
|
||||
_controls, SLOT( subOneClicked() ) );
|
||||
}
|
||||
@@ -0,0 +1,48 @@
|
||||
/*
|
||||
* dynamics_processor_control_dialog.h - control-dialog for dynamics_processor-effect
|
||||
*
|
||||
* * Copyright (c) 2014 Vesa Kivimäki <contact/dot/diizy/at/nbl/dot/fi>
|
||||
* Copyright (c) 2006-2008 Tobias Doerffel <tobydox/at/users.sourceforge.net>
|
||||
*
|
||||
* This file is part of Linux MultiMedia Studio - http://lmms.sourceforge.net
|
||||
*
|
||||
* 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 _DYNPROC_CONTROL_DIALOG_H
|
||||
#define _DYNPROC_CONTROL_DIALOG_H
|
||||
|
||||
#include "EffectControlDialog.h"
|
||||
|
||||
|
||||
class dynProcControls;
|
||||
|
||||
|
||||
class dynProcControlDialog : public EffectControlDialog
|
||||
{
|
||||
public:
|
||||
dynProcControlDialog( dynProcControls * _controls );
|
||||
virtual ~dynProcControlDialog()
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
private:
|
||||
|
||||
} ;
|
||||
|
||||
#endif
|
||||
172
plugins/dynamics_processor/dynamics_processor_controls.cpp
Normal file
@@ -0,0 +1,172 @@
|
||||
/*
|
||||
* dynamics_processor_controls.cpp - controls for dynamics_processor-effect
|
||||
*
|
||||
* Copyright (c) 2014 Vesa Kivimäki <contact/dot/diizy/at/nbl/dot/fi>
|
||||
* Copyright (c) 2008 Tobias Doerffel <tobydox/at/users.sourceforge.net>
|
||||
*
|
||||
* This file is part of Linux MultiMedia Studio - http://lmms.sourceforge.net
|
||||
*
|
||||
* 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 <QtXml/QDomElement>
|
||||
|
||||
#include "dynamics_processor_controls.h"
|
||||
#include "dynamics_processor.h"
|
||||
#include "graph.h"
|
||||
#include "engine.h"
|
||||
#include "song.h"
|
||||
|
||||
|
||||
#define onedB 1.1220184543019633f
|
||||
|
||||
dynProcControls::dynProcControls( dynProcEffect * _eff ) :
|
||||
EffectControls( _eff ),
|
||||
m_effect( _eff ),
|
||||
m_inputModel( 1.0f, 0.0f, 5.0f, 0.01f, this, tr( "Input gain" ) ),
|
||||
m_outputModel( 1.0f, 0.0f, 5.0f, 0.01f, this, tr( "Output gain" ) ),
|
||||
m_attackModel( 10.0f, 1.0f, 500.0f, 1.0f, this, tr( "Attack time" ) ),
|
||||
m_releaseModel( 100.0f, 1.0f, 500.0f, 1.0f, this, tr( "Release time" ) ),
|
||||
m_wavegraphModel( 0.0f, 1.0f, 200, this ),
|
||||
m_stereomodeModel( 0, 0, 2, this, tr( "Stereo mode" ) )
|
||||
{
|
||||
connect( &m_inputModel, SIGNAL( dataChanged() ),
|
||||
this, SLOT( changeControl() ) );
|
||||
|
||||
connect( &m_outputModel, SIGNAL( dataChanged() ),
|
||||
this, SLOT( changeControl() ) );
|
||||
|
||||
connect( &m_attackModel, SIGNAL( dataChanged() ),
|
||||
this, SLOT( changeControl() ) );
|
||||
|
||||
connect( &m_releaseModel, SIGNAL( dataChanged() ),
|
||||
this, SLOT( changeControl() ) );
|
||||
|
||||
connect( &m_stereomodeModel, SIGNAL( dataChanged() ),
|
||||
this, SLOT( changeControl() ) );
|
||||
|
||||
connect( &m_wavegraphModel, SIGNAL( samplesChanged( int, int ) ),
|
||||
this, SLOT( samplesChanged( int, int ) ) );
|
||||
|
||||
|
||||
setDefaultShape();
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
void dynProcControls::changeControl()
|
||||
{
|
||||
engine::getSong()->setModified();
|
||||
}
|
||||
|
||||
void dynProcControls::samplesChanged( int _begin, int _end)
|
||||
{
|
||||
engine::getSong()->setModified();
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
void dynProcControls::loadSettings( const QDomElement & _this )
|
||||
{
|
||||
//load knobs, stereomode
|
||||
m_inputModel.setValue( _this.attribute( "inputGain" ).toFloat() );
|
||||
m_outputModel.setValue( _this.attribute( "outputGain" ).toFloat() );
|
||||
m_attackModel.setValue( _this.attribute( "attack" ).toFloat() );
|
||||
m_releaseModel.setValue( _this.attribute( "release" ).toFloat() );
|
||||
m_stereomodeModel.setValue( _this.attribute( "stereoMode" ).toInt() );
|
||||
|
||||
//load waveshape
|
||||
int size = 0;
|
||||
char * dst = 0;
|
||||
base64::decode( _this.attribute( "waveShape"), &dst, &size );
|
||||
|
||||
m_wavegraphModel.setSamples( (float*) dst );
|
||||
delete[] dst;
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
void dynProcControls::saveSettings( QDomDocument & _doc,
|
||||
QDomElement & _this )
|
||||
{
|
||||
//save input, output knobs
|
||||
_this.setAttribute( "inputGain", m_inputModel.value() );
|
||||
_this.setAttribute( "outputGain", m_outputModel.value() );
|
||||
_this.setAttribute( "attack", m_attackModel.value() );
|
||||
_this.setAttribute( "release", m_releaseModel.value() );
|
||||
_this.setAttribute( "stereoMode", m_stereomodeModel.value() );
|
||||
|
||||
|
||||
//save waveshape
|
||||
QString sampleString;
|
||||
base64::encode( (const char *)m_wavegraphModel.samples(),
|
||||
m_wavegraphModel.length() * sizeof(float), sampleString );
|
||||
_this.setAttribute( "waveShape", sampleString );
|
||||
|
||||
}
|
||||
|
||||
|
||||
void dynProcControls::setDefaultShape()
|
||||
{
|
||||
float shp [200] = { };
|
||||
for ( int i = 0; i<200; i++)
|
||||
{
|
||||
shp[i] = ((float)i + 1.0f) / 200.0f;
|
||||
}
|
||||
|
||||
m_wavegraphModel.setLength( 200 );
|
||||
m_wavegraphModel.setSamples( (float*)&shp );
|
||||
}
|
||||
|
||||
void dynProcControls::resetClicked()
|
||||
{
|
||||
setDefaultShape();
|
||||
engine::getSong()->setModified();
|
||||
}
|
||||
|
||||
void dynProcControls::smoothClicked()
|
||||
{
|
||||
m_wavegraphModel.smoothNonCyclic();
|
||||
engine::getSong()->setModified();
|
||||
}
|
||||
|
||||
void dynProcControls::addOneClicked()
|
||||
{
|
||||
for( int i=0; i<200; i++ )
|
||||
{
|
||||
m_wavegraphModel.setSampleAt( i, qBound( 0.0f, m_wavegraphModel.samples()[i] * onedB, 1.0f ) );
|
||||
}
|
||||
engine::getSong()->setModified();
|
||||
}
|
||||
|
||||
void dynProcControls::subOneClicked()
|
||||
{
|
||||
for( int i=0; i<200; i++ )
|
||||
{
|
||||
m_wavegraphModel.setSampleAt( i, qBound( 0.0f, m_wavegraphModel.samples()[i] / onedB, 1.0f ) );
|
||||
}
|
||||
engine::getSong()->setModified();
|
||||
}
|
||||
|
||||
|
||||
#include "moc_dynamics_processor_controls.cxx"
|
||||
|
||||
98
plugins/dynamics_processor/dynamics_processor_controls.h
Normal file
@@ -0,0 +1,98 @@
|
||||
/*
|
||||
* dynamics_processor_controls.h - controls for dynamics_processor-effect
|
||||
*
|
||||
* Copyright (c) 2014 Vesa Kivimäki <contact/dot/diizy/at/nbl/dot/fi>
|
||||
* Copyright (c) 2008 Tobias Doerffel <tobydox/at/users.sourceforge.net>
|
||||
*
|
||||
* This file is part of Linux MultiMedia Studio - http://lmms.sourceforge.net
|
||||
*
|
||||
* 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 _WAVESHAPER_CONTROLS_H
|
||||
#define _WAVESHAPER_CONTROLS_H
|
||||
|
||||
#include "EffectControls.h"
|
||||
#include "dynamics_processor_control_dialog.h"
|
||||
#include "knob.h"
|
||||
#include "graph.h"
|
||||
|
||||
class dynProcEffect;
|
||||
|
||||
|
||||
class dynProcControls : public EffectControls
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
enum StereoModes
|
||||
{
|
||||
SM_Maximum,
|
||||
SM_Average,
|
||||
SM_Unlinked,
|
||||
NumStereoModes
|
||||
};
|
||||
dynProcControls( dynProcEffect * _eff );
|
||||
virtual ~dynProcControls()
|
||||
{
|
||||
}
|
||||
|
||||
virtual void saveSettings( QDomDocument & _doc, QDomElement & _parent );
|
||||
virtual void loadSettings( const QDomElement & _this );
|
||||
inline virtual QString nodeName() const
|
||||
{
|
||||
return( "dynamicsprocessor_controls" );
|
||||
}
|
||||
|
||||
virtual void setDefaultShape();
|
||||
|
||||
virtual int controlCount()
|
||||
{
|
||||
return( 6 );
|
||||
}
|
||||
|
||||
virtual EffectControlDialog * createView()
|
||||
{
|
||||
return( new dynProcControlDialog( this ) );
|
||||
}
|
||||
|
||||
|
||||
private slots:
|
||||
void changeControl();
|
||||
void samplesChanged( int, int );
|
||||
|
||||
void resetClicked();
|
||||
void smoothClicked();
|
||||
|
||||
void addOneClicked();
|
||||
void subOneClicked();
|
||||
|
||||
private:
|
||||
dynProcEffect * m_effect;
|
||||
|
||||
FloatModel m_inputModel;
|
||||
FloatModel m_outputModel;
|
||||
FloatModel m_attackModel;
|
||||
FloatModel m_releaseModel;
|
||||
graphModel m_wavegraphModel;
|
||||
IntModel m_stereomodeModel;
|
||||
|
||||
friend class dynProcControlDialog;
|
||||
friend class dynProcEffect;
|
||||
|
||||
} ;
|
||||
|
||||
#endif
|
||||
BIN
plugins/dynamics_processor/logo.png
Normal file
|
After Width: | Height: | Size: 3.1 KiB |
BIN
plugins/dynamics_processor/max_active.png
Normal file
|
After Width: | Height: | Size: 1.4 KiB |
BIN
plugins/dynamics_processor/max_inactive.png
Normal file
|
After Width: | Height: | Size: 969 B |
BIN
plugins/dynamics_processor/reset_active.png
Normal file
|
After Width: | Height: | Size: 1.2 KiB |
BIN
plugins/dynamics_processor/reset_inactive.png
Normal file
|
After Width: | Height: | Size: 1.2 KiB |
BIN
plugins/dynamics_processor/smooth_active.png
Normal file
|
After Width: | Height: | Size: 1.3 KiB |
BIN
plugins/dynamics_processor/smooth_inactive.png
Normal file
|
After Width: | Height: | Size: 1.3 KiB |
BIN
plugins/dynamics_processor/sub1_active.png
Normal file
|
After Width: | Height: | Size: 927 B |
BIN
plugins/dynamics_processor/sub1_inactive.png
Normal file
|
After Width: | Height: | Size: 900 B |
BIN
plugins/dynamics_processor/unl_active.png
Normal file
|
After Width: | Height: | Size: 1.4 KiB |
BIN
plugins/dynamics_processor/unl_inactive.png
Normal file
|
After Width: | Height: | Size: 854 B |
BIN
plugins/dynamics_processor/wavegraph.png
Normal file
|
After Width: | Height: | Size: 40 KiB |