diff --git a/plugins/CMakeLists.txt b/plugins/CMakeLists.txt index 01aa7868b..6dc69ad0b 100644 --- a/plugins/CMakeLists.txt +++ b/plugins/CMakeLists.txt @@ -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) diff --git a/plugins/dynamics_processor/CMakeLists.txt b/plugins/dynamics_processor/CMakeLists.txt new file mode 100644 index 000000000..4e95af34a --- /dev/null +++ b/plugins/dynamics_processor/CMakeLists.txt @@ -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") diff --git a/plugins/dynamics_processor/add1_active.png b/plugins/dynamics_processor/add1_active.png new file mode 100644 index 000000000..89ae87e0f Binary files /dev/null and b/plugins/dynamics_processor/add1_active.png differ diff --git a/plugins/dynamics_processor/add1_inactive.png b/plugins/dynamics_processor/add1_inactive.png new file mode 100644 index 000000000..94213a27c Binary files /dev/null and b/plugins/dynamics_processor/add1_inactive.png differ diff --git a/plugins/dynamics_processor/artwork.png b/plugins/dynamics_processor/artwork.png new file mode 100644 index 000000000..f5398d738 Binary files /dev/null and b/plugins/dynamics_processor/artwork.png differ diff --git a/plugins/dynamics_processor/avg_active.png b/plugins/dynamics_processor/avg_active.png new file mode 100644 index 000000000..baa6b36e3 Binary files /dev/null and b/plugins/dynamics_processor/avg_active.png differ diff --git a/plugins/dynamics_processor/avg_inactive.png b/plugins/dynamics_processor/avg_inactive.png new file mode 100644 index 000000000..816900e2c Binary files /dev/null and b/plugins/dynamics_processor/avg_inactive.png differ diff --git a/plugins/dynamics_processor/dynamics_processor.cpp b/plugins/dynamics_processor/dynamics_processor.cpp new file mode 100644 index 000000000..c2930a925 --- /dev/null +++ b/plugins/dynamics_processor/dynamics_processor.cpp @@ -0,0 +1,201 @@ +/* + * dynamics_processor.cpp - dynamics_processor effect-plugin + * + * Copyright (c) 2014 Vesa Kivimäki + * Copyright (c) 2006-2009 Tobias Doerffel + * + * 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 ", + 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( + _data ) ) ); +} + +} + diff --git a/plugins/dynamics_processor/dynamics_processor.h b/plugins/dynamics_processor/dynamics_processor.h new file mode 100644 index 000000000..287b46d55 --- /dev/null +++ b/plugins/dynamics_processor/dynamics_processor.h @@ -0,0 +1,66 @@ +/* + * dynamics_processor.h - dynamics_processor effect-plugin + * + * Copyright (c) 2014 Vesa Kivimäki + * Copyright (c) 2006-2008 Tobias Doerffel + * + * 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 diff --git a/plugins/dynamics_processor/dynamics_processor_control_dialog.cpp b/plugins/dynamics_processor/dynamics_processor_control_dialog.cpp new file mode 100644 index 000000000..a14c160f7 --- /dev/null +++ b/plugins/dynamics_processor/dynamics_processor_control_dialog.cpp @@ -0,0 +1,150 @@ +/* + * dynamics_processor_control_dialog.cpp - control-dialog for dynamics_processor-effect + * + * Copyright (c) 2014 Vesa Kivimäki + * Copyright (c) 2006-2008 Tobias Doerffel + * + * 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 + +#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() ) ); +} diff --git a/plugins/dynamics_processor/dynamics_processor_control_dialog.h b/plugins/dynamics_processor/dynamics_processor_control_dialog.h new file mode 100644 index 000000000..23770debd --- /dev/null +++ b/plugins/dynamics_processor/dynamics_processor_control_dialog.h @@ -0,0 +1,48 @@ +/* + * dynamics_processor_control_dialog.h - control-dialog for dynamics_processor-effect + * + * * Copyright (c) 2014 Vesa Kivimäki + * Copyright (c) 2006-2008 Tobias Doerffel + * + * 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 diff --git a/plugins/dynamics_processor/dynamics_processor_controls.cpp b/plugins/dynamics_processor/dynamics_processor_controls.cpp new file mode 100644 index 000000000..614aed8e9 --- /dev/null +++ b/plugins/dynamics_processor/dynamics_processor_controls.cpp @@ -0,0 +1,172 @@ +/* + * dynamics_processor_controls.cpp - controls for dynamics_processor-effect + * + * Copyright (c) 2014 Vesa Kivimäki + * Copyright (c) 2008 Tobias Doerffel + * + * 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 + +#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" + diff --git a/plugins/dynamics_processor/dynamics_processor_controls.h b/plugins/dynamics_processor/dynamics_processor_controls.h new file mode 100644 index 000000000..70ec9895c --- /dev/null +++ b/plugins/dynamics_processor/dynamics_processor_controls.h @@ -0,0 +1,98 @@ +/* + * dynamics_processor_controls.h - controls for dynamics_processor-effect + * + * Copyright (c) 2014 Vesa Kivimäki + * Copyright (c) 2008 Tobias Doerffel + * + * 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 diff --git a/plugins/dynamics_processor/logo.png b/plugins/dynamics_processor/logo.png new file mode 100644 index 000000000..89e9f3680 Binary files /dev/null and b/plugins/dynamics_processor/logo.png differ diff --git a/plugins/dynamics_processor/max_active.png b/plugins/dynamics_processor/max_active.png new file mode 100644 index 000000000..30bb7429e Binary files /dev/null and b/plugins/dynamics_processor/max_active.png differ diff --git a/plugins/dynamics_processor/max_inactive.png b/plugins/dynamics_processor/max_inactive.png new file mode 100644 index 000000000..0b556b2ee Binary files /dev/null and b/plugins/dynamics_processor/max_inactive.png differ diff --git a/plugins/dynamics_processor/reset_active.png b/plugins/dynamics_processor/reset_active.png new file mode 100644 index 000000000..7bb3957ee Binary files /dev/null and b/plugins/dynamics_processor/reset_active.png differ diff --git a/plugins/dynamics_processor/reset_inactive.png b/plugins/dynamics_processor/reset_inactive.png new file mode 100644 index 000000000..5c3955b2b Binary files /dev/null and b/plugins/dynamics_processor/reset_inactive.png differ diff --git a/plugins/dynamics_processor/smooth_active.png b/plugins/dynamics_processor/smooth_active.png new file mode 100644 index 000000000..a44bef32d Binary files /dev/null and b/plugins/dynamics_processor/smooth_active.png differ diff --git a/plugins/dynamics_processor/smooth_inactive.png b/plugins/dynamics_processor/smooth_inactive.png new file mode 100644 index 000000000..eb689a500 Binary files /dev/null and b/plugins/dynamics_processor/smooth_inactive.png differ diff --git a/plugins/dynamics_processor/sub1_active.png b/plugins/dynamics_processor/sub1_active.png new file mode 100644 index 000000000..b82eb2585 Binary files /dev/null and b/plugins/dynamics_processor/sub1_active.png differ diff --git a/plugins/dynamics_processor/sub1_inactive.png b/plugins/dynamics_processor/sub1_inactive.png new file mode 100644 index 000000000..075239fd4 Binary files /dev/null and b/plugins/dynamics_processor/sub1_inactive.png differ diff --git a/plugins/dynamics_processor/unl_active.png b/plugins/dynamics_processor/unl_active.png new file mode 100644 index 000000000..9b534b871 Binary files /dev/null and b/plugins/dynamics_processor/unl_active.png differ diff --git a/plugins/dynamics_processor/unl_inactive.png b/plugins/dynamics_processor/unl_inactive.png new file mode 100644 index 000000000..850b7077b Binary files /dev/null and b/plugins/dynamics_processor/unl_inactive.png differ diff --git a/plugins/dynamics_processor/wavegraph.png b/plugins/dynamics_processor/wavegraph.png new file mode 100644 index 000000000..650fcec02 Binary files /dev/null and b/plugins/dynamics_processor/wavegraph.png differ