diff --git a/data/themes/default/style.css b/data/themes/default/style.css index 0d199ba12..5dde74977 100644 --- a/data/themes/default/style.css +++ b/data/themes/default/style.css @@ -472,6 +472,14 @@ sf2InstrumentView knob { qproperty-lineWidth: 2; } +sfxrInstrumentView knob { + color: #b06319; + qproperty-outerColor: rgb(194, 177, 145); + qproperty-innerRadius: 2; + qproperty-outerRadius: 10; + qproperty-lineWidth: 2; +} + opl2instrumentView knob { color: rgb(128,128,128); qproperty-outerColor: rgb(255,255,255); diff --git a/plugins/CMakeLists.txt b/plugins/CMakeLists.txt index 0cbdc4359..6f315b792 100644 --- a/plugins/CMakeLists.txt +++ b/plugins/CMakeLists.txt @@ -15,6 +15,7 @@ ADD_SUBDIRECTORY(papu) ADD_SUBDIRECTORY(patman) ADD_SUBDIRECTORY(peak_controller_effect) ADD_SUBDIRECTORY(sf2_player) +ADD_SUBDIRECTORY(sfxr) ADD_SUBDIRECTORY(sid) ADD_SUBDIRECTORY(spectrum_analyzer) ADD_SUBDIRECTORY(stereo_enhancer) diff --git a/plugins/sfxr/CMakeLists.txt b/plugins/sfxr/CMakeLists.txt index 6d3f61a0c..2fe490d1e 100644 --- a/plugins/sfxr/CMakeLists.txt +++ b/plugins/sfxr/CMakeLists.txt @@ -1,3 +1,3 @@ INCLUDE(BuildPlugin) -BUILD_PLUGIN(sfxr sfxr.cpp sfxr.h MOCFILES EMBEDDED_RESOURCES ${CMAKE_CURRENT_SOURCE_DIR}/*.png) +BUILD_PLUGIN(sfxr sfxr.cpp sfxr.h MOCFILES sfxr.h EMBEDDED_RESOURCES ${CMAKE_CURRENT_SOURCE_DIR}/*.png) diff --git a/plugins/sfxr/artwork.png b/plugins/sfxr/artwork.png index 3938592ca..15f313d45 100644 Binary files a/plugins/sfxr/artwork.png and b/plugins/sfxr/artwork.png differ diff --git a/plugins/sfxr/logo.png b/plugins/sfxr/logo.png index 2e84cba5a..a39e4e865 100644 Binary files a/plugins/sfxr/logo.png and b/plugins/sfxr/logo.png differ diff --git a/plugins/sfxr/sfxr.cpp b/plugins/sfxr/sfxr.cpp index 246e9a907..2e942a6ab 100644 --- a/plugins/sfxr/sfxr.cpp +++ b/plugins/sfxr/sfxr.cpp @@ -1,5 +1,6 @@ /* * sfxr.cpp - port of sfxr to LMMS + * The original readme file of sfxr can be found in readme.txt in this directory. * * Copyright (c) 2014 Wong Cho Ching * @@ -19,9 +20,19 @@ * 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 + +#define rnd(n) (rand()%(n+1)) + +#define PI 3.14159265f + +float frnd(float range) +{ + return (float)rnd(10000)/10000*range; +} + #include @@ -43,7 +54,7 @@ extern "C" { -Plugin::Descriptor PLUGIN_EXPORT bitinvader_plugin_descriptor = +Plugin::Descriptor PLUGIN_EXPORT sfxr_plugin_descriptor = { STRINGIFY( PLUGIN_NAME ), "sfxr", @@ -60,7 +71,7 @@ Plugin::Descriptor PLUGIN_EXPORT bitinvader_plugin_descriptor = } -bSynth::bSynth( float * _shape, int _length, notePlayHandle * _nph, bool _interpolation, +SfxrSynth::SfxrSynth( float * _shape, int _length, notePlayHandle * _nph, bool _interpolation, float _factor, const sample_rate_t _sample_rate ) : sample_index( 0 ), sample_realindex( 0 ), @@ -77,18 +88,18 @@ bSynth::bSynth( float * _shape, int _length, notePlayHandle * _nph, bool _interp } -bSynth::~bSynth() +SfxrSynth::~SfxrSynth() { delete[] sample_shape; } -sample_t bSynth::nextStringSample() +sample_t SfxrSynth::nextStringSample() { - float sample_step = + float sample_step = static_cast( sample_length / ( sample_rate / nph->frequency() ) ); - + // check overflow while (sample_realindex >= sample_length) { sample_realindex -= sample_length; @@ -98,168 +109,195 @@ sample_t bSynth::nextStringSample() if (interpolation) { - // find position in shape - int a = static_cast(sample_realindex); + // find position in shape + int a = static_cast(sample_realindex); int b; if (a < (sample_length-1)) { b = static_cast(sample_realindex+1); } else { b = 0; } - + // Nachkommaanteil float frac = sample_realindex - static_cast(sample_realindex); - + sample = sample_shape[a]*(1-frac) + sample_shape[b]*(frac); } else { // No interpolation - sample_index = static_cast(sample_realindex); + sample_index = static_cast(sample_realindex); sample = sample_shape[sample_index]; } - + // progress in shape sample_realindex += sample_step; return sample; -} - -/*********************************************************************** -* -* class BitInvader -* -* lmms - plugin -* -***********************************************************************/ +} -bitInvader::bitInvader( InstrumentTrack * _instrument_track ) : - Instrument( _instrument_track, &bitinvader_plugin_descriptor ), - m_sampleLength( 128, 8, 128, 1, this, tr( "Samplelength" ) ), - m_graph( -1.0f, 1.0f, 128, this ), - m_interpolation( false, this ), - m_normalize( false, this ) + + +sfxrInstrument::sfxrInstrument( InstrumentTrack * _instrument_track ) : + Instrument( _instrument_track, &sfxr_plugin_descriptor ), + m_attModel(0.0f, this), + m_holdModel(0.3f, this), + m_susModel(0.0f, this), + m_decModel(0.4f, this), + + m_startFreqModel(0.3f, this), + m_minFreqModel(0.0f, this), + m_slideModel(0.0f, this), + m_dSlideModel(0.0f, this), + m_vibDepthModel(0.0f, this), + m_vibSpeedModel(0.0f, this), + + m_changeAmtModel(0.0f, this), + m_changeSpeedModel(0.0f, this), + + m_sqrDutyModel(0.0f, this), + m_sqrSweepModel(0.0f, this), + + m_repeatSpeedModel(0.0f, this), + + m_phaserOffsetModel(0.0f, this), + m_phaserSweepModel(0.0f, this), + + m_lpFilCutModel(1.0f, this), + m_lpFilCutSweepModel(0.0f, this), + m_lpFilResoModel(0.0f, this), + m_hpFilCutModel(0.0f, this), + m_hpFilCutSweepModel(0.0f, this), + m_waveFormModel( SQR_WAVE, 0, WAVES_NUM-1, this, tr( "Wave Form" ) ) { - - m_graph.setWaveToSine(); - + //TODO + /* connect( &m_sampleLength, SIGNAL( dataChanged( ) ), this, SLOT( lengthChanged( ) ) ); connect( &m_graph, SIGNAL( samplesChanged( int, int ) ), this, SLOT( samplesChanged( int, int ) ) ); - + */ } -bitInvader::~bitInvader() +sfxrInstrument::~sfxrInstrument() { } -void bitInvader::saveSettings( QDomDocument & _doc, QDomElement & _this ) +void sfxrInstrument::saveSettings( QDomDocument & _doc, QDomElement & _this ) { + _this.setAttribute( "version", "1" ); + m_attModel.saveSettings( _doc, _this, "att" ); + m_holdModel.saveSettings( _doc, _this, "hold" ); + m_susModel.saveSettings( _doc, _this, "sus" ); + m_decModel.saveSettings( _doc, _this, "dec" ); - // Save plugin version - _this.setAttribute( "version", "0.1" ); + m_startFreqModel.saveSettings( _doc, _this, "startFreq" ); + m_minFreqModel.saveSettings( _doc, _this, "minFreq" ); + m_slideModel.saveSettings( _doc, _this, "slide" ); + m_dSlideModel.saveSettings( _doc, _this, "dSlide" ); + m_vibDepthModel.saveSettings( _doc, _this, "vibDepth" ); + m_vibSpeedModel.saveSettings( _doc, _this, "vibSpeed" ); - // Save sample length - m_sampleLength.saveSettings( _doc, _this, "sampleLength" ); + m_changeAmtModel.saveSettings( _doc, _this, "changeAmt" ); + m_changeSpeedModel.saveSettings( _doc, _this, "changeSpeed" ); - // Save sample shape base64-encoded - QString sampleString; - base64::encode( (const char *)m_graph.samples(), - m_graph.length() * sizeof(float), sampleString ); - _this.setAttribute( "sampleShape", sampleString ); - + m_sqrDutyModel.saveSettings( _doc, _this, "sqrDuty" ); + m_sqrSweepModel.saveSettings( _doc, _this, "sqrSweep" ); - // save LED normalize - m_interpolation.saveSettings( _doc, _this, "interpolation" ); - - // save LED - m_normalize.saveSettings( _doc, _this, "normalize" ); + m_repeatSpeedModel.saveSettings( _doc, _this, "repeatSpeed" ); + + m_phaserOffsetModel.saveSettings( _doc, _this, "phaserOffset" ); + m_phaserSweepModel.saveSettings( _doc, _this, "phaserSweep" ); + + m_lpFilCutModel.saveSettings( _doc, _this, "lpFilCut" ); + m_lpFilCutSweepModel.saveSettings( _doc, _this, "lpFilCutSweep" ); + m_lpFilResoModel.saveSettings( _doc, _this, "lpFilReso" ); + m_hpFilCutModel.saveSettings( _doc, _this, "hpFilCut" ); + m_hpFilCutSweepModel.saveSettings( _doc, _this, "hpFilCutSweep" ); + + m_waveFormModel.saveSettings( _doc, _this, "waveForm" ); } -void bitInvader::loadSettings( const QDomElement & _this ) +void sfxrInstrument::loadSettings( const QDomElement & _this ) { - // Load sample length - m_sampleLength.loadSettings( _this, "sampleLength" ); - int sampleLength = (int)m_sampleLength.value(); + m_attModel.loadSettings(_this, "att" ); + m_holdModel.loadSettings( _this, "hold" ); + m_susModel.loadSettings( _this, "sus" ); + m_decModel.loadSettings( _this, "dec" ); - // Load sample shape - int size = 0; - char * dst = 0; - base64::decode( _this.attribute( "sampleShape"), &dst, &size ); + m_startFreqModel.loadSettings( _this, "startFreq" ); + m_minFreqModel.loadSettings( _this, "minFreq" ); + m_slideModel.loadSettings( _this, "slide" ); + m_dSlideModel.loadSettings( _this, "dSlide" ); + m_vibDepthModel.loadSettings( _this, "vibDepth" ); + m_vibSpeedModel.loadSettings( _this, "vibSpeed" ); - m_graph.setLength( sampleLength ); - m_graph.setSamples( (float*) dst ); - delete[] dst; + m_changeAmtModel.loadSettings( _this, "changeAmt" ); + m_changeSpeedModel.loadSettings( _this, "changeSpeed" ); - // Load LED normalize - m_interpolation.loadSettings( _this, "interpolation" ); - // Load LED - m_normalize.loadSettings( _this, "normalize" ); + m_sqrDutyModel.loadSettings( _this, "sqrDuty" ); + m_sqrSweepModel.loadSettings( _this, "sqrSweep" ); + + m_repeatSpeedModel.loadSettings( _this, "repeatSpeed" ); + + m_phaserOffsetModel.loadSettings( _this, "phaserOffset" ); + m_phaserSweepModel.loadSettings( _this, "phaserSweep" ); + + m_lpFilCutModel.loadSettings( _this, "lpFilCut" ); + m_lpFilCutSweepModel.loadSettings( _this, "lpFilCutSweep" ); + m_lpFilResoModel.loadSettings( _this, "lpFilReso" ); + m_hpFilCutModel.loadSettings( _this, "hpFilCut" ); + m_hpFilCutSweepModel.loadSettings( _this, "hpFilCutSweep" ); + + m_waveFormModel.loadSettings( _this, "waveForm" ); } -void bitInvader::lengthChanged() +void sfxrInstrument::samplesChanged( int _begin, int _end ) { - m_graph.setLength( (int) m_sampleLength.value() ); - - normalize(); -} - - - - -void bitInvader::samplesChanged( int _begin, int _end ) -{ - normalize(); + //TODO + //normalize(); //engine::getSongEditor()->setModified(); } -void bitInvader::normalize() +QString sfxrInstrument::nodeName() const { - // analyze - float max = 0; - const float* samples = m_graph.samples(); - for(int i=0; i < m_graph.length(); i++) - { - const float f = fabsf( samples[i] ); - if (f > max) { max = f; } - } - m_normalizeFactor = 1.0 / max; + return( sfxr_plugin_descriptor.name ); } -QString bitInvader::nodeName() const +f_cnt_t sfxrInstrument::desiredReleaseFrames() const { - return( bitinvader_plugin_descriptor.name ); + //TODO: check whether this disables + return 0; } - -void bitInvader::playNote( notePlayHandle * _n, +void sfxrInstrument::playNote( notePlayHandle * _n, sampleFrame * _working_buffer ) { - if ( _n->totalFramesPlayed() == 0 || _n->m_pluginData == NULL ) + //TODO + /*if ( _n->totalFramesPlayed() == 0 || _n->m_pluginData == NULL ) { float factor; @@ -272,7 +310,7 @@ void bitInvader::playNote( notePlayHandle * _n, factor = m_normalizeFactor; } - _n->m_pluginData = new bSynth( + _n->m_pluginData = new SfxrSynth( const_cast( m_graph.samples() ), m_graph.length(), _n, @@ -282,7 +320,7 @@ void bitInvader::playNote( notePlayHandle * _n, const fpp_t frames = _n->framesLeftForCurrentPeriod(); - bSynth * ps = static_cast( _n->m_pluginData ); + SfxrSynth * ps = static_cast( _n->m_pluginData ); for( fpp_t frame = 0; frame < frames; ++frame ) { const sample_t cur = ps->nextStringSample(); @@ -294,281 +332,588 @@ void bitInvader::playNote( notePlayHandle * _n, applyRelease( _working_buffer, _n ); - instrumentTrack()->processAudioBuffer( _working_buffer, frames, _n ); + instrumentTrack()->processAudioBuffer( _working_buffer, frames, _n );*/ } -void bitInvader::deleteNotePluginData( notePlayHandle * _n ) +void sfxrInstrument::deleteNotePluginData( notePlayHandle * _n ) { - delete static_cast( _n->m_pluginData ); + delete static_cast( _n->m_pluginData ); } -PluginView * bitInvader::instantiateView( QWidget * _parent ) +PluginView * sfxrInstrument::instantiateView( QWidget * _parent ) { - return( new bitInvaderView( this, _parent ) ); + return( new sfxrInstrumentView( this, _parent ) ); } +void sfxrInstrument::resetModels() +{ + m_attModel.reset(); + m_holdModel.reset(); + m_susModel.reset(); + m_decModel.reset(); + + m_startFreqModel.reset(); + m_minFreqModel.reset(); + m_slideModel.reset(); + m_dSlideModel.reset(); + m_vibDepthModel.reset(); + m_vibSpeedModel.reset(); + + m_changeAmtModel.reset(); + m_changeSpeedModel.reset(); + + m_sqrDutyModel.reset(); + m_sqrSweepModel.reset(); + + m_repeatSpeedModel.reset(); + + m_phaserOffsetModel.reset(); + m_phaserSweepModel.reset(); + + m_lpFilCutModel.reset(); + m_lpFilCutSweepModel.reset(); + m_lpFilResoModel.reset(); + m_hpFilCutModel.reset(); + m_hpFilCutSweepModel.reset(); + + m_waveFormModel.reset(); +} -bitInvaderView::bitInvaderView( Instrument * _instrument, + +class sfxrKnob : public knob +{ +public: + sfxrKnob( QWidget * _parent ) : + knob( knobStyled, _parent ) + { + setFixedSize( 20, 20 ); + setCenterPointX( 10.0 ); + setCenterPointY( 10.0 ); + setTotalAngle( 270.0 ); + setLineWidth( 1 ); + } +}; + + + + +#define createKnob(_knob, _x, _y, _name)\ + _knob = new sfxrKnob( this ); \ + _knob->setHintText( tr( _name ":" ), "" ); \ + _knob->move( _x, _y ); \ + toolTip::add( _knob, tr( _name ) ); + + + + +#define createButton(_button, _x, _y, _name, _resName)\ + _button = new pixmapButton( this, tr( "Sine wave" ) );\ + _button->move( _x, _y );\ + _button->setActiveGraphic( embed::getIconPixmap( _resName "_active" ) );\ + _button->setInactiveGraphic( embed::getIconPixmap( _resName "_inactive" ) );\ + toolTip::add( _button, tr( _name ) ); + + + + +#define createButtonLocalGraphic(_button, _x, _y, _name, _resName)\ + _button = new pixmapButton( this, tr( "Sine wave" ) );\ + _button->move( _x, _y );\ + _button->setActiveGraphic( PLUGIN_NAME::getIconPixmap( _resName "_active" ) );\ + _button->setInactiveGraphic( PLUGIN_NAME::getIconPixmap( _resName "_inactive" ) );\ + toolTip::add( _button, tr( _name ) ); + + + + +sfxrInstrumentView::sfxrInstrumentView( Instrument * _instrument, QWidget * _parent ) : InstrumentView( _instrument, _parent ) { + srand(time(NULL)); setAutoFillBackground( true ); QPalette pal; - - pal.setBrush( backgroundRole(), PLUGIN_NAME::getIconPixmap( - "artwork" ) ); + pal.setBrush( backgroundRole(), PLUGIN_NAME::getIconPixmap( "artwork" ) ); setPalette( pal ); - - m_sampleLengthKnob = new knob( knobDark_28, this ); - m_sampleLengthKnob->move( 10, 120 ); - m_sampleLengthKnob->setHintText( tr( "Sample Length" ) + " ", "" ); - m_graph = new graph( this, graph::NearestStyle ); - m_graph->move(53,118); // 55,120 - 2px border - m_graph->setAutoFillBackground( true ); + createKnob(m_attKnob, KNOBS_BASE_X+KNOB_BLOCK_SIZE_X*0, KNOBS_BASE_Y+KNOB_BLOCK_SIZE_Y*0, "Attack Time"); + createKnob(m_holdKnob, KNOBS_BASE_X+KNOB_BLOCK_SIZE_X*1, KNOBS_BASE_Y+KNOB_BLOCK_SIZE_Y*0, "Sustain Time"); + createKnob(m_susKnob, KNOBS_BASE_X+KNOB_BLOCK_SIZE_X*2, KNOBS_BASE_Y+KNOB_BLOCK_SIZE_Y*0, "Sustain Punch"); + createKnob(m_decKnob, KNOBS_BASE_X+KNOB_BLOCK_SIZE_X*3, KNOBS_BASE_Y+KNOB_BLOCK_SIZE_Y*0, "Decay Time"); - toolTip::add( m_graph, tr ( "Draw your own waveform here " - "by dragging your mouse on this graph." - )); + createKnob(m_startFreqKnob, KNOBS_BASE_X+KNOB_BLOCK_SIZE_X*0, KNOBS_BASE_Y+KNOB_BLOCK_SIZE_Y*1, "Start Frequency"); + createKnob(m_minFreqKnob, KNOBS_BASE_X+KNOB_BLOCK_SIZE_X*1, KNOBS_BASE_Y+KNOB_BLOCK_SIZE_Y*1, "Min Frequency"); + createKnob(m_slideKnob, KNOBS_BASE_X+KNOB_BLOCK_SIZE_X*2, KNOBS_BASE_Y+KNOB_BLOCK_SIZE_Y*1, "Slide"); + createKnob(m_dSlideKnob, KNOBS_BASE_X+KNOB_BLOCK_SIZE_X*3, KNOBS_BASE_Y+KNOB_BLOCK_SIZE_Y*1, "Delta Slide"); + createKnob(m_vibDepthKnob, KNOBS_BASE_X+KNOB_BLOCK_SIZE_X*4, KNOBS_BASE_Y+KNOB_BLOCK_SIZE_Y*1, "Vibrato Depth"); + createKnob(m_vibSpeedKnob, KNOBS_BASE_X+KNOB_BLOCK_SIZE_X*5, KNOBS_BASE_Y+KNOB_BLOCK_SIZE_Y*1, "Vibrato Speed"); + + createKnob(m_changeAmtKnob, KNOBS_BASE_X+KNOB_BLOCK_SIZE_X*0, KNOBS_BASE_Y+KNOB_BLOCK_SIZE_Y*2, "Change Amount"); + createKnob(m_changeSpeedKnob, KNOBS_BASE_X+KNOB_BLOCK_SIZE_X*1, KNOBS_BASE_Y+KNOB_BLOCK_SIZE_Y*2, "Change Speed"); + + createKnob(m_sqrDutyKnob, KNOBS_BASE_X+KNOB_BLOCK_SIZE_X*3, KNOBS_BASE_Y+KNOB_BLOCK_SIZE_Y*2, "Squre Duty(Square wave only)"); + createKnob(m_sqrSpeedKnob, KNOBS_BASE_X+KNOB_BLOCK_SIZE_X*4, KNOBS_BASE_Y+KNOB_BLOCK_SIZE_Y*2, "Squre Sweep(Square wave only)"); + + createKnob(m_repeatSpeedKnob, KNOBS_BASE_X+KNOB_BLOCK_SIZE_X*0, KNOBS_BASE_Y+KNOB_BLOCK_SIZE_Y*3, "Repeat Speed"); + + createKnob(m_phaserOffsetKnob, KNOBS_BASE_X+KNOB_BLOCK_SIZE_X*2, KNOBS_BASE_Y+KNOB_BLOCK_SIZE_Y*3, "Phaser Offset"); + createKnob(m_phaserSweepKnob, KNOBS_BASE_X+KNOB_BLOCK_SIZE_X*3, KNOBS_BASE_Y+KNOB_BLOCK_SIZE_Y*3, "Phaser Sweep"); + + createKnob(m_lpFilCutKnob, KNOBS_BASE_X+KNOB_BLOCK_SIZE_X*0, KNOBS_BASE_Y+KNOB_BLOCK_SIZE_Y*4, "LP Filter Cutoff"); + createKnob(m_lpFilCutSweepKnob, KNOBS_BASE_X+KNOB_BLOCK_SIZE_X*1, KNOBS_BASE_Y+KNOB_BLOCK_SIZE_Y*4, "LP Filter Cutoff Sweep"); + createKnob(m_lpFilResoKnob, KNOBS_BASE_X+KNOB_BLOCK_SIZE_X*2, KNOBS_BASE_Y+KNOB_BLOCK_SIZE_Y*4, "LP Filter Resonance"); + createKnob(m_hpFilCutKnob, KNOBS_BASE_X+KNOB_BLOCK_SIZE_X*3, KNOBS_BASE_Y+KNOB_BLOCK_SIZE_Y*4, "HP Filter Cutoff"); + createKnob(m_hpFilCutSweepKnob, KNOBS_BASE_X+KNOB_BLOCK_SIZE_X*4, KNOBS_BASE_Y+KNOB_BLOCK_SIZE_Y*4, "HP Filter Cutoff Sweep"); + + createButton(m_sqrWaveBtn, KNOBS_BASE_X+WAVEFORM_BUTTON_WIDTH*0, WAVEFORM_BASE_Y, "Square Wave", "square_wave"); + createButton(m_sawWaveBtn, KNOBS_BASE_X+WAVEFORM_BUTTON_WIDTH*1, WAVEFORM_BASE_Y, "Saw Wave", "saw_wave"); + createButton(m_sinWaveBtn, KNOBS_BASE_X+WAVEFORM_BUTTON_WIDTH*2, WAVEFORM_BASE_Y, "Sine Wave", "sin_wave"); + createButton(m_noiseWaveBtn, KNOBS_BASE_X+WAVEFORM_BUTTON_WIDTH*3, WAVEFORM_BASE_Y, "Noise", "white_noise_wave"); + + m_waveBtnGroup = new automatableButtonGroup( this ); + m_waveBtnGroup->addButton(m_sqrWaveBtn); + m_waveBtnGroup->addButton(m_sawWaveBtn); + m_waveBtnGroup->addButton(m_sinWaveBtn); + m_waveBtnGroup->addButton(m_noiseWaveBtn); + connect( m_waveBtnGroup, SIGNAL ( dataChanged() ), + this, SLOT ( waveFormChanged() ) ); - pal = QPalette(); - pal.setBrush( backgroundRole(), - PLUGIN_NAME::getIconPixmap("wavegraph") ); - m_graph->setPalette( pal ); + createButtonLocalGraphic(m_pickupBtn, GENERATOR_BASE_X+GENERATOR_BUTTON_WIDTH*0, GENERATOR_BASE_Y, "Generate pick up/coin sfx", "pickup"); + createButtonLocalGraphic(m_laserBtn, GENERATOR_BASE_X+GENERATOR_BUTTON_WIDTH*1, GENERATOR_BASE_Y, "Generate laser/shoot sfx", "laser"); + createButtonLocalGraphic(m_explosionBtn, GENERATOR_BASE_X+GENERATOR_BUTTON_WIDTH*2, GENERATOR_BASE_Y, "Generate explosion sfx", "explosion"); + createButtonLocalGraphic(m_powerupBtn, GENERATOR_BASE_X+GENERATOR_BUTTON_WIDTH*3, GENERATOR_BASE_Y, "Generate power up sfx", "powerup"); + createButtonLocalGraphic(m_hitBtn, GENERATOR_BASE_X+GENERATOR_BUTTON_WIDTH*4, GENERATOR_BASE_Y, "Generate hit/hurt sfx", "hit"); + createButtonLocalGraphic(m_jumpBtn, GENERATOR_BASE_X+GENERATOR_BUTTON_WIDTH*5, GENERATOR_BASE_Y, "Generate jump sfx", "jump"); + createButtonLocalGraphic(m_blipBtn, GENERATOR_BASE_X+GENERATOR_BUTTON_WIDTH*6, GENERATOR_BASE_Y, "Generate blip/select sfx", "blip"); + connect( m_pickupBtn, SIGNAL ( clicked() ), this, SLOT ( genPickup() ) ); + connect( m_laserBtn, SIGNAL ( clicked() ), this, SLOT ( genLaser() ) ); + connect( m_explosionBtn, SIGNAL ( clicked() ), this, SLOT ( genExplosion() ) ); + connect( m_powerupBtn, SIGNAL ( clicked() ), this, SLOT ( genPowerup() ) ); + connect( m_hitBtn, SIGNAL ( clicked() ), this, SLOT ( genHit() ) ); + connect( m_jumpBtn, SIGNAL ( clicked() ), this, SLOT ( genJump() ) ); + connect( m_blipBtn, SIGNAL ( clicked() ), this, SLOT ( genBlip() ) ); - m_sinWaveBtn = new pixmapButton( this, tr( "Sine wave" ) ); - m_sinWaveBtn->move( 188, 120 ); - m_sinWaveBtn->setActiveGraphic( embed::getIconPixmap( - "sin_wave_active" ) ); - m_sinWaveBtn->setInactiveGraphic( embed::getIconPixmap( - "sin_wave_inactive" ) ); - toolTip::add( m_sinWaveBtn, - tr( "Click for a sine-wave." ) ); + createButtonLocalGraphic(m_randomizeBtn, RAND_BUTTON_X, RAND_BUTTON_Y, "Generate random sfx", "randomize"); + createButtonLocalGraphic(m_mutateBtn, MUTA_BUTTON_X, MUTA_BUTTON_Y, "Mutate sfx", "mutate"); + connect( m_randomizeBtn, SIGNAL ( clicked() ), this, SLOT ( randomize() ) ); + connect( m_mutateBtn, SIGNAL ( clicked() ), this, SLOT ( mutate() ) ); - m_triangleWaveBtn = new pixmapButton( this, tr( "Triangle wave" ) ); - m_triangleWaveBtn->move( 188, 136 ); - m_triangleWaveBtn->setActiveGraphic( - embed::getIconPixmap( "triangle_wave_active" ) ); - m_triangleWaveBtn->setInactiveGraphic( - embed::getIconPixmap( "triangle_wave_inactive" ) ); - toolTip::add( m_triangleWaveBtn, - tr( "Click here for a triangle-wave." ) ); + //TODO: for each generator button: + /*connect( m_pickupBtn, SIGNAL ( dataChanged() ), + this, SLOT ( pickupClicked() ) );*/ - m_sawWaveBtn = new pixmapButton( this, tr( "Saw wave" ) ); - m_sawWaveBtn->move( 188, 152 ); - m_sawWaveBtn->setActiveGraphic( embed::getIconPixmap( - "saw_wave_active" ) ); - m_sawWaveBtn->setInactiveGraphic( embed::getIconPixmap( - "saw_wave_inactive" ) ); - toolTip::add( m_sawWaveBtn, - tr( "Click here for a saw-wave." ) ); - - m_sqrWaveBtn = new pixmapButton( this, tr( "Square wave" ) ); - m_sqrWaveBtn->move( 188, 168 ); - m_sqrWaveBtn->setActiveGraphic( embed::getIconPixmap( - "square_wave_active" ) ); - m_sqrWaveBtn->setInactiveGraphic( embed::getIconPixmap( - "square_wave_inactive" ) ); - toolTip::add( m_sqrWaveBtn, - tr( "Click here for a square-wave." ) ); - - m_whiteNoiseWaveBtn = new pixmapButton( this, - tr( "White noise wave" ) ); - m_whiteNoiseWaveBtn->move( 188, 184 ); - m_whiteNoiseWaveBtn->setActiveGraphic( - embed::getIconPixmap( "white_noise_wave_active" ) ); - m_whiteNoiseWaveBtn->setInactiveGraphic( - embed::getIconPixmap( "white_noise_wave_inactive" ) ); - toolTip::add( m_whiteNoiseWaveBtn, - tr( "Click here for white-noise." ) ); - - m_usrWaveBtn = new pixmapButton( this, tr( "User defined wave" ) ); - m_usrWaveBtn->move( 188, 200 ); - m_usrWaveBtn->setActiveGraphic( embed::getIconPixmap( - "usr_wave_active" ) ); - m_usrWaveBtn->setInactiveGraphic( embed::getIconPixmap( - "usr_wave_inactive" ) ); - toolTip::add( m_usrWaveBtn, - tr( "Click here for a user-defined shape." ) ); - - m_smoothBtn = new pixmapButton( this, tr( "Smooth" ) ); - m_smoothBtn->move( 35, 200 ); - m_smoothBtn->setActiveGraphic( PLUGIN_NAME::getIconPixmap( - "smooth" ) ); - m_smoothBtn->setInactiveGraphic( PLUGIN_NAME::getIconPixmap( - "smooth" ) ); - m_smoothBtn->setChecked( true ); - toolTip::add( m_smoothBtn, - tr( "Click here to smooth waveform." ) ); - - - m_interpolationToggle = new ledCheckBox( "Interpolation", this, - tr( "Interpolation" ) ); - m_interpolationToggle->move( 55,80 ); - - - m_normalizeToggle = new ledCheckBox( "Normalize", this, - tr( "Normalize" ) ); - m_normalizeToggle->move( 55, 100 ); - - - connect( m_sinWaveBtn, SIGNAL (clicked () ), - this, SLOT ( sinWaveClicked() ) ); - connect( m_triangleWaveBtn, SIGNAL ( clicked () ), - this, SLOT ( triangleWaveClicked() ) ); - connect( m_sawWaveBtn, SIGNAL (clicked () ), - this, SLOT ( sawWaveClicked() ) ); - connect( m_sqrWaveBtn, SIGNAL ( clicked () ), - this, SLOT ( sqrWaveClicked() ) ); - connect( m_whiteNoiseWaveBtn, SIGNAL ( clicked () ), - this, SLOT ( noiseWaveClicked() ) ); - connect( m_usrWaveBtn, SIGNAL ( clicked () ), - this, SLOT ( usrWaveClicked() ) ); - - connect( m_smoothBtn, SIGNAL ( clicked () ), - this, SLOT ( smoothClicked() ) ); - - connect( m_interpolationToggle, SIGNAL( toggled( bool ) ), - this, SLOT ( interpolationToggled( bool ) ) ); - - connect( m_normalizeToggle, SIGNAL( toggled( bool ) ), - this, SLOT ( normalizeToggled( bool ) ) ); } -void bitInvaderView::modelChanged() +void sfxrInstrumentView::modelChanged() { - bitInvader * b = castModel(); + sfxrInstrument * s = castModel(); - m_graph->setModel( &b->m_graph ); - m_sampleLengthKnob->setModel( &b->m_sampleLength ); - m_interpolationToggle->setModel( &b->m_interpolation ); - m_normalizeToggle->setModel( &b->m_normalize ); + m_attKnob->setModel( &s->m_attModel ); + m_holdKnob->setModel( &s->m_holdModel ); + m_susKnob->setModel( &s->m_susModel ); + m_decKnob->setModel( &s->m_decModel ); + m_startFreqKnob->setModel( &s->m_startFreqModel ); + m_minFreqKnob->setModel( &s->m_minFreqModel ); + m_slideKnob->setModel( &s->m_slideModel ); + m_dSlideKnob->setModel( &s->m_dSlideModel ); + m_vibDepthKnob->setModel( &s->m_vibDepthModel ); + m_vibSpeedKnob->setModel( &s->m_vibSpeedModel ); + + m_changeAmtKnob->setModel( &s->m_changeAmtModel ); + m_changeSpeedKnob->setModel( &s->m_changeSpeedModel ); + + m_sqrDutyKnob->setModel( &s->m_sqrDutyModel ); + m_sqrSpeedKnob->setModel( &s->m_sqrSweepModel ); + + m_repeatSpeedKnob->setModel( &s->m_repeatSpeedModel ); + + m_phaserOffsetKnob->setModel( &s->m_phaserOffsetModel ); + m_phaserSweepKnob->setModel( &s->m_phaserSweepModel ); + + m_lpFilCutKnob->setModel( &s->m_lpFilCutModel ); + m_lpFilCutSweepKnob->setModel( &s->m_lpFilCutSweepModel ); + m_lpFilResoKnob->setModel( &s->m_lpFilResoModel ); + m_hpFilCutKnob->setModel( &s->m_hpFilCutModel ); + m_hpFilCutSweepKnob->setModel( &s->m_hpFilCutSweepModel ); + + m_waveBtnGroup->setModel( &s->m_waveFormModel ); } -void bitInvaderView::sinWaveClicked() +void sfxrInstrumentView::waveFormChanged() { - m_graph->model()->setWaveToSine(); - engine::getSong()->setModified(); -} - - - - -void bitInvaderView::triangleWaveClicked() -{ - m_graph->model()->setWaveToTriangle(); - engine::getSong()->setModified(); -} - - - - -void bitInvaderView::sawWaveClicked() -{ - m_graph->model()->setWaveToSaw(); - engine::getSong()->setModified(); -} - - - - -void bitInvaderView::sqrWaveClicked() -{ - m_graph->model()->setWaveToSquare(); - engine::getSong()->setModified(); -} - - - - -void bitInvaderView::noiseWaveClicked() -{ - m_graph->model()->setWaveToNoise(); - engine::getSong()->setModified(); -} - - - - -void bitInvaderView::usrWaveClicked() -{ - QString fileName = m_graph->model()->setWaveToUser(); - toolTip::add( m_usrWaveBtn, fileName ); - engine::getSong()->setModified(); + //TODO: do we even need this slot? /* m_graph->model()->setWaveToNoise(); engine::getSong()->setModified(); - // zero sample_shape - for (int i = 0; i < sample_length; i++) - { - sample_shape[i] = 0; - } - - // load user shape - sampleBuffer buffer; - QString af = buffer.openAudioFile(); - if ( af != "" ) - { - buffer.setAudioFile( af ); - - // copy buffer data - sample_length = min( sample_length, static_cast( - buffer.frames() ) ); - for ( int i = 0; i < sample_length; i++ ) - { - sample_shape[i] = (float)*buffer.data()[i]; - } - } - - sampleChanged(); */ } -void bitInvaderView::smoothClicked() +void sfxrInstrumentView::genPickup() { - m_graph->model()->smooth(); - engine::getSong()->setModified(); + sfxrInstrument * s = castModel(); + s->resetModels(); + s->m_startFreqModel.setValue( 0.4f+frnd(0.5f) ); + s->m_attModel.setValue( 0.0f ); + s->m_holdModel.setValue( frnd(0.1f) ); + s->m_decModel.setValue( 0.1f+frnd(0.4f) ); + s->m_susModel.setValue( 0.3f+frnd(0.3f) ); + + if(rnd(1)) + { + s->m_changeAmtModel.setValue( 0.5f+frnd(0.2f) ); + s->m_changeSpeedModel.setValue( 0.2f+frnd(0.4f) ); + } } -void bitInvaderView::interpolationToggled( bool value ) +void sfxrInstrumentView::genLaser() { - m_graph->setGraphStyle( value ? graph::LinearStyle : graph::NearestStyle); - engine::getSong()->setModified(); + sfxrInstrument * s = castModel(); + s->resetModels(); + + s->m_waveFormModel.setValue( rnd(2) ); + if(s->m_waveFormModel.value()==2 && rnd(1)) + s->m_waveFormModel.setValue(rnd(1)); + + s->m_startFreqModel.setValue( 0.5f+frnd(0.5f) ); + s->m_minFreqModel.setValue( s->m_startFreqModel.value()-0.2f-frnd(0.6f) ); + + if(s->m_minFreqModel.value()<0.2f) + { + s->m_minFreqModel.setValue(0.2f); + } + + s->m_slideModel.setValue( -0.15f-frnd(0.2f) ); + + if(rnd(2)==0) + { + s->m_startFreqModel.setValue( 0.3f+frnd(0.6f) ); + s->m_minFreqModel.setValue( frnd(0.1f) ); + s->m_slideModel.setValue( -0.35f-frnd(0.3f) ); + } + + if(rnd(1)) + { + s->m_sqrDutyModel.setValue( frnd(0.5f) ); + s->m_sqrSweepModel.setValue( 0.2f ); + } + else + { + s->m_sqrDutyModel.setValue( 0.4f+frnd(0.5f) ); + s->m_sqrSweepModel.setValue( -frnd(0.7f) ); + } + + s->m_attModel.setValue( 0.0f ); + s->m_holdModel.setValue( 0.1f+frnd(0.2f) ); + s->m_decModel.setValue( frnd(0.4f) ); + + if(rnd(1)) + { + s->m_susModel.setValue( frnd(0.3f) ); + } + + if(rnd(2)==0) + { + s->m_phaserOffsetModel.setValue( frnd(0.2f) ); + s->m_phaserSweepModel.setValue( -frnd(0.2f) ); + } + + if(rnd(1)) + s->m_hpFilCutModel.setValue( frnd(0.3f) ); } -void bitInvaderView::normalizeToggled( bool value ) +void sfxrInstrumentView::genExplosion() { - engine::getSong()->setModified(); + sfxrInstrument * s = castModel(); + s->resetModels(); + + s->m_waveFormModel.setValue( 3 ); + + if(rnd(1)) + { + s->m_startFreqModel.setValue( 0.1f+frnd(0.4f) ); + s->m_slideModel.setValue( -0.1f+frnd(0.4f) ); + } + else + { + s->m_startFreqModel.setValue( 0.2f+frnd(0.7f) ); + s->m_slideModel.setValue( -0.2f-frnd(0.2f) ); + } + s->m_startFreqModel.setValue( s->m_startFreqModel.value()*s->m_startFreqModel.value() ); + + if(rnd(4)==0) + { + s->m_slideModel.setValue( 0.0f ); + } + + if(rnd(2)==0) + { + s->m_repeatSpeedModel.setValue( 0.3f+frnd(0.5f) ); + } + + s->m_attModel.setValue( 0.0f ); + s->m_holdModel.setValue( 0.1f+frnd(0.3f) ); + s->m_decModel.setValue( 0.5f ); + if(rnd(1)==0) + { + s->m_phaserOffsetModel.setValue( -0.3f+frnd(0.9f) ); + s->m_phaserSweepModel.setValue( -frnd(0.3f) ); + } + s->m_susModel.setValue( 0.2f+frnd(0.6f) ); + + if(rnd(1)) + { + s->m_vibDepthModel.setValue( frnd(0.7f) ); + s->m_vibSpeedModel.setValue( frnd(0.6f) ); + } + if(rnd(2)==0) + { + s->m_changeSpeedModel.setValue( 0.6f+frnd(0.3f) ); + s->m_changeAmtModel.setValue( 0.8f-frnd(1.6f) ); + } + +} + + + + +void sfxrInstrumentView::genPowerup() +{ + sfxrInstrument * s = castModel(); + s->resetModels(); + + if(rnd(1)) + s->m_waveFormModel.setValue( 1 ); + else + s->m_sqrDutyModel.setValue( frnd(0.6f) ); + if(rnd(1)) + { + s->m_startFreqModel.setValue( 0.2f+frnd(0.3f) ); + s->m_slideModel.setValue( 0.1f+frnd(0.4f) ); + s->m_repeatSpeedModel.setValue( 0.4f+frnd(0.4f) ); + } + else + { + s->m_startFreqModel.setValue( 0.2f+frnd(0.3f) ); + s->m_slideModel.setValue( 0.05f+frnd(0.2f) ); + if(rnd(1)) + { + s->m_vibDepthModel.setValue( frnd(0.7f) ); + s->m_vibSpeedModel.setValue( frnd(0.6f) ); + } + } + + s->m_attModel.setValue( 0.0f ); + s->m_holdModel.setValue( frnd(0.4f) ); + s->m_decModel.setValue( 0.1f+frnd(0.4f) ); +} + + + + +void sfxrInstrumentView::genHit() +{ + sfxrInstrument * s = castModel(); + s->resetModels(); + + s->m_waveFormModel.setValue( rnd(2) ); + if(s->m_waveFormModel.value()==2) + s->m_waveFormModel.setValue( 3 ); + if(s->m_waveFormModel.value()==0) + s->m_sqrDutyModel.setValue( frnd(0.6f) ); + + s->m_startFreqModel.setValue( 0.2f+frnd(0.6f) ); + s->m_slideModel.setValue( -0.3f-frnd(0.4f) ); + + s->m_attModel.setValue( 0.0f ); + s->m_holdModel.setValue( frnd(0.1f) ); + s->m_decModel.setValue( 0.1f+frnd(0.2f) ); + if(rnd(1)) + { + s->m_hpFilCutModel.setValue( frnd(0.3f) ); + } +} + + + + +void sfxrInstrumentView::genJump() +{ + sfxrInstrument * s = castModel(); + s->resetModels(); + + s->m_waveFormModel.setValue( 0 ); + s->m_sqrDutyModel.setValue( frnd(0.6f) ); + + s->m_startFreqModel.setValue( 0.3f+frnd(0.3f) ); + s->m_slideModel.setValue( 0.1f+frnd(0.2f) ); + + s->m_attModel.setValue( 0.0f ); + s->m_holdModel.setValue( 0.1f+frnd(0.3f) ); + s->m_decModel.setValue( 0.1f+frnd(0.2f) ); + + if(rnd(1)) + { + s->m_hpFilCutModel.setValue( frnd(0.3f) ); + } + + if(rnd(1)) + { + + s->m_lpFilCutModel.setValue( 1.0f-frnd(0.6f) ); + } +} + + + + +void sfxrInstrumentView::genBlip() +{ + sfxrInstrument * s = castModel(); + s->resetModels(); + + s->m_waveFormModel.setValue( rnd(1) ); + if( s->m_waveFormModel.value()==0 ) + { + s->m_sqrDutyModel.setValue( frnd(0.6f) ); + } + + s->m_startFreqModel.setValue( 0.2f+frnd(0.4f) ); + + s->m_attModel.setValue( 0.0f ); + s->m_holdModel.setValue( 0.1f+frnd(0.1f) ); + s->m_decModel.setValue( frnd(0.2f) ); + s->m_hpFilCutModel.setValue( 0.1f ); +} + + + + +void sfxrInstrumentView::randomize() +{ + sfxrInstrument * s = castModel(); + + s->m_startFreqModel.setValue( pow(frnd(2.0f)-1.0f, 2.0f) ); + if(rnd(1)) + { + s->m_startFreqModel.setValue( pow(frnd(2.0f)-1.0f, 3.0f)+0.5f ); + } + s->m_minFreqModel.setValue( 0.0f ); + s->m_slideModel.setValue( pow(frnd(2.0f)-1.0f, 5.0f) ); + if( s->m_startFreqModel.value()>0.7f && s->m_slideModel.value()>0.2f ) + { + s->m_slideModel.setValue( -s->m_slideModel.value() ); + } + if( s->m_startFreqModel.value()<0.2f && s->m_slideModel.value()<-0.05f ) + { + s->m_slideModel.setValue( -s->m_slideModel.value() ); + } + s->m_dSlideModel.setValue( pow(frnd(2.0f)-1.0f, 3.0f) ); + + s->m_sqrDutyModel.setValue( frnd(2.0f)-1.0f ); + s->m_sqrSweepModel.setValue( pow(frnd(2.0f)-1.0f, 3.0f) ); + + s->m_vibDepthModel.setValue( pow(frnd(2.0f)-1.0f, 3.0f) ); + s->m_vibSpeedModel.setValue( frnd(2.0f)-1.0f ); + //s->m_vibDelayModel.setValue( frnd(2.0f)-1.0f ); + + s->m_attModel.setValue( pow(frnd(2.0f)-1.0f, 3.0f) ); + s->m_holdModel.setValue( pow(frnd(2.0f)-1.0f, 2.0f) ); + s->m_decModel.setValue( frnd(2.0f)-1.0f ); + s->m_susModel.setValue( pow(frnd(0.8f), 2.0f) ); + if(s->m_attModel.value()+s->m_holdModel.value()+s->m_decModel.value()<0.2f) + { + s->m_holdModel.setValue( s->m_holdModel.value()+0.2f+frnd(0.3f) ); + s->m_decModel.setValue( s->m_decModel.value()+0.2f+frnd(0.3f) ); + } + + s->m_lpFilResoModel.setValue( frnd(2.0f)-1.0f ); + s->m_lpFilCutModel.setValue( 1.0f-pow(frnd(1.0f), 3.0f) ); + s->m_lpFilCutSweepModel.setValue( pow(frnd(2.0f)-1.0f, 3.0f) ); + if(s->m_lpFilCutModel.value()<0.1f && s->m_lpFilCutSweepModel.value()<-0.05f) + { + s->m_lpFilCutSweepModel.setValue( -s->m_lpFilCutSweepModel.value() ); + } + s->m_hpFilCutModel.setValue( pow(frnd(1.0f), 5.0f) ); + s->m_hpFilCutSweepModel.setValue( pow(frnd(2.0f)-1.0f, 5.0f) ); + + s->m_phaserOffsetModel.setValue( pow(frnd(2.0f)-1.0f, 3.0f) ); + s->m_phaserSweepModel.setValue( pow(frnd(2.0f)-1.0f, 3.0f) ); + + s->m_repeatSpeedModel.setValue( frnd(2.0f)-1.0f ); + + s->m_changeSpeedModel.setValue( frnd(2.0f)-1.0f ); + s->m_changeAmtModel.setValue( frnd(2.0f)-1.0f ); + +} + + + + +void sfxrInstrumentView::mutate() +{ + sfxrInstrument * s = castModel(); + + if(rnd(1)) s->m_startFreqModel.setValue( s->m_startFreqModel.value()+frnd(0.1f)-0.05f ); + // if(rnd(1)) s->m_minFreqModel.setValue( s->m_minFreqModel.value()+frnd(0.1f)-0.05f ); + if(rnd(1)) s->m_slideModel.setValue( s->m_slideModel.value()+frnd(0.1f)-0.05f ); + if(rnd(1)) s->m_dSlideModel.setValue( s->m_dSlideModel.value()+frnd(0.1f)-0.05f ); + + if(rnd(1)) s->m_sqrDutyModel.setValue( s->m_sqrDutyModel.value()+frnd(0.1f)-0.05f ); + if(rnd(1)) s->m_sqrSweepModel.setValue( s->m_sqrSweepModel.value()+frnd(0.1f)-0.05f ); + + if(rnd(1)) s->m_vibDepthModel.setValue( s->m_vibDepthModel.value()+frnd(0.1f)-0.05f ); + if(rnd(1)) s->m_vibSpeedModel.setValue( s->m_vibSpeedModel.value()+frnd(0.1f)-0.05f ); + // if(rnd(1)) s->m_vibDelayModel.setValue( s->m_vibDelayModel.value()+frnd(0.1f)-0.05f ); + + if(rnd(1)) s->m_attModel.setValue( s->m_attModel.value()+frnd(0.1f)-0.05f ); + if(rnd(1)) s->m_holdModel.setValue( s->m_holdModel.value()+frnd(0.1f)-0.05f ); + if(rnd(1)) s->m_decModel.setValue( s->m_decModel.value()+frnd(0.1f)-0.05f ); + if(rnd(1)) s->m_susModel.setValue( s->m_susModel.value()+frnd(0.1f)-0.05f ); + + if(rnd(1)) s->m_lpFilResoModel.setValue( s->m_lpFilResoModel.value()+frnd(0.1f)-0.05f ); + if(rnd(1)) s->m_lpFilCutModel.setValue( s->m_lpFilCutModel.value()+frnd(0.1f)-0.05f ); + if(rnd(1)) s->m_lpFilCutSweepModel.setValue( s->m_lpFilCutSweepModel.value()+frnd(0.1f)-0.05f ); + if(rnd(1)) s->m_hpFilCutModel.setValue( s->m_hpFilCutModel.value()+frnd(0.1f)-0.05f ); + if(rnd(1)) s->m_hpFilCutSweepModel.setValue( s->m_hpFilCutSweepModel.value()+frnd(0.1f)-0.05f ); + + if(rnd(1)) s->m_phaserOffsetModel.setValue( s->m_phaserOffsetModel.value()+frnd(0.1f)-0.05f ); + if(rnd(1)) s->m_phaserSweepModel.setValue( s->m_phaserSweepModel.value()+frnd(0.1f)-0.05f ); + + if(rnd(1)) s->m_repeatSpeedModel.setValue( s->m_repeatSpeedModel.value()+frnd(0.1f)-0.05f ); + + if(rnd(1)) s->m_changeSpeedModel.setValue( s->m_changeSpeedModel.value()+frnd(0.1f)-0.05f ); + if(rnd(1)) s->m_changeAmtModel.setValue( s->m_changeAmtModel.value()+frnd(0.1f)-0.05f ); + } @@ -580,7 +925,7 @@ extern "C" // necessary for getting instance out of shared lib Plugin * PLUGIN_EXPORT lmms_plugin_main( Model *, void * _data ) { - return( new bitInvader( static_cast( _data ) ) ); + return( new sfxrInstrument( static_cast( _data ) ) ); } @@ -588,4 +933,4 @@ Plugin * PLUGIN_EXPORT lmms_plugin_main( Model *, void * _data ) -#include "moc_bit_invader.cxx" +#include "moc_sfxr.cxx" diff --git a/plugins/sfxr/sfxr.h b/plugins/sfxr/sfxr.h index 3b2320e80..e363dd343 100644 --- a/plugins/sfxr/sfxr.h +++ b/plugins/sfxr/sfxr.h @@ -1,5 +1,6 @@ /* * sfxr.h - declaration of classes of the LMMS sfxr plugin + * The original readme file of sfxr can be found in readme.txt in this directory. * * Copyright (c) 2014 Wong Cho Ching * @@ -29,19 +30,44 @@ #include "Instrument.h" #include "InstrumentView.h" #include "knob.h" +#include "graph.h" #include "pixmap_button.h" #include "led_checkbox.h" -class bitInvaderView; -class bSynth +enum SfxrWaves +{ + SQR_WAVE, SAW_WAVE, SINE_WAVE, NOISE_WAVE, WAVES_NUM +}; + +const int WAVEFORM_BASE_X = 20; +const int WAVEFORM_BASE_Y = 14; +const int WAVEFORM_BUTTON_WIDTH = 16; + +const int GENERATOR_BASE_X = 110; +const int GENERATOR_BASE_Y = 24; +const int GENERATOR_BUTTON_WIDTH = 16; + +const int RAND_BUTTON_X = 160; +const int RAND_BUTTON_Y = 4; + +const int MUTA_BUTTON_X = 205; +const int MUTA_BUTTON_Y = 4; + +const int KNOBS_BASE_X = 20; +const int KNOBS_BASE_Y = 50; +const int KNOB_BLOCK_SIZE_X = 40; +const int KNOB_BLOCK_SIZE_Y = 40; + + +class SfxrSynth { public: - bSynth( float * sample, int length, notePlayHandle * _nph, - bool _interpolation, float factor, + SfxrSynth( float * sample, int length, notePlayHandle * _nph, + bool _interpolation, float factor, const sample_rate_t _sample_rate ); - virtual ~bSynth(); - + virtual ~SfxrSynth(); + sample_t nextStringSample(); @@ -54,15 +80,39 @@ private: const sample_rate_t sample_rate; bool interpolation; - -} ; -class bitInvader : public Instrument +}; + +/** + * @brief A class that simplify the constructor of FloatModel, with value [0,1] + */ +class SfxrZeroToOneFloatModel : public FloatModel +{ +public: + SfxrZeroToOneFloatModel(float val, Model * parent): + FloatModel( val, 0.0, 1.0, 0.001, parent) + { + } +}; + +/** + * @brief A class that simplify the constructor of FloatModel, with value [-1,1] + */ +class SfxrNegPosOneFloatModel : public FloatModel +{ +public: + SfxrNegPosOneFloatModel(float val, Model * parent): + FloatModel( val, -1.0, 1.0, 0.001, parent) + { + } +}; + +class sfxrInstrument : public Instrument { Q_OBJECT public: - bitInvader(InstrumentTrack * _instrument_track ); - virtual ~bitInvader(); + sfxrInstrument(InstrumentTrack * _instrument_track ); + virtual ~sfxrInstrument(); virtual void playNote( notePlayHandle * _n, sampleFrame * _working_buffer ); @@ -75,77 +125,127 @@ public: virtual QString nodeName() const; - virtual f_cnt_t desiredReleaseFrames() const - { - return( 64 ); - } + virtual f_cnt_t desiredReleaseFrames() const; virtual PluginView * instantiateView( QWidget * _parent ); -protected slots: - void lengthChanged(); - void samplesChanged( int, int ); + void resetModels(); - void normalize(); +protected slots: + void samplesChanged( int, int ); private: - FloatModel m_sampleLength; - graphModel m_graph; - - BoolModel m_interpolation; - BoolModel m_normalize; - - float m_normalizeFactor; + SfxrZeroToOneFloatModel m_attModel; + SfxrZeroToOneFloatModel m_holdModel; + SfxrZeroToOneFloatModel m_susModel; + SfxrZeroToOneFloatModel m_decModel; - friend class bitInvaderView; -} ; + SfxrZeroToOneFloatModel m_startFreqModel; + SfxrZeroToOneFloatModel m_minFreqModel; + SfxrNegPosOneFloatModel m_slideModel; + SfxrNegPosOneFloatModel m_dSlideModel; + SfxrZeroToOneFloatModel m_vibDepthModel; + SfxrZeroToOneFloatModel m_vibSpeedModel; + + SfxrNegPosOneFloatModel m_changeAmtModel; + SfxrZeroToOneFloatModel m_changeSpeedModel; + + SfxrZeroToOneFloatModel m_sqrDutyModel; + SfxrNegPosOneFloatModel m_sqrSweepModel; + + SfxrZeroToOneFloatModel m_repeatSpeedModel; + + SfxrNegPosOneFloatModel m_phaserOffsetModel; + SfxrNegPosOneFloatModel m_phaserSweepModel; + + SfxrZeroToOneFloatModel m_lpFilCutModel; + SfxrNegPosOneFloatModel m_lpFilCutSweepModel; + SfxrZeroToOneFloatModel m_lpFilResoModel; + SfxrZeroToOneFloatModel m_hpFilCutModel; + SfxrNegPosOneFloatModel m_hpFilCutSweepModel; + + IntModel m_waveFormModel; + + friend class sfxrInstrumentView; +}; -class bitInvaderView : public InstrumentView +class sfxrInstrumentView : public InstrumentView { Q_OBJECT public: - bitInvaderView( Instrument * _instrument, + sfxrInstrumentView( Instrument * _instrument, QWidget * _parent ); - virtual ~bitInvaderView() {}; + virtual ~sfxrInstrumentView() {}; protected slots: - //void sampleSizeChanged( float _new_sample_length ); - - void interpolationToggled( bool value ); - void normalizeToggled( bool value ); - - void sinWaveClicked(); - void triangleWaveClicked(); - void sqrWaveClicked(); - void sawWaveClicked(); - void noiseWaveClicked(); - void usrWaveClicked(); - - void smoothClicked( void ); + void waveFormChanged(); + void genPickup(); + void genLaser(); + void genExplosion(); + void genPowerup(); + void genHit(); + void genJump(); + void genBlip(); + void randomize(); + void mutate(); private: virtual void modelChanged(); - knob * m_sampleLengthKnob; - pixmapButton * m_sinWaveBtn; - pixmapButton * m_triangleWaveBtn; - pixmapButton * m_sqrWaveBtn; + knob * m_attKnob; //Attack Time + knob * m_holdKnob; //Sustain Time + knob * m_susKnob; //Sustain Punch + knob * m_decKnob; //Decay Time + + knob * m_startFreqKnob; //Start Frequency + knob * m_minFreqKnob; //Min Frequency + knob * m_slideKnob; //Slide + knob * m_dSlideKnob; //Delta Slide + knob * m_vibDepthKnob; //Vibrato Depth + knob * m_vibSpeedKnob; //Vibrato Speed + + knob * m_changeAmtKnob; //Change Amount + knob * m_changeSpeedKnob; //Change Speed + + knob * m_sqrDutyKnob; //Squre Duty + knob * m_sqrSpeedKnob; //Squre Sweep + + knob * m_repeatSpeedKnob; //Repeat Speed + + knob * m_phaserOffsetKnob; //Phaser Offset + knob * m_phaserSweepKnob; //Phaser Sweep + + knob * m_lpFilCutKnob; //LP Filter Cutoff + knob * m_lpFilCutSweepKnob; //LP Filter Cutoff Sweep + knob * m_lpFilResoKnob; //LP Filter Resonance + knob * m_hpFilCutKnob; //HP Filter Cutoff + knob * m_hpFilCutSweepKnob; //HP Filter Cutoff Sweep + + automatableButtonGroup * m_waveBtnGroup; + pixmapButton * m_sqrWaveBtn; //NOTE: This button has Squre Duty + //and Squre Speed configurable pixmapButton * m_sawWaveBtn; - pixmapButton * m_whiteNoiseWaveBtn; - pixmapButton * m_smoothBtn; - pixmapButton * m_usrWaveBtn; + pixmapButton * m_sinWaveBtn; + pixmapButton * m_noiseWaveBtn; + + + pixmapButton * m_pickupBtn; + pixmapButton * m_laserBtn; + pixmapButton * m_explosionBtn; + pixmapButton * m_powerupBtn; + pixmapButton * m_hitBtn; + pixmapButton * m_jumpBtn; + pixmapButton * m_blipBtn; + + pixmapButton * m_randomizeBtn; + pixmapButton * m_mutateBtn; static QPixmap * s_artwork; - - graph * m_graph; - ledCheckBox * m_interpolationToggle; - ledCheckBox * m_normalizeToggle; - -} ; +};