diff --git a/ChangeLog b/ChangeLog index d9c4984f6..2139e0276 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,5 +1,17 @@ 2008-06-24 Tobias Doerffel + * plugins/plucked_string_synth/logo.png: + * plugins/plucked_string_synth/plucked_string_synth.cpp: + * plugins/plucked_string_synth/plucked_string_synth.h: + * plugins/plucked_string_synth/Makefile.am: + * plugins/plucked_string_synth/artwork.png: + * plugins/polyb302/polyb302.h: + * plugins/polyb302/logo.png: + * plugins/polyb302/Makefile.am: + * plugins/polyb302/polyb302.cpp: + * plugins/polyb302/artwork.png: + removed obsolete plugins + * plugins/spectrum_analyzer/spectrumanalyzer_control_dialog.cpp: * plugins/spectrum_analyzer/spectrum_analyzer.cpp: * plugins/spectrum_analyzer/Makefile.am: diff --git a/plugins/plucked_string_synth/Makefile.am b/plugins/plucked_string_synth/Makefile.am deleted file mode 100644 index 47263f346..000000000 --- a/plugins/plucked_string_synth/Makefile.am +++ /dev/null @@ -1,33 +0,0 @@ -AUTOMAKE_OPTIONS = foreign 1.4 - - -INCLUDES = -I$(top_srcdir)/include -I$(top_srcdir)/src/lib -I. - - -AM_CXXFLAGS := $(AM_CXXFLAGS) $(QT_CXXFLAGS) -DPLUGIN_NAME="pluckedstringsynth" - - -%.moc: ./%.h - $(MOC) -o $@ $< - - -MOC_FILES = ./plucked_string_synth.moc - -BUILT_SOURCES = $(MOC_FILES) ./embedded_resources.h -EMBEDDED_RESOURCES = $(wildcard *png) - -./embedded_resources.h: $(EMBEDDED_RESOURCES) - $(BIN2RES) $(EMBEDDED_RESOURCES) > $@ - -EXTRA_DIST = $(EMBEDDED_RESOURCES) - - -CLEANFILES = $(MOC_FILES) ./embedded_resources.h - - - -pkglib_LTLIBRARIES= libpluckedstringsynth.la - -libpluckedstringsynth_la_SOURCES = plucked_string_synth.cpp plucked_string_synth.h - -$(libpluckedstringsynth_la_SOURCES): ./embedded_resources.h diff --git a/plugins/plucked_string_synth/artwork.png b/plugins/plucked_string_synth/artwork.png deleted file mode 100644 index 88476ab09..000000000 Binary files a/plugins/plucked_string_synth/artwork.png and /dev/null differ diff --git a/plugins/plucked_string_synth/logo.png b/plugins/plucked_string_synth/logo.png deleted file mode 100644 index 39455b5bf..000000000 Binary files a/plugins/plucked_string_synth/logo.png and /dev/null differ diff --git a/plugins/plucked_string_synth/plucked_string_synth.cpp b/plugins/plucked_string_synth/plucked_string_synth.cpp deleted file mode 100644 index d6e676379..000000000 --- a/plugins/plucked_string_synth/plucked_string_synth.cpp +++ /dev/null @@ -1,278 +0,0 @@ -/* - * plucked_string_synth.cpp - instrument which uses the Karplus-Strong-algorithm - * - * Copyright (c) 2004-2007 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 "plucked_string_synth.h" -#include "engine.h" -#include "instrument_track.h" -#include "knob.h" -#include "note_play_handle.h" -#include "templates.h" - -#undef SINGLE_SOURCE_COMPILE -#include "embed.cpp" - - -extern "C" -{ - -plugin::descriptor pluckedstringsynth_plugin_descriptor = -{ - STRINGIFY_PLUGIN_NAME( PLUGIN_NAME ), - "PluckedStringSynth", - QT_TRANSLATE_NOOP( "pluginBrowser", - "cheap synthesis of guitar/harp-like sounds" ), - "Tobias Doerffel ", - 0x0100, - plugin::Instrument, - new QPixmap( PLUGIN_NAME::getIconPixmap( "logo" ) ), - NULL -} ; - -} - - -// TODO: make this synth stereo for better better spacial (room) feeling and -// add distortion - -pluckedStringSynth::pluckedStringSynth( instrumentTrack * _instrument_track ) : - instrument( _instrument_track, &pluckedstringsynth_plugin_descriptor ), - m_pickModel( 0.0f, 0.0f, 0.5f, 0.005f, this ), - m_pickupModel( 0.05f, 0.0f, 0.5f, 0.005f, this ) -{ -} - - - - -pluckedStringSynth::~pluckedStringSynth() -{ -} - - - - -void pluckedStringSynth::saveSettings( QDomDocument & _doc, - QDomElement & _this ) -{ - m_pickModel.saveSettings( _doc, _this, "pick" ); - m_pickupModel.saveSettings( _doc, _this, "pickup" ); -} - - - - -void pluckedStringSynth::loadSettings( const QDomElement & _this ) -{ - m_pickModel.loadSettings( _this, "pick" ); - m_pickupModel.loadSettings( _this, "pickup" ); -} - - - - -QString pluckedStringSynth::nodeName( void ) const -{ - return( pluckedstringsynth_plugin_descriptor.name ); -} - - - - -void pluckedStringSynth::playNote( notePlayHandle * _n, bool ) -{ - if ( _n->totalFramesPlayed() == 0 ) - { - _n->m_pluginData = new pluckSynth( _n->frequency(), - m_pickModel.value(), - m_pickupModel.value(), - engine::getMixer()->sampleRate() ); - } - - const fpp_t frames = _n->framesLeftForCurrentPeriod(); - sampleFrame * buf = new sampleFrame[frames]; - - pluckSynth * ps = static_cast( _n->m_pluginData ); - for( fpp_t frame = 0; frame < frames; ++frame ) - { - const sample_t cur = ps->nextStringSample(); - for( Uint8 chnl = 0; chnl < DEFAULT_CHANNELS; ++chnl ) - { - buf[frame][chnl] = cur; - } - } - - getInstrumentTrack()->processAudioBuffer( buf, frames, _n ); - - delete[] buf; -} - - - - -void pluckedStringSynth::deleteNotePluginData( notePlayHandle * _n ) -{ - delete static_cast( _n->m_pluginData ); -} - - -pluginView * pluckedStringSynth::instantiateView( QWidget * _parent ) -{ - return( new pluckedStringSynthView( this, _parent ) ); -} - - -pluckedStringSynthView::pluckedStringSynthView( instrument * _instrument, - QWidget * _parent ) : - instrumentView( _instrument, _parent ) -{ - m_pickKnob = new knob( knobDark_28, this, tr( "Pick position" ) ); - m_pickKnob->move( 86, 134 ); - m_pickKnob->setHintText( tr( "Pick position:" ) + " ", "" ); - - m_pickupKnob = new knob( knobDark_28, this, tr( "Pickup position" ) ); - m_pickupKnob->move( 138, 134 ); - m_pickupKnob->setHintText( tr( "Pickup position:" ) + " ", "" ); - - setAutoFillBackground( TRUE ); - QPalette pal; - pal.setBrush( backgroundRole(), PLUGIN_NAME::getIconPixmap( - "artwork" ) ); - setPalette( pal ); -} - - -pluckedStringSynthView::~pluckedStringSynthView() -{ -} - - -void pluckedStringSynthView::modelChanged( void ) -{ - pluckedStringSynth * p = castModel(); - m_pickKnob->setModel( &p->m_pickModel ); - m_pickupKnob->setModel( &p->m_pickupModel ); -} - - -pluckSynth::delayLine * FASTCALL pluckSynth::initDelayLine( int _len ) -{ - delayLine * dl = new pluckSynth::delayLine[_len]; - dl->length = _len; - if( _len > 0 ) - { - dl->data = new sample_t[_len]; - } - else - { - dl->data = NULL; - } - - dl->pointer = dl->data; - dl->end = dl->data + _len - 1; - - return( dl ); -} - - - - -void FASTCALL pluckSynth::freeDelayLine( delayLine * _dl ) -{ - if( _dl ) - { - delete[] _dl->data; - delete[] _dl; - } -} - - - - -pluckSynth::pluckSynth( const float _pitch, const float _pick, - const float _pickup, const sample_rate_t _sample_rate ) -{ - const float AMP = 1.5f; - int rail_length = static_cast( _sample_rate / 2 / _pitch ) + 1; - // Round pick position to nearest spatial sample. - // A pick position at x = 0 is not allowed. - int pick_sample = static_cast( tMax( rail_length * _pick, - 1.0f ) ); - float initial_shape[rail_length]; - - m_upperRail = pluckSynth::initDelayLine( rail_length ); - m_lowerRail = pluckSynth::initDelayLine( rail_length ); - -//#define METALLIC_PLUCK -#ifdef METALLIC_PLUCK - for ( int i = 0; i < rail_length; i++ ) - { - initial_shape[i] = rand() * AMP / RAND_MAX; - } - - initial_shape[pick_sample] = 0.5; - initial_shape[pick_sample+1] = 0.5; - -#else - float upslope = AMP / pick_sample; - const float downslope = AMP / ( rail_length - pick_sample - 1 ); - - for( int i = 0; i < pick_sample; i++ ) - { - initial_shape[i] = upslope * i; - } - - for( int i = pick_sample; i < rail_length; i++ ) - { - initial_shape[i] = downslope * ( rail_length - 1 - i ); - } -#endif - - // Initial conditions for the ideal plucked string. - // "Past history" is measured backward from the end of the array. - pluckSynth::setDelayLine( m_lowerRail, initial_shape, 0.5f ); - pluckSynth::setDelayLine( m_upperRail, initial_shape, 0.5f ); - - m_pickupLoc = static_cast( _pickup * rail_length ); -} - - - - -extern "C" -{ - -// neccessary for getting instance out of shared lib -plugin * lmms_plugin_main( model *, void * _data ) -{ - return( new pluckedStringSynth( - static_cast( _data ) ) ); -} - - -} - - diff --git a/plugins/plucked_string_synth/plucked_string_synth.h b/plugins/plucked_string_synth/plucked_string_synth.h deleted file mode 100644 index 961214ce9..000000000 --- a/plugins/plucked_string_synth/plucked_string_synth.h +++ /dev/null @@ -1,238 +0,0 @@ -/* - * plucked_string_synth.h - declaration of class pluckedStringSynth which - * is a synth for plucked string-sounds - * - * Copyright (c) 2004-2006 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 _PLUCKED_STRING_SYNTH_H -#define _PLUCKED_STRING_SYNTH_H - -#include "instrument.h" -#include "instrument_view.h" -#include "knob.h" - - -class knob; -class notePlayHandle; - - -// the actual synth -class pluckSynth -{ -public: - pluckSynth( const float _pitch, const float _pick, const float _pickup, - const sample_rate_t _sample_rate ); - - inline ~pluckSynth( void ) - { - pluckSynth::freeDelayLine( m_upperRail ); - pluckSynth::freeDelayLine( m_lowerRail ); - } - - inline sample_t nextStringSample( void ) - { - // Output at pickup position - sample_t outsamp = rgDlAccess( m_upperRail, m_pickupLoc ); - outsamp += lgDlAccess( m_lowerRail, m_pickupLoc ); - - // Sample traveling into "bridge" - sample_t ym0 = lgDlAccess( m_lowerRail, 1 ); - // Sample to "nut" - sample_t ypM = rgDlAccess( m_upperRail, - m_upperRail->length - 2 ); - - // String state update - - // Decrement pointer and then update - rgDlUpdate( m_upperRail, -bridgeReflection( ym0 ) ); - // Update and then increment pointer - lgDlUpdate( m_lowerRail, -ypM ); - - return( outsamp ); - } - - -private: - struct delayLine - { - sample_t * data; - int length; - sample_t * pointer; - sample_t * end; - } ; - - delayLine * m_upperRail; - delayLine * m_lowerRail; - int m_pickupLoc; - - static delayLine * FASTCALL initDelayLine( int _len ); - static void FASTCALL freeDelayLine( delayLine * _dl ); - static inline void setDelayLine( delayLine * _dl, float * _values, - float _scale ) - { - for( int i = 0; i < _dl->length; ++i ) - { - _dl->data[i] = _scale * _values[i]; - } - } - - /* lgDlUpdate(dl, insamp); - * Places "nut-reflected" sample from upper delay-line into - * current lower delay-line pointer position (which represents - * x = 0 position). The pointer is then incremented (i.e. the - * wave travels one sample to the left), turning the previous - * position into an "effective" x = L position for the next - * iteration. */ - static inline void lgDlUpdate( delayLine * _dl, sample_t _insamp ) - { - register sample_t * ptr = _dl->pointer; - *ptr = _insamp; - ++ptr; - if( ptr > _dl->end ) - { - ptr = _dl->data; - } - _dl->pointer = ptr; - } - - /* rgDlUpdate(dl, insamp); - * Decrements current upper delay-line pointer position (i.e. - * the wave travels one sample to the right), moving it to the - * "effective" x = 0 position for the next iteration. The - * "bridge-reflected" sample from lower delay-line is then placed - * into this position. */ - static inline void rgDlUpdate( delayLine * _dl, sample_t _insamp ) - { - register sample_t * ptr = _dl->pointer; - --ptr; - if( ptr < _dl->data ) - { - ptr = _dl->end; - } - *ptr = _insamp; - _dl->pointer = ptr; - } - - /* dlAccess(dl, position); - * Returns sample "position" samples into delay-line's past. - * Position "0" points to the most recently inserted sample. */ - static inline sample_t dlAccess( delayLine * _dl, int _position ) - { - sample_t * outpos = _dl->pointer + _position; - while( outpos < _dl->data ) - { - outpos += _dl->length; - } - while( outpos > _dl->end ) - { - outpos -= _dl->length; - } - return( *outpos ); - } - - /* - * Right-going delay line: - * -->---->---->--- - * x=0 - * (pointer) - * Left-going delay line: - * --<----<----<--- - * x=0 - * (pointer) - */ - - /* rgDlAccess(dl, position); - * Returns spatial sample at position "position", where position zero - * is equal to the current upper delay-line pointer position (x = 0). - * In a right-going delay-line, position increases to the right, and - * delay increases to the right => left = past and right = future. */ - static inline sample_t rgDlAccess( delayLine * _dl, int _position ) - { - return( dlAccess( _dl, _position ) ); - } - - /* lgDlAccess(dl, position); - * Returns spatial sample at position "position", where position zero - * is equal to the current lower delay-line pointer position (x = 0). - * In a left-going delay-line, position increases to the right, and - * delay DEcreases to the right => left = future and right = past. */ - static inline sample_t lgDlAccess( delayLine * _dl, int _position ) - { - return( dlAccess( _dl, _position ) ); - } - - static inline sample_t bridgeReflection( sample_t _insamp ) - { - static sample_t state = 0.0f; // filter memory - // Implement a one-pole lowpass with feedback coefficient = 0.5 - return( state = state*0.5f + _insamp*0.5f ); - } - -} ; - - - - -class pluckedStringSynth : public instrument -{ -public: - pluckedStringSynth( instrumentTrack * _instrument_track ); - virtual ~pluckedStringSynth(); - - virtual void FASTCALL playNote( notePlayHandle * _n, - bool _try_parallelizing ); - virtual void FASTCALL deleteNotePluginData( notePlayHandle * _n ); - - - virtual void FASTCALL saveSettings( QDomDocument & _doc, - QDomElement & _parent ); - virtual void FASTCALL loadSettings( const QDomElement & _this ); - - virtual QString nodeName( void ) const; - - virtual pluginView * instantiateView( QWidget * _parent ); - -private: - knobModel m_pickModel; - knobModel m_pickupModel; - - friend class pluckedStringSynthView; -} ; - -class pluckedStringSynthView : public instrumentView -{ -public: - pluckedStringSynthView( instrument * _instrument, - QWidget * _parent ); - virtual ~pluckedStringSynthView(); - -private: - virtual void modelChanged( void ); - - knob * m_pickKnob; - knob * m_pickupKnob; - -} ; - - -#endif diff --git a/plugins/polyb302/Makefile.am b/plugins/polyb302/Makefile.am deleted file mode 100644 index 5c262f562..000000000 --- a/plugins/polyb302/Makefile.am +++ /dev/null @@ -1,33 +0,0 @@ -AUTOMAKE_OPTIONS = foreign 1.4 - - -INCLUDES = -I$(top_srcdir)/include -I$(top_srcdir)/src/gui -I. - - -AM_CXXFLAGS := $(AM_CXXFLAGS) $(QT_CXXFLAGS) -DPLUGIN_NAME="polyb302" - - -%.moc: ./%.h - $(MOC) -o $@ $< - - -MOC_FILES = ./polyb302.moc - -BUILT_SOURCES = $(MOC_FILES) ./embedded_resources.h -EMBEDDED_RESOURCES = $(wildcard *png) - -./embedded_resources.h: $(EMBEDDED_RESOURCES) - $(BIN2RES) $(EMBEDDED_RESOURCES) > $@ - -EXTRA_DIST = $(EMBEDDED_RESOURCES) - - -CLEANFILES = $(MOC_FILES) ./embedded_resources.h - - - -pkglib_LTLIBRARIES = libpolyb302.la - -libpolyb302_la_SOURCES = polyb302.cpp polyb302.h - -$(libpolyb302_la_SOURCES): ./embedded_resources.h diff --git a/plugins/polyb302/artwork.png b/plugins/polyb302/artwork.png deleted file mode 100644 index d8a25feff..000000000 Binary files a/plugins/polyb302/artwork.png and /dev/null differ diff --git a/plugins/polyb302/logo.png b/plugins/polyb302/logo.png deleted file mode 100644 index 456a42675..000000000 Binary files a/plugins/polyb302/logo.png and /dev/null differ diff --git a/plugins/polyb302/polyb302.cpp b/plugins/polyb302/polyb302.cpp deleted file mode 100644 index ffc90eeed..000000000 --- a/plugins/polyb302/polyb302.cpp +++ /dev/null @@ -1,926 +0,0 @@ -/* - * polyb302.cpp - implementation of instrument polyb302, an attempt to emulate - * the Roland TB303 bass synth - * - * Copyright (c) 2006-2007 Paul Giblock - * - * This file is part of Linux MultiMedia Studio - http://lmms.sourceforge.net - * - * lb302FilterIIR2 is based on the gsyn filter code by Andy Sloane. - * - * lb302Filter3Pole is based on the TB303 instrument written by - * Josep M Comajuncosas for the CSounds library - * - * 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 "polyb302.h" -#include "engine.h" -#include "knob.h" -#include "led_checkbox.h" -#include "note_play_handle.h" - -#undef SINGLE_SOURCE_COMPILE -#include "embed.cpp" -#include "polyb302.moc" - - -// Envelope Recalculation period -#define ENVINC 64 - -// -// New config -// -#define LB_24_IGNORE_ENVELOPE -#define LB_FILTERED -//#define LB_24_RES_TRICK - -#define LB_DIST_RATIO 4.0 -#define LB_24_VOL_ADJUST 3.0 - - - - -using namespace std; -extern "C" -{ - -plugin::descriptor polyb302_plugin_descriptor = -{ - STRINGIFY_PLUGIN_NAME( PLUGIN_NAME ), - "PoLyB302", - QT_TRANSLATE_NOOP( "pluginBrowser", - "Incomplete polyphonic immitation tb303" ), - "Javier Serrano Polo ", - 0x0100, - plugin::Instrument, - new QPixmap( PLUGIN_NAME::getIconPixmap( "logo" ) ), - NULL -} ; - - -// necessary for getting instance out of shared lib -plugin * lmms_plugin_main( void * _data ) -{ - return( new polyb302Synth( static_cast( _data ) ) ); -} - -} - - - -// -// lb302Filter -// - -lb302Filter::lb302Filter( lb302FilterState * _p_fs ) : - m_fs( _p_fs ), - m_vcf_c0( 0 ), - m_vcf_e0( 0 ), - m_vcf_e1( 0 ) -{ -} - - - - -void lb302Filter::recalc( void ) -{ - m_vcf_e1 = exp( 4.909 + 1.5876 * m_fs->envmod + 2.1553 * m_fs->cutoff - + 1.2 * m_fs->reso ); - m_vcf_e0 = exp( 4.8434 - 0.8 * m_fs->envmod + 2.1553 * m_fs->cutoff - + 0.7696 * m_fs->reso ); - m_vcf_e0 *= M_PI / engine::getMixer()->sampleRate(); - m_vcf_e1 *= M_PI / engine::getMixer()->sampleRate(); - m_vcf_e1 -= m_vcf_e0; -} - - - - -void lb302Filter::envRecalc( void ) -{ - // Filter Decay. vcf_decay is adjusted for Hz and ENVINC - m_vcf_c0 *= m_fs->envdecay; - m_vcf_rescoeff = exp( -1.20 + 3.455 * m_fs->reso ); -} - - - - -void lb302Filter::playNote( void ) -{ - m_vcf_c0 = m_vcf_e1; -} - - - -// -// lb302FilterIIR2 -// - -lb302FilterIIR2::lb302FilterIIR2( lb302FilterState * _p_fs ) : - lb302Filter( _p_fs ), - m_vcf_d1( 0 ), - m_vcf_d2( 0 ), - m_vcf_a( 0 ), - m_vcf_b( 0 ), - m_vcf_c( 1 ) -{ - m_dist = new effectLib::distortion<>( 1.0, 1.0f ); -} - - - - -lb302FilterIIR2::~lb302FilterIIR2() -{ - delete m_dist; -} - - - - -void lb302FilterIIR2::recalc( void ) -{ - lb302Filter::recalc(); - //m_dist->setThreshold(0.5+(m_fs->dist*2.0)); - m_dist->setThreshold( m_fs->dist * 75.0 ); -} - - - - -void lb302FilterIIR2::envRecalc( void ) -{ - lb302Filter::envRecalc(); - - // e0 is adjusted for Hz and doesn't need ENVINC - float w = m_vcf_e0 + m_vcf_c0; - float k = exp( -w / m_vcf_rescoeff ); - // Does this mean c0 is inheritantly? - m_vcf_a = 2.0 * cos( 2.0 * w ) * k; - m_vcf_b = -k * k; - m_vcf_c = 1.0 - m_vcf_a - m_vcf_b; -} - - - - -float lb302FilterIIR2::process( const float & _samp ) -{ - float ret = m_vcf_a * m_vcf_d1 + m_vcf_b * m_vcf_d2 + m_vcf_c * _samp; - // Delayed samples for filter - m_vcf_d2 = m_vcf_d1; - m_vcf_d1 = ret; - - if( m_fs->dist > 0 ) - { - ret = m_dist->nextSample( ret ); - } - // output = IIR2 + dry - return( ret ); -} - - - -// -// lb302Filter3Pole -// - -lb302Filter3Pole::lb302Filter3Pole( lb302FilterState * _p_fs ) : - lb302Filter( _p_fs ), - m_ay1( 0 ), - m_ay2( 0 ), - m_aout( 0 ), - m_lastin( 0 ) -{ -} - - - - -void lb302Filter3Pole::recalc( void ) -{ - // DO NOT CALL BASE CLASS - m_vcf_e0 = 0.000001; - m_vcf_e1 = 1.0; -} - - - - -// TODO: Try using k instead of vcf_reso -void lb302Filter3Pole::envRecalc( void ) -{ - lb302Filter::envRecalc(); - - - // e0 is adjusted for Hz and doesn't need ENVINC - float w = m_vcf_e0 + m_vcf_c0; - float k = ( m_fs->cutoff > 0.975 ) ? 0.975 : m_fs->cutoff; - //TODO: Fix high quality - float kfco = 50.0f + k * ( 2300.0f - 1600.0f * m_fs->envmod - + w * ( 700.0f + 1500.0f * k + ( 1500.0f + k * ( - engine::getMixer()->sampleRate() / 2.0f - 6000.0f ) ) - * m_fs->envmod ) ); - //+iacc*(.3+.7*kfco*kenvmod)*kaccent*kaccurve*2000 - - -#ifdef LB_24_IGNORE_ENVELOPE - // m_kfcn = m_fs->cutoff; - m_kfcn = 2.0 * kfco / engine::getMixer()->sampleRate(); -#else - m_kfcn = w; -#endif - m_kp = ( ( -2.7528 * m_kfcn + 3.0429 ) * m_kfcn + 1.718 ) * m_kfcn - - 0.9984; - m_kp1 = m_kp + 1.0; - m_kp1h = 0.5 * m_kp1; -#ifdef LB_24_RES_TRICK - k = exp( -w / m_vcf_rescoeff ); - m_kres = k * ( ( ( -2.7079 * m_kp1 + 10.963 ) * m_kp1 - 14.934 ) * m_kp1 - + 8.4974 ); -#else - m_kres = m_fs->reso * ( ( ( -2.7079 * m_kp1 + 10.963 ) * m_kp1 - - 14.934 ) * m_kp1 + 8.4974 ); -#endif - // ENVMOD was DIST*/ - m_value = 1.0 + ( m_fs->dist * ( 1.5 + 2.0 * m_kres - * ( 1.0 - m_kfcn ) ) ); -} - - - - -float lb302Filter3Pole::process( const float & _samp ) -{ - float ax1 = m_lastin; - float ay11 = m_ay1; - float ay31 = m_ay2; - m_lastin = _samp - tanh( m_kres * m_aout ); - m_ay1 = m_kp1h * ( m_lastin + ax1 ) - m_kp * m_ay1; - m_ay2 = m_kp1h * ( m_ay1 + ay11 ) - m_kp * m_ay2; - m_aout = m_kp1h * ( m_ay2 + ay31 ) - m_kp * m_aout; - - return( tanh( m_aout * m_value ) * LB_24_VOL_ADJUST - / ( 1.0 + m_fs->dist ) ); -} - - - -// -// PoLyBSynth -// - -polyb302Synth::polyb302Synth( instrumentTrack * _track ) : - instrument( _track, &polyb302_plugin_descriptor ) -{ - m_vcf_cut_knob = new knob( knobBright_26, this, - tr( "VCF Cutoff Frequency" ), - _track ); - m_vcf_cut_knob->setRange( 0.0f, 1.5f, 0.005f ); // Originally [0,1.0] - m_vcf_cut_knob->setInitValue( 0.75f ); - m_vcf_cut_knob->move( 75, 130 ); - m_vcf_cut_knob->setHintText( tr( "Cutoff Freq:" ) + " ", "" ); - m_vcf_cut_knob->setLabel( tr( "CUT" ) ); - - m_vcf_res_knob = new knob( knobBright_26, this, tr( "VCF Resonance" ), - _track ); - m_vcf_res_knob->setRange( 0.0f, 1.25f, 0.005f ); // Originally [0,1.0] - m_vcf_res_knob->setInitValue( 0.75f ); - m_vcf_res_knob->move( 120, 130 ); - m_vcf_res_knob->setHintText( tr( "Resonance:" ) + " ", "" ); - m_vcf_res_knob->setLabel( tr( "RES" ) ); - - m_vcf_mod_knob = new knob( knobBright_26, this, - tr( "VCF Envelope Mod" ), - _track ); - m_vcf_mod_knob->setRange( 0.0f, 1.0f, 0.005f ); // Originally [0,1.0] - m_vcf_mod_knob->setInitValue( 1.0f ); - m_vcf_mod_knob->move( 165, 130 ); - m_vcf_mod_knob->setHintText( tr( "Env Mod:" ) + " ", "" ); - m_vcf_mod_knob->setLabel( tr( "ENV MOD" ) ); - - m_vcf_dec_knob = new knob( knobBright_26, this, - tr( "VCF Envelope Decay" ), - _track ); - m_vcf_dec_knob->setRange( 0.0f, 1.0f, 0.005f ); // Originally [0,1.0] - m_vcf_dec_knob->setInitValue( 0.1f ); - m_vcf_dec_knob->move( 210, 130 ); - m_vcf_dec_knob->setHintText( tr( "Decay:" ) + " ", "" ); - m_vcf_dec_knob->setLabel( tr( "DEC" ) ); - -// m_slideToggle = new ledCheckBox( "Slide", this, tr( "Slide" ), _track ); -// m_slideToggle->move( 10, 180 ); - -// m_accentToggle = new ledCheckBox( "Accent", this, -// tr( "Accent" ), -// _track ); -// m_accentToggle->move( 10, 200 ); -// m_accentToggle->setDisabled(true); - -// m_deadToggle = new ledCheckBox( "Dead", this, tr( "Dead" ), _track ); -// m_deadToggle->move( 10, 220 ); - - m_db24Toggle = new ledCheckBox( "24dB/oct", this, - tr( "303-es-que, 24dB/octave, 3 pole filter" ), - _track ); - m_db24Toggle->move( 10, 150 ); - - - m_slide_dec_knob = new knob( knobBright_26, this, tr( "Slide Decay" ), - _track ); - m_slide_dec_knob->setRange( 0.0f, 1.0f, 0.005f ); // Originally [0,1.0] - m_slide_dec_knob->setInitValue( 0.6f ); - m_slide_dec_knob->move( 210, 75 ); - m_slide_dec_knob->setHintText( tr( "Slide Decay:" ) + " ", "" ); - m_slide_dec_knob->setLabel( tr( "SLIDE" ) ); - - m_vco_fine_detune_knob = new knob( knobBright_26, this, - tr( "VCO fine detuning" ), - _track ); - m_vco_fine_detune_knob->setRange( -100.0f, 100.0f, 1.0f ); - m_vco_fine_detune_knob->setInitValue( 0.0f ); - m_vco_fine_detune_knob->move( 165, 75 ); - m_vco_fine_detune_knob->setHintText( tr( "VCO Fine Detuning:" ) + " ", - "cents" ); - m_vco_fine_detune_knob->setLabel( tr( "DETUNE" ) ); - - - m_dist_knob = new knob( knobBright_26, this, tr( "Distortion" ), - _track ); - m_dist_knob->setRange( 0.0f, 1.0f, 0.01f ); // Originally [0,1.0] - m_dist_knob->setInitValue( 0.0f ); - m_dist_knob->move( 210, 190 ); - m_dist_knob->setHintText( tr( "DIST:" ) + " ", "" ); - m_dist_knob->setLabel( tr( "DIST" ) ); - - - m_wave_knob = new knob( knobBright_26, this, tr( "Waveform" ), _track ); - m_wave_knob->setRange( 0.0f, 5.0f, 1.0f ); // Originally [0,1.0] - m_wave_knob->setInitValue( 0.0f ); - m_wave_knob->move( 120, 75 ); - m_wave_knob->setHintText( tr( "WAVE:" ) + " ", "" ); - m_wave_knob->setLabel( tr( "WAVE" ) ); - - - setAutoFillBackground( TRUE ); - QPalette pal; - pal.setBrush( backgroundRole(), PLUGIN_NAME::getIconPixmap( - "artwork" ) ); - setPalette( pal ); - - connect( m_vcf_cut_knob, SIGNAL( valueChanged( float ) ), - this, SLOT ( filterChanged( float ) ) ); - connect( m_vcf_res_knob, SIGNAL( valueChanged( float ) ), - this, SLOT ( filterChanged( float ) ) ); - connect( m_vcf_mod_knob, SIGNAL( valueChanged( float ) ), - this, SLOT ( filterChanged( float ) ) ); - connect( m_vcf_dec_knob, SIGNAL( valueChanged( float ) ), - this, SLOT ( filterChanged( float ) ) ); - connect( m_vco_fine_detune_knob, SIGNAL( valueChanged( float ) ), - this, SLOT ( detuneChanged( float) ) ); - connect( m_db24Toggle, SIGNAL( toggled( bool ) ), - this, SLOT ( db24Toggled( bool) ) ); - connect( m_dist_knob, SIGNAL( valueChanged(float) ), - this, SLOT ( filterChanged( float ) ) ); - connect( m_wave_knob, SIGNAL( valueChanged( float ) ), - this, SLOT ( waveChanged( float ) ) ); -} - - - - -polyb302Synth::~polyb302Synth() -{ -} - - - - -void polyb302Synth::saveSettings( QDomDocument & _doc, QDomElement & _this ) -{ - m_vcf_cut_knob->saveSettings( _doc, _this, "vcf_cut" ); - m_vcf_res_knob->saveSettings( _doc, _this, "vcf_res" ); - m_vcf_mod_knob->saveSettings( _doc, _this, "vcf_mod" ); - m_vcf_dec_knob->saveSettings( _doc, _this, "vcf_dec" ); - - m_vco_fine_detune_knob->saveSettings( _doc, _this, "vco_detune" ); - m_wave_knob->saveSettings( _doc, _this, "shape" ); - m_dist_knob->saveSettings( _doc, _this, "dist" ); - m_slide_dec_knob->saveSettings( _doc, _this, "slide_dec" ); - -// m_slideToggle->saveSettings( _doc, _this, "slide" ); -// m_deadToggle->saveSettings( _doc, _this, "dead" ); - m_db24Toggle->saveSettings( _doc, _this, "db24"); -} - - - - -void polyb302Synth::loadSettings( const QDomElement & _this ) -{ - m_vcf_cut_knob->loadSettings( _this, "vcf_cut" ); - m_vcf_res_knob->loadSettings( _this, "vcf_res" ); - m_vcf_mod_knob->loadSettings( _this, "vcf_mod" ); - m_vcf_dec_knob->loadSettings( _this, "vcf_dec" ); - - m_vco_fine_detune_knob->loadSettings( _this, "vco_detune" ); - m_dist_knob->loadSettings( _this, "dist" ); - m_wave_knob->loadSettings( _this, "shape" ); - m_slide_dec_knob->loadSettings( _this, "slide_dec" ); - -// m_slideToggle->loadSettings( _this, "slide" ); -// m_deadToggle->loadSettings( _this, "dead" ); - m_db24Toggle->loadSettings( _this, "db24" ); -} - - - - -QString polyb302Synth::nodeName( void ) const -{ - return( polyb302_plugin_descriptor.name ); -} - - - - -void polyb302Synth::playNote( notePlayHandle * _n, bool ) -{ - //int nidx = _n->index(); - - //if( _n->nphsOfInstrumentTrack(_n->getInstrumentTrack()).first() != _n ) - //if( _n->released() && _n->nphsOfInstrumentTrack( _n->getInstrumentTrack() ).count() > 1 ) - // return; - -/* - if (_n->released() ) { - if( notePlayHandle::nphsOfInstrumentTrack( getInstrumentTrack() ).size() > 0 - && notePlayHandle::nphsOfInstrumentTrack( getInstrumentTrack(), - TRUE ).last() == _n ) - { - return; - } - } -*/ - - handleState * hstate; - if( !_n->m_pluginData ) - { - hstate = new handleState( this ); - _n->m_pluginData = hstate; - m_handleStates.push_back( hstate ); - } - else - { - hstate = (handleState *)_n->m_pluginData; - } - - if( _n->totalFramesPlayed() <= hstate->m_lastFramesPlayed ) - { - // TODO: Try moving to the if() below -// if( m_deadToggle->value() == 0 ) - { - hstate->m_sample_cnt = 0; - hstate->m_vca_mode = 0; - hstate->m_vca_a = 0; - } - - // Adjust inc on SampRate change or detuning change - hstate->m_vco_inc = hstate->m_vco_detune - / engine::getMixer()->sampleRate(); - - // Initiate Slide - // TODO: Break out into function, - // should be called again on detuneChanged - if( hstate->m_vco_slideinc ) - { - hstate->m_vco_slide = hstate->m_vco_inc - - hstate->m_vco_slideinc; - hstate->m_vco_slidebase = hstate->m_vco_inc; - hstate->m_vco_slideinc = 0; - } - else - { - hstate->m_vco_slide = 0; - } - // End break-out - - // Slide note, save inc for next note -// if( m_slideToggle->value() ) -// { -// hstate->m_vco_slideinc = hstate->m_vco_inc; - // May need to equal m_vco_slidebase+m_vco_slide if last - // note slid -// } - - - hstate->recalcFilter(); - -// if( m_deadToggle->value() == 0 ) - { - // Swap next two blocks?? - hstate->m_vcf->playNote(); - // Ensure envelope is recalculated - hstate->m_vcf_envpos = ENVINC; - - // Double Check - hstate->m_vca_mode = 0; - hstate->m_vca_a = 0.0; - } - } - - const fpp_t frames = _n->framesLeftForCurrentPeriod(); - sampleFrame * buf = new sampleFrame[frames]; - - hstate->process( buf, frames, _n->frequency() ); - getInstrumentTrack()->processAudioBuffer( buf, frames, _n ); - - delete[] buf; - - hstate->m_lastFramesPlayed = _n->totalFramesPlayed(); -} - - - - -void polyb302Synth::deleteNotePluginData( notePlayHandle * _n ) -{ - handleState * hstate = (handleState *)_n->m_pluginData; - m_handleStates.removeAll( hstate ); - delete hstate; -} - - - - -void polyb302Synth::db24Toggled( bool ) -{ - for( QList::iterator it = m_handleStates.begin(); - it != m_handleStates.end(); ++it ) - { - ( *it )->db24Toggled(); - } -} - - - - -void polyb302Synth::detuneChanged( float ) -{ - for( QList::iterator it = m_handleStates.begin(); - it != m_handleStates.end(); ++it ) - { - ( *it )->detuneChanged(); - } -} - - - - -// TODO: Split into one function per knob. envdecay doesn't require -// recalcFilter. -void polyb302Synth::filterChanged( float ) -{ - for( QList::iterator it = m_handleStates.begin(); - it != m_handleStates.end(); ++it ) - { - ( *it )->filterChanged(); - } -} - - - - -// TODO: Set m_vco_shape in here. -void polyb302Synth::waveChanged( float ) -{ - switch( (int)rint( m_wave_knob->value() ) ) - { - case 0: - m_wave_knob->setHintText( tr( "Sawtooth " ), "" ); - break; - case 1: - m_wave_knob->setHintText( tr( "Inverted Sawtooth " ), - "" ); - break; - case 2: - m_wave_knob->setHintText( tr( "Triangle " ), "" ); - break; - case 3: - m_wave_knob->setHintText( tr( "Square " ), "" ); - break; - case 4: - m_wave_knob->setHintText( tr( "Rounded Square " ), "" ); - break; - case 5: - m_wave_knob->setHintText( tr( "Moog " ), "" ); - break; - } -} - - - - - - - - -polyb302Synth::handleState::handleState( const polyb302Synth * _synth ) -{ - m_vco_inc = 0.0; - m_vco_c = 0; - m_vco_k = 0; - - m_vco_slide = 0; - m_vco_slideinc = 0; - - m_fs.cutoff = 0; - m_fs.envmod = 0; - m_fs.reso = 0; - m_fs.envdecay = 0; - m_fs.dist = 0; - - m_vcf_envpos = ENVINC; - m_vco_detune = 0; - - // Start VCA on an attack. - m_vca_mode = 0; - m_vca_a = 0; - //m_vca_attack = 1.0 - 0.94406088; - m_vca_attack = 1.0 - 0.96406088; - m_vca_decay = 0.99897516; - - m_vco_shape = SAWTOOTH; - - // Experimenting between original (0.5) and 1.0 - m_vca_a0 = 0.5; - - if( _synth->m_db24Toggle->isChecked() ) - { - m_vcf = new lb302Filter3Pole( &m_fs ); - } - else - { - m_vcf = new lb302FilterIIR2( &m_fs ); - } - recalcFilter(); - - m_lastFramesPlayed = 0; - - m_synth = _synth; - - filterChanged(); - detuneChanged(); -} - - - - -polyb302Synth::handleState::~handleState() -{ - delete m_vcf; -} - - - - -void polyb302Synth::handleState::db24Toggled( void ) -{ - delete m_vcf; - if( m_synth->m_db24Toggle->isChecked() ) - { - m_vcf = new lb302Filter3Pole( &m_fs ); - } - else - { - m_vcf = new lb302FilterIIR2( &m_fs ); - } - recalcFilter(); -} - - - - -void polyb302Synth::handleState::detuneChanged( void ) -{ - m_vco_detune = powf( 2.0f, - (float)m_synth->m_vco_fine_detune_knob->value() - / 1200.0f ); - m_vco_inc = m_vco_detune / engine::getMixer()->sampleRate(); - - // If a slide note is pending, - if( m_vco_slideinc ) - { - m_vco_slideinc = m_vco_inc; - } - - // If currently sliding, - // May need to rescale m_vco_slide as well - if( m_vco_slide ) - { - m_vco_slidebase = m_vco_detune - / engine::getMixer()->sampleRate(); - } -} - - - - -// TODO: Split into one function per knob. envdecay doesn't require -// recalcFilter. -void polyb302Synth::handleState::filterChanged( void ) -{ - m_fs.cutoff = m_synth->m_vcf_cut_knob->value(); - m_fs.reso = m_synth->m_vcf_res_knob->value(); - m_fs.envmod = m_synth->m_vcf_mod_knob->value(); - m_fs.dist = LB_DIST_RATIO * m_synth->m_dist_knob->value(); - - float d = 0.2 + 2.3 * m_synth->m_vcf_dec_knob->value(); - d *= engine::getMixer()->sampleRate(); - // decay is 0.1 to the 1/d * ENVINC - m_fs.envdecay = pow( 0.1, ENVINC / d ); - // vcf_envdecay is now adjusted for both - // sampling rate and ENVINC - recalcFilter(); -} - - - - -// OBSOLETE. Break apart once we get Q_OBJECT to work. >:[ -void polyb302Synth::handleState::recalcFilter( void ) -{ - m_vcf->recalc(); - - // THIS IS OLD 3pole/24dB code, I may reintegrate it. Don't need it - // right now. Should be toggled by LB_24_RES_TRICK at the moment. - - /*kfcn = 2.0 * (((vcf_cutoff*3000))) / m_LB_HZ; - kp = ((-2.7528*kfcn + 3.0429)*kfcn + 1.718)*kfcn - 0.9984; - kp1 = kp+1.0; - kp1h = 0.5*kp1; - kres = (((vcf_reso))) * (((-2.7079*kp1 + 10.963)*kp1 - 14.934)*kp1 + 8.4974); - value = 1.0+( (((0))) *(1.5 + 2.0*kres*(1.0-kfcn))); // ENVMOD was DIST*/ - - m_vcf_envpos = ENVINC; // Trigger filter update in process() -} - - - - -void polyb302Synth::handleState::process( sampleFrame * _outbuf, - const Uint32 _size, - float _freq ) -{ - for( Uint32 i = 0; i < _size; i++ ) - { - // update m_vcf - if( m_vcf_envpos >= ENVINC ) - { - m_vcf->envRecalc(); - - m_vcf_envpos = 0; - - if( m_vco_slide ) - { - m_vco_inc = m_vco_slidebase - m_vco_slide; - // Calculate coeff from dec_knob on knob change. - // TODO: Adjust for ENVINC - m_vco_slide *= 0.9 - + ( m_synth->m_slide_dec_knob->value() - * 0.0999 ); - } - } - - m_sample_cnt++; - m_vcf_envpos++; - - // update vco - m_vco_c += m_vco_inc * _freq; - if( m_vco_c > 0.5 ) - { - m_vco_c -= 1.0; - } - - switch( (int)rint( m_synth->m_wave_knob->value() ) ) - { - case 0: m_vco_shape = SAWTOOTH; break; - case 1: m_vco_shape = INVERTED_SAWTOOTH; break; - case 2: m_vco_shape = TRIANGLE; break; - case 3: m_vco_shape = SQUARE; break; - case 4: m_vco_shape = ROUND_SQUARE; break; - case 5: m_vco_shape = MOOG; break; - default: m_vco_shape = SAWTOOTH; break; - } - - // add m_vco_shape_param the changes the shape of each curve. - // merge sawtooths with triangle and square with round square? - switch( m_vco_shape ) - { - case SAWTOOTH: // p0: curviness of line - // Is this sawtooth backwards? - m_vco_k = m_vco_c; - break; - - case INVERTED_SAWTOOTH: // p0: curviness of line - // Is this sawtooth backwards? - m_vco_k = -m_vco_c; - break; - - // TODO: I think TRIANGLE is broken. - // p0: duty rev.saw<->triangle<->saw p1: curviness - case TRIANGLE: - m_vco_k = m_vco_c * 2.0 + 0.5; - if( m_vco_k > 0.5 ) - { - m_vco_k = 1.0 - m_vco_k; - } - break; - - case SQUARE: // p0: slope of top - m_vco_k = ( m_vco_c < 0 ) ? 0.5 : -0.5; - break; - - case ROUND_SQUARE: // p0: width of round - m_vco_k = ( m_vco_c < 0 ) ? - sqrtf( 1 - m_vco_c * m_vco_c * 4 ) - - 0.5 : - -0.5; - break; - - // Maybe the fall should be exponential/sinsoidal - // instead of quadric. - case MOOG: - // [-0.5, 0]: Rise, [0,0.25]: Slope down, - // [0.25,0.5]: Low - m_vco_k = m_vco_c * 2.0 + 0.5; - if( m_vco_k > 1.0 ) - { - m_vco_k = -0.5; - } - else if( m_vco_k > 0.5 ) - { - float w = 2 * ( m_vco_k - 0.5 ) - 1; - m_vco_k = 0.5 - sqrtf( 1 - w * w ); - // MOOG wave gets filtered away - m_vco_k *= 2.0; - } - break; - } - - // Write out samples. -#ifdef LB_FILTERED - float samp = m_vcf->process( m_vco_k ) * 2.0 * m_vca_a; -#else - float samp = m_vco_k * m_vca_a; -#endif - - for( int c = 0; c < DEFAULT_CHANNELS; c++ ) - { - _outbuf[i][c] = samp; - } - - - // Handle Envelope - // TODO: Add decay once I figure out how to extend past the end - // of a note. - if( m_vca_mode == 0 ) - { - m_vca_a += ( m_vca_a0 - m_vca_a ) * m_vca_attack; - if( m_sample_cnt >= 0.5 - * engine::getMixer()->sampleRate() ) - { - m_vca_mode = 2; - } - } - else if( m_vca_mode == 1 ) - { - m_vca_a *= m_vca_decay; - // the following line actually speeds up processing - if( m_vca_a < 1 / 65536.0 ) - { - m_vca_a = 0; - m_vca_mode = 2; - } - } - - } -} diff --git a/plugins/polyb302/polyb302.h b/plugins/polyb302/polyb302.h deleted file mode 100644 index c32919f76..000000000 --- a/plugins/polyb302/polyb302.h +++ /dev/null @@ -1,252 +0,0 @@ -/* - * polyb302.h - declaration of instrument polyb302, an attempt to emulate the - * Roland TB303 bass synth - * - * Copyright (c) 2006-2007 Paul Giblock - * - * This file is part of Linux MultiMedia Studio - http://lmms.sourceforge.net - * - * lb302FilterIIR2 is based on the gsyn filter code by Andy Sloane. - * - * lb302Filter3Pole is based on the TB303 instrument written by - * Josep M Comajuncosas for the CSounds library - * - * 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 _POLYB302_H_ -#define _POLYB302_H_ - -#include "effect_lib.h" -#include "instrument.h" -#include "mixer.h" - - -class knob; -class ledCheckBox; -class notePlayHandle; - - -typedef struct -{ - float cutoff; - float reso; - float envmod; - float envdecay; - float dist; -} lb302FilterState; - - - - -class lb302Filter -{ -public: - lb302Filter( lb302FilterState * _p_fs ); - virtual ~lb302Filter() {}; - - virtual void recalc( void ); - virtual void envRecalc( void ); - virtual float process( const float & _samp ) = 0; - virtual void playNote( void ); - - -protected: - lb302FilterState * m_fs; - - // Filter Decay - float m_vcf_c0; // c0=e1 on retrigger; c0*=ed every sample; cutoff=e0+c0 - float m_vcf_e0; // e0 and e1 for interpolation - float m_vcf_e1; - float m_vcf_rescoeff; // Resonance coefficient [0.30,9.54] - -}; - - - - -class lb302FilterIIR2 : public lb302Filter -{ -public: - lb302FilterIIR2( lb302FilterState * _p_fs ); - virtual ~lb302FilterIIR2(); - - virtual void recalc( void ); - virtual void envRecalc( void ); - virtual float process( const float & _samp ); - - -protected: - float m_vcf_d1; // d1 and d2 are added back into the sample with - float m_vcf_d2; // vcf_a and b as coefficients. IIR2 resonance - // loop. - - // IIR2 Coefficients for mixing dry and delay. - float m_vcf_a; // Mixing coefficients for the final sound. - float m_vcf_b; - float m_vcf_c; - - effectLib::distortion<> * m_dist; - -}; - - - - -class lb302Filter3Pole : public lb302Filter -{ -public: - lb302Filter3Pole( lb302FilterState * _p_fs ); - - virtual void envRecalc( void ); - virtual void recalc( void ); - virtual float process( const float & _samp ); - - -protected: - float m_kfcn, - m_kp, - m_kp1, - m_kp1h, - m_kres; - float m_ay1, - m_ay2, - m_aout, - m_lastin, - m_value; -}; - - - - -class polyb302Synth : public instrument -{ - Q_OBJECT -public: - polyb302Synth( instrumentTrack * _track ); - virtual ~polyb302Synth(); - - virtual void FASTCALL playNote( notePlayHandle * _n, - bool _try_parallelizing ); - virtual void FASTCALL deleteNotePluginData( notePlayHandle * _n ); - - - virtual void FASTCALL saveSettings( QDomDocument & _doc, - QDomElement & _parent ); - virtual void FASTCALL loadSettings( const QDomElement & _this ); - - virtual QString nodeName( void ) const; - - -public slots: - void db24Toggled( bool ); - void detuneChanged( float ); - void filterChanged( float ); - void waveChanged( float ); - - -private: - class handleState - { - public: - handleState( const polyb302Synth * _synth ); - virtual ~handleState(); - - enum vco_shape_t { - SAWTOOTH, INVERTED_SAWTOOTH, SQUARE, TRIANGLE, MOOG, - ROUND_SQUARE - }; - - // Oscillator - // Sample increment for the frequency. Creates Sawtooth. - float m_vco_inc; - // Raw oscillator sample [-0.5,0.5] - float m_vco_k; - // Raw oscillator sample [-0.5,0.5] - float m_vco_c; - - // Current value of slide exponential curve. Nonzero=sliding - float m_vco_slide; - // Slide base to use in next node. Nonzero=slide next note - float m_vco_slideinc; - // The base vco_inc while sliding. - float m_vco_slidebase; - - float m_vco_detune; - - vco_shape_t m_vco_shape; - - // User settings - lb302FilterState m_fs; - lb302Filter * m_vcf; - - float m_lastFramesPlayed; - - // More States - // Update counter. Updates when >= ENVINC - int m_vcf_envpos; - - float m_vca_attack; // Amp attack - float m_vca_decay; // Amp decay - float m_vca_a0; // Initial amplifier coefficient - float m_vca_a; // Amplifier coefficient. - - // Envelope State - int m_vca_mode; // 0: attack, 1: decay, 2: idle - - // My hacks - int m_sample_cnt; - - // TODO: split synth slots - const polyb302Synth * m_synth; - - void recalcFilter( void ); - - void process( sampleFrame * _outbuf, const Uint32 _size, - float _freq ); - - void db24Toggled( void ); - void detuneChanged( void ); - void filterChanged( void ); - - } ; - - - knob * m_vcf_cut_knob; - knob * m_vcf_res_knob; - knob * m_vcf_dec_knob; - knob * m_vcf_mod_knob; - - knob * m_vco_fine_detune_knob; - - knob * m_dist_knob; - knob * m_wave_knob; - -// ledCheckBox * m_slideToggle; -// ledCheckBox * m_accentToggle; -// ledCheckBox * m_deadToggle; - ledCheckBox * m_db24Toggle; - - knob * m_slide_dec_knob; - - QList m_handleStates; - -} ; - - -#endif