Ported synth function
This commit is contained in:
@@ -1,6 +1,7 @@
|
||||
/*
|
||||
* sfxr.cpp - port of sfxr to LMMS
|
||||
* The original readme file of sfxr can be found in readme.txt in this directory.
|
||||
* Originally written by Tomas Pettersson. For the original license,
|
||||
* please read readme.txt in this directory
|
||||
*
|
||||
* Copyright (c) 2014 Wong Cho Ching
|
||||
*
|
||||
@@ -38,10 +39,8 @@ float frnd(float range)
|
||||
|
||||
#include "sfxr.h"
|
||||
#include "engine.h"
|
||||
#include "graph.h"
|
||||
#include "InstrumentTrack.h"
|
||||
#include "knob.h"
|
||||
#include "led_checkbox.h"
|
||||
#include "note_play_handle.h"
|
||||
#include "pixmap_button.h"
|
||||
#include "song_editor.h"
|
||||
@@ -71,73 +70,252 @@ Plugin::Descriptor PLUGIN_EXPORT sfxr_plugin_descriptor =
|
||||
}
|
||||
|
||||
|
||||
SfxrSynth::SfxrSynth( float * _shape, int _length, notePlayHandle * _nph, bool _interpolation,
|
||||
float _factor, const sample_rate_t _sample_rate ) :
|
||||
sample_index( 0 ),
|
||||
sample_realindex( 0 ),
|
||||
nph( _nph ),
|
||||
sample_length( _length ),
|
||||
sample_rate( _sample_rate ),
|
||||
interpolation( _interpolation)
|
||||
|
||||
|
||||
SfxrSynth::SfxrSynth( const sfxrInstrument * s ):
|
||||
s(s),
|
||||
playing_sample( true )
|
||||
{
|
||||
sample_shape = new float[sample_length];
|
||||
for (int i=0; i < _length; ++i)
|
||||
{
|
||||
sample_shape[i] = _shape[i] * _factor;
|
||||
}
|
||||
resetSample( false );
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
SfxrSynth::~SfxrSynth()
|
||||
{
|
||||
delete[] sample_shape;
|
||||
|
||||
}
|
||||
|
||||
|
||||
sample_t SfxrSynth::nextStringSample()
|
||||
|
||||
|
||||
void SfxrSynth::resetSample( bool restart )
|
||||
{
|
||||
float sample_step =
|
||||
static_cast<float>( sample_length / ( sample_rate / nph->frequency() ) );
|
||||
|
||||
|
||||
// check overflow
|
||||
while (sample_realindex >= sample_length) {
|
||||
sample_realindex -= sample_length;
|
||||
if(!restart)
|
||||
{
|
||||
phase=0;
|
||||
}
|
||||
fperiod=100.0/(s->m_startFreqModel.value()*s->m_startFreqModel.value()+0.001);
|
||||
period=(int)fperiod;
|
||||
fmaxperiod=100.0/(s->m_minFreqModel.value()*s->m_minFreqModel.value()+0.001);
|
||||
fslide=1.0-pow((double)s->m_slideModel.value(), 3.0)*0.01;
|
||||
fdslide=-pow((double)s->m_dSlideModel.value(), 3.0)*0.000001;
|
||||
square_duty=0.5f-s->m_sqrDutyModel.value()*0.5f;
|
||||
square_slide=-s->m_sqrSweepModel.value()*0.00005f;
|
||||
if(s->m_changeAmtModel.value()>=0.0f)
|
||||
arp_mod=1.0-pow((double)s->m_changeAmtModel.value(), 2.0)*0.9;
|
||||
else
|
||||
arp_mod=1.0+pow((double)s->m_changeAmtModel.value(), 2.0)*10.0;
|
||||
arp_time=0;
|
||||
arp_limit=(int)(pow(1.0f-s->m_changeSpeedModel.value(), 2.0f)*20000+32);
|
||||
if(s->m_changeSpeedModel.value()==1.0f)
|
||||
arp_limit=0;
|
||||
if(!restart)
|
||||
{
|
||||
// reset filter
|
||||
fltp=0.0f;
|
||||
fltdp=0.0f;
|
||||
fltw=pow(s->m_lpFilCutModel.value(), 3.0f)*0.1f;
|
||||
fltw_d=1.0f+s->m_lpFilCutSweepModel.value()*0.0001f;
|
||||
fltdmp=5.0f/(1.0f+pow(s->m_lpFilResoModel.value(), 2.0f)*20.0f)*(0.01f+fltw);
|
||||
if(fltdmp>0.8f) fltdmp=0.8f;
|
||||
fltphp=0.0f;
|
||||
flthp=pow(s->m_hpFilCutModel.value(), 2.0f)*0.1f;
|
||||
flthp_d=1.0+s->m_hpFilCutSweepModel.value()*0.0003f;
|
||||
// reset vibrato
|
||||
vib_phase=0.0f;
|
||||
vib_speed=pow(s->m_vibSpeedModel.value(), 2.0f)*0.01f;
|
||||
vib_amp=s->m_vibDepthModel.value()*0.5f;
|
||||
// reset envelope
|
||||
env_vol=0.0f;
|
||||
env_stage=0;
|
||||
env_time=0;
|
||||
env_length[0]=(int)(s->m_attModel.value()*s->m_attModel.value()*100000.0f);
|
||||
env_length[1]=(int)(s->m_holdModel.value()*s->m_holdModel.value()*100000.0f);
|
||||
env_length[2]=(int)(s->m_decModel.value()*s->m_decModel.value()*100000.0f);
|
||||
|
||||
sample_t sample;
|
||||
fphase=pow(s->m_phaserOffsetModel.value(), 2.0f)*1020.0f;
|
||||
if(s->m_phaserOffsetModel.value()<0.0f) fphase=-fphase;
|
||||
fdphase=pow(s->m_phaserSweepModel.value(), 2.0f)*1.0f;
|
||||
if(s->m_phaserSweepModel.value()<0.0f) fdphase=-fdphase;
|
||||
iphase=abs((int)fphase);
|
||||
ipp=0;
|
||||
for(int i=0;i<1024;i++)
|
||||
phaser_buffer[i]=0.0f;
|
||||
|
||||
if (interpolation) {
|
||||
for(int i=0;i<32;i++)
|
||||
noise_buffer[i]=frnd(2.0f)-1.0f;
|
||||
|
||||
// find position in shape
|
||||
int a = static_cast<int>(sample_realindex);
|
||||
int b;
|
||||
if (a < (sample_length-1)) {
|
||||
b = static_cast<int>(sample_realindex+1);
|
||||
} else {
|
||||
b = 0;
|
||||
rep_time=0;
|
||||
rep_limit=(int)(pow(1.0f-s->m_repeatSpeedModel.value(), 2.0f)*20000+32);
|
||||
if(s->m_repeatSpeedModel.value()==0.0f)
|
||||
rep_limit=0;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
void SfxrSynth::update( sampleFrame * buffer, const fpp_t frameNum )
|
||||
{
|
||||
for(int i=0;i<frameNum;i++)
|
||||
{
|
||||
if(!playing_sample)
|
||||
{
|
||||
for( ch_cnt_t j=0; j < DEFAULT_CHANNELS; j++ )
|
||||
{
|
||||
buffer[i][j]=0.0f;
|
||||
}
|
||||
}
|
||||
|
||||
rep_time++;
|
||||
if(rep_limit!=0 && rep_time>=rep_limit)
|
||||
{
|
||||
rep_limit=0;
|
||||
resetSample(true);
|
||||
}
|
||||
|
||||
// Nachkommaanteil
|
||||
float frac = sample_realindex - static_cast<int>(sample_realindex);
|
||||
// frequency envelopes/arpeggios
|
||||
arp_time++;
|
||||
if(arp_limit!=0 && arp_time>=arp_limit)
|
||||
{
|
||||
arp_limit=0;
|
||||
fperiod*=arp_mod;
|
||||
}
|
||||
fslide+=fdslide;
|
||||
fperiod*=fslide;
|
||||
if(fperiod>fmaxperiod)
|
||||
{
|
||||
fperiod=fmaxperiod;
|
||||
if(s->m_minFreqModel.value()>0.0f)
|
||||
playing_sample=false;
|
||||
}
|
||||
float rfperiod=fperiod;
|
||||
if(vib_amp>0.0f)
|
||||
{
|
||||
vib_phase+=vib_speed;
|
||||
rfperiod=fperiod*(1.0+sin(vib_phase)*vib_amp);
|
||||
}
|
||||
period=(int)rfperiod;
|
||||
if(period<8) period=8;
|
||||
square_duty+=square_slide;
|
||||
if(square_duty<0.0f) square_duty=0.0f;
|
||||
if(square_duty>0.5f) square_duty=0.5f;
|
||||
// volume envelope
|
||||
env_time++;
|
||||
if(env_time>env_length[env_stage])
|
||||
{
|
||||
env_time=0;
|
||||
env_stage++;
|
||||
if(env_stage==3)
|
||||
playing_sample=false;
|
||||
}
|
||||
if(env_stage==0)
|
||||
env_vol=(float)env_time/env_length[0];
|
||||
if(env_stage==1)
|
||||
env_vol=1.0f+pow(1.0f-(float)env_time/env_length[1], 1.0f)*2.0f*s->m_susModel.value();
|
||||
if(env_stage==2)
|
||||
env_vol=1.0f-(float)env_time/env_length[2];
|
||||
|
||||
sample = sample_shape[a]*(1-frac) + sample_shape[b]*(frac);
|
||||
// phaser step
|
||||
fphase+=fdphase;
|
||||
iphase=abs((int)fphase);
|
||||
if(iphase>1023) iphase=1023;
|
||||
|
||||
} else {
|
||||
// No interpolation
|
||||
sample_index = static_cast<int>(sample_realindex);
|
||||
sample = sample_shape[sample_index];
|
||||
if(flthp_d!=0.0f)
|
||||
{
|
||||
flthp*=flthp_d;
|
||||
if(flthp<0.00001f) flthp=0.00001f;
|
||||
if(flthp>0.1f) flthp=0.1f;
|
||||
}
|
||||
|
||||
float ssample=0.0f;
|
||||
for(int si=0;si<8;si++) // 8x supersampling
|
||||
{
|
||||
float sample=0.0f;
|
||||
phase++;
|
||||
if(phase>=period)
|
||||
{
|
||||
// phase=0;
|
||||
phase%=period;
|
||||
if(s->m_waveFormModel.value()==3)
|
||||
for(int i=0;i<32;i++)
|
||||
noise_buffer[i]=frnd(2.0f)-1.0f;
|
||||
}
|
||||
// base waveform
|
||||
float fp=(float)phase/period;
|
||||
switch(s->m_waveFormModel.value())
|
||||
{
|
||||
case 0: // square
|
||||
if(fp<square_duty)
|
||||
sample=0.5f;
|
||||
else
|
||||
sample=-0.5f;
|
||||
break;
|
||||
case 1: // sawtooth
|
||||
sample=1.0f-fp*2;
|
||||
break;
|
||||
case 2: // sine
|
||||
sample=(float)sin(fp*2*PI);
|
||||
break;
|
||||
case 3: // noise
|
||||
sample=noise_buffer[phase*32/period];
|
||||
break;
|
||||
}
|
||||
// lp filter
|
||||
float pp=fltp;
|
||||
fltw*=fltw_d;
|
||||
if(fltw<0.0f) fltw=0.0f;
|
||||
if(fltw>0.1f) fltw=0.1f;
|
||||
if(s->m_lpFilCutModel.value()!=1.0f)
|
||||
{
|
||||
fltdp+=(sample-fltp)*fltw;
|
||||
fltdp-=fltdp*fltdmp;
|
||||
}
|
||||
else
|
||||
{
|
||||
fltp=sample;
|
||||
fltdp=0.0f;
|
||||
}
|
||||
fltp+=fltdp;
|
||||
// hp filter
|
||||
fltphp+=fltp-pp;
|
||||
fltphp-=fltphp*flthp;
|
||||
sample=fltphp;
|
||||
// phaser
|
||||
phaser_buffer[ipp&1023]=sample;
|
||||
sample+=phaser_buffer[(ipp-iphase+1024)&1023];
|
||||
ipp=(ipp+1)&1023;
|
||||
// final accumulation and envelope application
|
||||
ssample+=sample*env_vol;
|
||||
}
|
||||
//ssample=ssample/8*master_vol;
|
||||
|
||||
//ssample*=2.0f*sound_vol;
|
||||
ssample*=0.05f;
|
||||
|
||||
if(buffer!=NULL)
|
||||
{
|
||||
if(ssample>1.0f) ssample=1.0f;
|
||||
if(ssample<-1.0f) ssample=-1.0f;
|
||||
for( ch_cnt_t j=0; j < DEFAULT_CHANNELS; j++ )
|
||||
{
|
||||
buffer[i][j]=ssample;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// progress in shape
|
||||
sample_realindex += sample_step;
|
||||
|
||||
return sample;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
bool SfxrSynth::isPlaying() const
|
||||
{
|
||||
return playing_sample;
|
||||
}
|
||||
|
||||
|
||||
sfxrInstrument::sfxrInstrument( InstrumentTrack * _instrument_track ) :
|
||||
Instrument( _instrument_track, &sfxr_plugin_descriptor ),
|
||||
m_attModel(0.0f, this),
|
||||
@@ -170,14 +348,6 @@ sfxrInstrument::sfxrInstrument( InstrumentTrack * _instrument_track ) :
|
||||
m_hpFilCutSweepModel(0.0f, this),
|
||||
m_waveFormModel( SQR_WAVE, 0, WAVES_NUM-1, this, tr( "Wave Form" ) )
|
||||
{
|
||||
//TODO
|
||||
/*
|
||||
connect( &m_sampleLength, SIGNAL( dataChanged( ) ),
|
||||
this, SLOT( lengthChanged( ) ) );
|
||||
|
||||
connect( &m_graph, SIGNAL( samplesChanged( int, int ) ),
|
||||
this, SLOT( samplesChanged( int, int ) ) );
|
||||
*/
|
||||
}
|
||||
|
||||
|
||||
@@ -267,16 +437,6 @@ void sfxrInstrument::loadSettings( const QDomElement & _this )
|
||||
|
||||
|
||||
|
||||
void sfxrInstrument::samplesChanged( int _begin, int _end )
|
||||
{
|
||||
//TODO
|
||||
//normalize();
|
||||
//engine::getSongEditor()->setModified();
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
QString sfxrInstrument::nodeName() const
|
||||
{
|
||||
return( sfxr_plugin_descriptor.name );
|
||||
@@ -285,54 +445,23 @@ QString sfxrInstrument::nodeName() const
|
||||
|
||||
|
||||
|
||||
f_cnt_t sfxrInstrument::desiredReleaseFrames() const
|
||||
void sfxrInstrument::playNote(notePlayHandle * _n, sampleFrame * _working_buffer )
|
||||
{
|
||||
//TODO: check whether this disables
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
|
||||
void sfxrInstrument::playNote( notePlayHandle * _n,
|
||||
sampleFrame * _working_buffer )
|
||||
{
|
||||
//TODO
|
||||
/*if ( _n->totalFramesPlayed() == 0 || _n->m_pluginData == NULL )
|
||||
m_synthMutex.lock();
|
||||
fpp_t frameNum = _n->framesLeftForCurrentPeriod();
|
||||
if ( _n->totalFramesPlayed() == 0 )
|
||||
{
|
||||
|
||||
float factor;
|
||||
if( !m_normalize.value() )
|
||||
{
|
||||
factor = 1.0f;
|
||||
}
|
||||
else
|
||||
{
|
||||
factor = m_normalizeFactor;
|
||||
}
|
||||
|
||||
_n->m_pluginData = new SfxrSynth(
|
||||
const_cast<float*>( m_graph.samples() ),
|
||||
m_graph.length(),
|
||||
_n,
|
||||
m_interpolation.value(), factor,
|
||||
engine::mixer()->processingSampleRate() );
|
||||
_n->m_pluginData = new SfxrSynth( this );
|
||||
}
|
||||
else if( static_cast<SfxrSynth*>(_n->m_pluginData)->isPlaying() == false )
|
||||
{
|
||||
_n->noteOff();
|
||||
}
|
||||
|
||||
const fpp_t frames = _n->framesLeftForCurrentPeriod();
|
||||
static_cast<SfxrSynth*>(_n->m_pluginData)->update( _working_buffer, frameNum );
|
||||
m_synthMutex.unlock();
|
||||
|
||||
SfxrSynth * ps = static_cast<SfxrSynth *>( _n->m_pluginData );
|
||||
for( fpp_t frame = 0; frame < frames; ++frame )
|
||||
{
|
||||
const sample_t cur = ps->nextStringSample();
|
||||
for( ch_cnt_t chnl = 0; chnl < DEFAULT_CHANNELS; ++chnl )
|
||||
{
|
||||
_working_buffer[frame][chnl] = cur;
|
||||
}
|
||||
}
|
||||
|
||||
applyRelease( _working_buffer, _n );
|
||||
|
||||
instrumentTrack()->processAudioBuffer( _working_buffer, frames, _n );*/
|
||||
instrumentTrack()->processAudioBuffer( _working_buffer, frameNum, NULL );
|
||||
}
|
||||
|
||||
|
||||
@@ -356,6 +485,7 @@ PluginView * sfxrInstrument::instantiateView( QWidget * _parent )
|
||||
|
||||
void sfxrInstrument::resetModels()
|
||||
{
|
||||
|
||||
m_attModel.reset();
|
||||
m_holdModel.reset();
|
||||
m_susModel.reset();
|
||||
@@ -463,7 +593,7 @@ sfxrInstrumentView::sfxrInstrumentView( Instrument * _instrument,
|
||||
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_sqrSweepKnob, 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");
|
||||
|
||||
@@ -485,9 +615,7 @@ sfxrInstrumentView::sfxrInstrumentView( Instrument * _instrument,
|
||||
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() ) );
|
||||
m_waveBtnGroup->addButton(m_noiseWaveBtn);
|
||||
|
||||
|
||||
createButtonLocalGraphic(m_pickupBtn, GENERATOR_BASE_X+GENERATOR_BUTTON_WIDTH*0, GENERATOR_BASE_Y, "Generate pick up/coin sfx", "pickup");
|
||||
@@ -511,10 +639,6 @@ sfxrInstrumentView::sfxrInstrumentView( Instrument * _instrument,
|
||||
connect( m_randomizeBtn, SIGNAL ( clicked() ), this, SLOT ( randomize() ) );
|
||||
connect( m_mutateBtn, SIGNAL ( clicked() ), this, SLOT ( mutate() ) );
|
||||
|
||||
//TODO: for each generator button:
|
||||
/*connect( m_pickupBtn, SIGNAL ( dataChanged() ),
|
||||
this, SLOT ( pickupClicked() ) );*/
|
||||
|
||||
|
||||
}
|
||||
|
||||
@@ -541,7 +665,7 @@ void sfxrInstrumentView::modelChanged()
|
||||
m_changeSpeedKnob->setModel( &s->m_changeSpeedModel );
|
||||
|
||||
m_sqrDutyKnob->setModel( &s->m_sqrDutyModel );
|
||||
m_sqrSpeedKnob->setModel( &s->m_sqrSweepModel );
|
||||
m_sqrSweepKnob->setModel( &s->m_sqrSweepModel );
|
||||
|
||||
m_repeatSpeedKnob->setModel( &s->m_repeatSpeedModel );
|
||||
|
||||
@@ -560,32 +684,20 @@ void sfxrInstrumentView::modelChanged()
|
||||
|
||||
|
||||
|
||||
void sfxrInstrumentView::waveFormChanged()
|
||||
{
|
||||
//TODO: do we even need this slot?
|
||||
/*
|
||||
m_graph->model()->setWaveToNoise();
|
||||
engine::getSong()->setModified();
|
||||
*/
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
void sfxrInstrumentView::genPickup()
|
||||
{
|
||||
sfxrInstrument * s = castModel<sfxrInstrument>();
|
||||
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) );
|
||||
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) );
|
||||
s->m_changeSpeedModel.setValue( 0.5f+frnd(0.2f) );
|
||||
s->m_changeAmtModel.setValue( 0.2f+frnd(0.4f) );
|
||||
}
|
||||
}
|
||||
|
||||
@@ -599,9 +711,9 @@ void sfxrInstrumentView::genLaser()
|
||||
|
||||
s->m_waveFormModel.setValue( rnd(2) );
|
||||
if(s->m_waveFormModel.value()==2 && rnd(1))
|
||||
s->m_waveFormModel.setValue(rnd(1));
|
||||
s->m_waveFormModel.setValue( rnd(1) );
|
||||
|
||||
s->m_startFreqModel.setValue( 0.5f+frnd(0.5f) );
|
||||
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)
|
||||
@@ -615,7 +727,7 @@ void sfxrInstrumentView::genLaser()
|
||||
{
|
||||
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) );
|
||||
s->m_slideModel.setValue( -0.35f-frnd(0.3f) );
|
||||
}
|
||||
|
||||
if(rnd(1))
|
||||
@@ -747,9 +859,13 @@ void sfxrInstrumentView::genHit()
|
||||
|
||||
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) );
|
||||
@@ -785,12 +901,12 @@ void sfxrInstrumentView::genJump()
|
||||
{
|
||||
s->m_hpFilCutModel.setValue( frnd(0.3f) );
|
||||
}
|
||||
|
||||
if(rnd(1))
|
||||
{
|
||||
|
||||
s->m_lpFilCutModel.setValue( 1.0f-frnd(0.6f) );
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
/*
|
||||
* 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.
|
||||
* Originally written by Tomas Pettersson. For the original license,
|
||||
* please read readme.txt in this directory
|
||||
*
|
||||
* Copyright (c) 2014 Wong Cho Ching
|
||||
*
|
||||
@@ -60,28 +61,64 @@ const int KNOB_BLOCK_SIZE_X = 40;
|
||||
const int KNOB_BLOCK_SIZE_Y = 40;
|
||||
|
||||
|
||||
|
||||
|
||||
class sfxrInstrument;
|
||||
|
||||
|
||||
|
||||
class SfxrSynth
|
||||
{
|
||||
public:
|
||||
SfxrSynth( float * sample, int length, notePlayHandle * _nph,
|
||||
bool _interpolation, float factor,
|
||||
const sample_rate_t _sample_rate );
|
||||
SfxrSynth( const sfxrInstrument * s );
|
||||
virtual ~SfxrSynth();
|
||||
|
||||
sample_t nextStringSample();
|
||||
void resetSample( bool restart );
|
||||
void update( sampleFrame * buffer, const fpp_t frameNum );
|
||||
|
||||
bool isPlaying() const;
|
||||
|
||||
private:
|
||||
int sample_index;
|
||||
float sample_realindex;
|
||||
float* sample_shape;
|
||||
notePlayHandle* nph;
|
||||
const int sample_length;
|
||||
const sample_rate_t sample_rate;
|
||||
const sfxrInstrument * s;
|
||||
bool playing_sample;
|
||||
int phase;
|
||||
double fperiod;
|
||||
double fmaxperiod;
|
||||
double fslide;
|
||||
double fdslide;
|
||||
int period;
|
||||
float square_duty;
|
||||
float square_slide;
|
||||
int env_stage;
|
||||
int env_time;
|
||||
int env_length[3];
|
||||
float env_vol;
|
||||
float fphase;
|
||||
float fdphase;
|
||||
int iphase;
|
||||
float phaser_buffer[1024];
|
||||
int ipp;
|
||||
float noise_buffer[32];
|
||||
float fltp;
|
||||
float fltdp;
|
||||
float fltw;
|
||||
float fltw_d;
|
||||
float fltdmp;
|
||||
float fltphp;
|
||||
float flthp;
|
||||
float flthp_d;
|
||||
float vib_phase;
|
||||
float vib_speed;
|
||||
float vib_amp;
|
||||
int rep_time;
|
||||
int rep_limit;
|
||||
int arp_time;
|
||||
int arp_limit;
|
||||
double arp_mod;
|
||||
|
||||
} ;
|
||||
|
||||
bool interpolation;
|
||||
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief A class that simplify the constructor of FloatModel, with value [0,1]
|
||||
@@ -93,6 +130,15 @@ public:
|
||||
FloatModel( val, 0.0, 1.0, 0.001, parent)
|
||||
{
|
||||
}
|
||||
/* purpose: prevent the initial value of the model from being changed */
|
||||
virtual void loadSettings( const QDomElement& element, const QString& name = QString( "value" ) )
|
||||
{
|
||||
float oldInitValue = initValue();
|
||||
FloatModel::loadSettings(element, name);
|
||||
float oldValue = value();
|
||||
setInitValue(oldInitValue);
|
||||
setValue(oldValue);
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
@@ -105,6 +151,15 @@ public:
|
||||
FloatModel( val, -1.0, 1.0, 0.001, parent)
|
||||
{
|
||||
}
|
||||
/* purpose: prevent the initial value of the model from being changed */
|
||||
virtual void loadSettings( const QDomElement& element, const QString& name = QString( "value" ) )
|
||||
{
|
||||
float oldInitValue = initValue();
|
||||
FloatModel::loadSettings(element, name);
|
||||
float oldValue = value();
|
||||
setInitValue(oldInitValue);
|
||||
setValue(oldValue);
|
||||
}
|
||||
};
|
||||
|
||||
class sfxrInstrument : public Instrument
|
||||
@@ -114,28 +169,22 @@ public:
|
||||
sfxrInstrument(InstrumentTrack * _instrument_track );
|
||||
virtual ~sfxrInstrument();
|
||||
|
||||
virtual void playNote( notePlayHandle * _n,
|
||||
sampleFrame * _working_buffer );
|
||||
virtual void playNote( notePlayHandle * _n, sampleFrame * _working_buffer );
|
||||
virtual void deleteNotePluginData( notePlayHandle * _n );
|
||||
|
||||
|
||||
virtual void saveSettings( QDomDocument & _doc,
|
||||
QDomElement & _parent );
|
||||
virtual void loadSettings( const QDomElement & _this );
|
||||
|
||||
virtual QString nodeName() const;
|
||||
|
||||
virtual f_cnt_t desiredReleaseFrames() const;
|
||||
|
||||
virtual PluginView * instantiateView( QWidget * _parent );
|
||||
|
||||
void resetModels();
|
||||
|
||||
protected slots:
|
||||
void samplesChanged( int, int );
|
||||
|
||||
|
||||
private:
|
||||
QMutex m_synthMutex;
|
||||
SfxrZeroToOneFloatModel m_attModel;
|
||||
SfxrZeroToOneFloatModel m_holdModel;
|
||||
SfxrZeroToOneFloatModel m_susModel;
|
||||
@@ -168,6 +217,7 @@ private:
|
||||
IntModel m_waveFormModel;
|
||||
|
||||
friend class sfxrInstrumentView;
|
||||
friend class SfxrSynth;
|
||||
};
|
||||
|
||||
|
||||
@@ -182,7 +232,6 @@ public:
|
||||
virtual ~sfxrInstrumentView() {};
|
||||
|
||||
protected slots:
|
||||
void waveFormChanged();
|
||||
void genPickup();
|
||||
void genLaser();
|
||||
void genExplosion();
|
||||
@@ -212,7 +261,7 @@ private:
|
||||
knob * m_changeSpeedKnob; //Change Speed
|
||||
|
||||
knob * m_sqrDutyKnob; //Squre Duty
|
||||
knob * m_sqrSpeedKnob; //Squre Sweep
|
||||
knob * m_sqrSweepKnob; //Squre Sweep
|
||||
|
||||
knob * m_repeatSpeedKnob; //Repeat Speed
|
||||
|
||||
|
||||
Reference in New Issue
Block a user