diff --git a/data/locale/it.qm b/data/locale/it.qm index 28ddcfd3a..f5b44309d 100644 Binary files a/data/locale/it.qm and b/data/locale/it.qm differ diff --git a/data/locale/it.ts b/data/locale/it.ts index 7fc41fed6..64d6537fe 100644 --- a/data/locale/it.ts +++ b/data/locale/it.ts @@ -36,7 +36,9 @@ If you're interested in translating LMMS in another language or want to improve existing translations, you're welcome to help us! Simply contact the maintainer! Se hai partecipato alla traduzione ed il tuo nome non รจ presente in questa lista, aggiungilo! - Roberto Giaconia <derobyj@gmail.com> + Roberto Giaconia <derobyj@gmail.com> + +Se sei interessato a tradurre LMMS o vuoi migliorare una traduzione esistente, sei il benvenuto! License @@ -3256,7 +3258,7 @@ Assicurarsi di avere i permessi in lettura per il file e per la directory che lo Ui Contributors ordered by number of commits: - Hanno collaborato: (ordinati per numero di contributi) + Hanno collaborato (ordinati per numero di contributi): Involved @@ -4969,7 +4971,7 @@ Facendo doppio click sui plugin verranno fornite informazioni sulle relative por Wave Channel Volume - Volume wave del canale: + Volume wave del canale Noise Channel Volume: @@ -5342,7 +5344,7 @@ la rotellina del mouse impostare il volume delle note versatile kick- & bassdrum-synthesizer - sintetizzatore di colpo di cassa versatile + sintetizzatore di colpo di cassa e di kick versatile GUS-compatible patch instrument diff --git a/plugins/monstro/Monstro.cpp b/plugins/monstro/Monstro.cpp index 6f8721257..0323d63f0 100644 --- a/plugins/monstro/Monstro.cpp +++ b/plugins/monstro/Monstro.cpp @@ -67,11 +67,6 @@ MonstroSynth::MonstroSynth( MonstroInstrument * _i, NotePlayHandle * _nph, m_samplerate( _samplerate ), m_fpp( _frames ) { - m_env1_buf = new sample_t[_frames]; - m_env2_buf = new sample_t[_frames]; - m_lfo1_buf = new sample_t[_frames]; - m_lfo2_buf = new sample_t[_frames]; - m_osc1l_phase = 0.0f; m_osc1r_phase = 0.0f; m_osc2l_phase = 0.0f; @@ -84,15 +79,14 @@ MonstroSynth::MonstroSynth( MonstroInstrument * _i, NotePlayHandle * _nph, m_ph3l_last = 0.0f; m_ph3r_last = 0.0f; - m_env1_phase = 0.0f; - m_env2_phase = 0.0f; - - m_lfo1_phase = 0.0f; - m_lfo2_phase = 0.0f; - - m_lfo1_s = Oscillator::noiseSample( 0.0f ); - m_lfo2_s = Oscillator::noiseSample( 0.0f ); + m_env_phase[0] = 0.0f; + m_env_phase[1] = 0.0f; + m_lfo_phase[0] = 0.0f; + m_lfo_phase[1] = 0.0f; + m_lfo_next[0] = Oscillator::noiseSample( 0.0f ); + m_lfo_next[1] = Oscillator::noiseSample( 0.0f ); + m_osc1l_last = 0.0f; m_osc1r_last = 0.0f; @@ -118,11 +112,6 @@ MonstroSynth::MonstroSynth( MonstroInstrument * _i, NotePlayHandle * _nph, MonstroSynth::~MonstroSynth() { - delete[] m_env1_buf; - delete[] m_env2_buf; - delete[] m_lfo1_buf; - delete[] m_lfo2_buf; - } @@ -132,39 +121,78 @@ void MonstroSynth::renderOutput( fpp_t _frames, sampleFrame * _buf ) // macros for modulating with env/lfos #define modulatefreq( car, mod ) \ modtmp = 0.0f; \ - if( mod##_e1 != 0.0f ) modtmp += m_env1_buf[f] * mod##_e1; \ - if( mod##_e2 != 0.0f ) modtmp += m_env2_buf[f] * mod##_e2; \ - if( mod##_l1 != 0.0f ) modtmp += m_lfo1_buf[f] * mod##_l1; \ - if( mod##_l2 != 0.0f ) modtmp += m_lfo2_buf[f] * mod##_l2; \ + if( mod##_e1 != 0.0f ) modtmp += m_env[0] * mod##_e1; \ + if( mod##_e2 != 0.0f ) modtmp += m_env[1] * mod##_e2; \ + if( mod##_l1 != 0.0f ) modtmp += m_lfo[0] * mod##_l1; \ + if( mod##_l2 != 0.0f ) modtmp += m_lfo[1] * mod##_l2; \ car = qBound( MIN_FREQ, car * powf( 2.0f, modtmp ), MAX_FREQ ); #define modulateabs( car, mod ) \ - if( mod##_e1 != 0.0f ) car += m_env1_buf[f] * mod##_e1; \ - if( mod##_e2 != 0.0f ) car += m_env2_buf[f] * mod##_e2; \ - if( mod##_l1 != 0.0f ) car += m_lfo1_buf[f] * mod##_l1; \ - if( mod##_l2 != 0.0f ) car += m_lfo2_buf[f] * mod##_l2; + if( mod##_e1 != 0.0f ) car += m_env[0] * mod##_e1; \ + if( mod##_e2 != 0.0f ) car += m_env[1] * mod##_e2; \ + if( mod##_l1 != 0.0f ) car += m_lfo[0] * mod##_l1; \ + if( mod##_l2 != 0.0f ) car += m_lfo[1] * mod##_l2; #define modulatephs( car, mod ) \ - if( mod##_e1 != 0.0f ) car += m_env1_buf[f] * mod##_e1; \ - if( mod##_e2 != 0.0f ) car += m_env2_buf[f] * mod##_e2; \ - if( mod##_l1 != 0.0f ) car += m_lfo1_buf[f] * mod##_l1; \ - if( mod##_l2 != 0.0f ) car += m_lfo2_buf[f] * mod##_l2; + if( mod##_e1 != 0.0f ) car += m_env[0] * mod##_e1; \ + if( mod##_e2 != 0.0f ) car += m_env[1] * mod##_e2; \ + if( mod##_l1 != 0.0f ) car += m_lfo[0] * mod##_l1; \ + if( mod##_l2 != 0.0f ) car += m_lfo[1] * mod##_l2; #define modulatevol( car, mod ) \ - if( mod##_e1 > 0.0f ) car *= ( 1.0f - mod##_e1 + mod##_e1 * m_env1_buf[f] ); \ - if( mod##_e1 < 0.0f ) car *= ( 1.0f + mod##_e1 * m_env1_buf[f] ); \ - if( mod##_e2 > 0.0f ) car *= ( 1.0f - mod##_e2 + mod##_e2 * m_env2_buf[f] ); \ - if( mod##_e2 < 0.0f ) car *= ( 1.0f + mod##_e2 * m_env2_buf[f] ); \ - if( mod##_l1 != 0.0f ) car *= ( 1.0f + mod##_l1 * m_lfo1_buf[f] ); \ - if( mod##_l2 != 0.0f ) car *= ( 1.0f + mod##_l2 * m_lfo2_buf[f] ); \ + if( mod##_e1 > 0.0f ) car *= ( 1.0f - mod##_e1 + mod##_e1 * m_env[0] ); \ + if( mod##_e1 < 0.0f ) car *= ( 1.0f + mod##_e1 * m_env[0] ); \ + if( mod##_e2 > 0.0f ) car *= ( 1.0f - mod##_e2 + mod##_e2 * m_env[1] ); \ + if( mod##_e2 < 0.0f ) car *= ( 1.0f + mod##_e2 * m_env[1] ); \ + if( mod##_l1 != 0.0f ) car *= ( 1.0f + mod##_l1 * m_lfo[0] ); \ + if( mod##_l2 != 0.0f ) car *= ( 1.0f + mod##_l2 * m_lfo[1] ); \ car = qBound( -MODCLIP, car, MODCLIP ); - // pre-render env's and lfo's - renderModulators( _frames ); + + + //////////////////// + // // + // MODULATORS // + // // + //////////////////// + + // LFO phase offsets + const float lfo1_po = m_parent->m_lfo1Phs.value() / 360.0f; + const float lfo2_po = m_parent->m_lfo2Phs.value() / 360.0f; + + // remove cruft from phase counters to prevent overflow, add phase offset + m_lfo_phase[0] = absFraction( m_lfo_phase[0] + lfo1_po ); + m_lfo_phase[1] = absFraction( m_lfo_phase[1] + lfo2_po ); + + // LFO rates and increment + m_lfo_rate[0] = ( m_parent->m_lfo1Rate.value() * 0.001f * m_samplerate ); + m_lfo_rate[1] = ( m_parent->m_lfo2Rate.value() * 0.001f * m_samplerate ); + m_lfo_inc[0] = 1.0f / m_lfo_rate[0]; + m_lfo_inc[1] = 1.0f / m_lfo_rate[1]; + + m_env_sus[0] = m_parent-> m_env1Sus.value(); + m_env_sus[1] = m_parent-> m_env2Sus.value(); + + m_lfovalue[0] = m_parent->m_lfo1Wave.value(); + m_lfovalue[1] = m_parent->m_lfo2Wave.value(); + m_lfoatt[0] = m_parent->m_lfo1_att; + m_lfoatt[1] = m_parent->m_lfo2_att; + + m_env_pre[0] = m_parent->m_env1_pre; + m_env_att[0] = m_parent->m_env1_att; + m_env_hold[0] = m_parent->m_env1_hold; + m_env_dec[0] = m_parent->m_env1_dec; + m_env_rel[0] = m_parent->m_env1_rel; + m_env_pre[1] = m_parent->m_env2_pre; + m_env_att[1] = m_parent->m_env2_att; + m_env_hold[1] = m_parent->m_env2_hold; + m_env_dec[1] = m_parent->m_env2_dec; + m_env_rel[1] = m_parent->m_env2_rel; + // get updated osc1 values // get pulse width - const float pw = ( m_parent->m_osc1Pw.value() / 100.0f ); + const float pw = ( m_parent->m_osc1Pw.value() * 0.01f ); const float o1pw_e1 = ( m_parent->m_pw1env1.value() ); const float o1pw_e2 = ( m_parent->m_pw1env2.value() ); const float o1pw_l1 = ( m_parent->m_pw1lfo1.value() * 0.5f ); @@ -322,7 +350,8 @@ void MonstroSynth::renderOutput( fpp_t _frames, sampleFrame * _buf ) // begin for loop for( f_cnt_t f = 0; f < _frames; f++ ) { - + // update modulators + updateModulators( f ); /* // debug code if( f % 10 == 0 ) { @@ -618,408 +647,122 @@ void MonstroSynth::renderOutput( fpp_t _frames, sampleFrame * _buf ) m_osc3l_phase = absFraction( o3l_p - o3lpo ); m_osc3r_phase = absFraction( o3r_p - o3rpo ); + m_lfo_phase[0] = absFraction( m_lfo_phase[0] - lfo1_po ); + m_lfo_phase[1] = absFraction( m_lfo_phase[1] - lfo2_po ); } -void MonstroSynth::renderModulators( fpp_t _frames ) +inline void MonstroSynth::updateModulators( int frame ) { - // LFO phase offsets - const float lfo1_po = m_parent->m_lfo1Phs.value() / 360.0f; - const float lfo2_po = m_parent->m_lfo2Phs.value() / 360.0f; - - // remove cruft from phase counters to prevent overflow - m_lfo1_phase = fraction( m_lfo1_phase ); - m_lfo2_phase = fraction( m_lfo2_phase ); - - // LFO rates - const float lfo1_r = m_parent->m_lfo1Rate.value() / 1000.0f * m_samplerate; - const float lfo2_r = m_parent->m_lfo2Rate.value() / 1000.0f * m_samplerate; - // frames played before - const f_cnt_t tfp = m_nph->totalFramesPlayed(); - - // LFOs - // LFO 1 - - switch( m_parent->m_lfo1Wave.value() ) + const f_cnt_t tfp = m_nph->totalFramesPlayed() + frame; + + for( int i = 0; i < 2; ++i ) { - case WAVE_SINE: - for( f_cnt_t f = 0; f < _frames; f++ ) - { - const f_cnt_t t = f + tfp; - const float ph = m_lfo1_phase + lfo1_po; - m_lfo1_s = Oscillator::sinSample( ph ); - if( t < m_parent->m_lfo1_att ) m_lfo1_s *= ( static_cast( t ) / m_parent-> m_lfo1_att ); - m_lfo1_buf[f] = m_lfo1_s; - m_lfo1_phase += 1.0f / lfo1_r; - } - break; - case WAVE_TRI: - for( f_cnt_t f = 0; f < _frames; f++ ) - { - const f_cnt_t t = f + tfp; - const float ph = m_lfo1_phase + lfo1_po; - m_lfo1_s = Oscillator::triangleSample( ph ); - if( t < m_parent->m_lfo1_att ) m_lfo1_s *= ( static_cast( t ) / m_parent->m_lfo1_att ); - m_lfo1_buf[f] = m_lfo1_s; - m_lfo1_phase += 1.0f / lfo1_r; - } - break; - case WAVE_SAW: - for( f_cnt_t f = 0; f < _frames; f++ ) - { - const f_cnt_t t = f + tfp; - const float ph = m_lfo1_phase + lfo1_po; - m_lfo1_s = Oscillator::sawSample( ph ); - if( t < m_parent->m_lfo1_att ) m_lfo1_s *= ( static_cast( t ) / m_parent->m_lfo1_att ); - m_lfo1_buf[f] = m_lfo1_s; - m_lfo1_phase += 1.0f / lfo1_r; - } - break; - case WAVE_RAMP: - for( f_cnt_t f = 0; f < _frames; f++ ) - { - const f_cnt_t t = f + tfp; - const float ph = m_lfo1_phase + lfo1_po; - m_lfo1_s = Oscillator::sawSample( ph ) * -1.0f; - if( t < m_parent->m_lfo1_att ) m_lfo1_s *= ( static_cast( t ) / m_parent->m_lfo1_att ); - m_lfo1_buf[f] = m_lfo1_s; - m_lfo1_phase += 1.0f / lfo1_r; - } - break; - case WAVE_SQR: - for( f_cnt_t f = 0; f < _frames; f++ ) - { - const f_cnt_t t = f + tfp; - const float ph = m_lfo1_phase + lfo1_po; - m_lfo1_s = Oscillator::squareSample( ph ); - if( t < m_parent->m_lfo1_att ) m_lfo1_s *= ( static_cast( t ) / m_parent->m_lfo1_att ); - m_lfo1_buf[f] = m_lfo1_s; - m_lfo1_phase += 1.0f / lfo1_r; - } - break; - case WAVE_SQRSOFT: - for( f_cnt_t f = 0; f < _frames; f++ ) - { - const f_cnt_t t = f + tfp; - const float ph = m_lfo1_phase + lfo1_po; - m_lfo1_s = oscillate( WAVE_SQRSOFT, ph, lfo1_r ); - if( t < m_parent->m_lfo1_att ) m_lfo1_s *= ( static_cast( t ) / m_parent->m_lfo1_att ); - m_lfo1_buf[f] = m_lfo1_s; - m_lfo1_phase += 1.0f / lfo1_r; - } - break; - case WAVE_MOOG: - for( f_cnt_t f = 0; f < _frames; f++ ) - { - const f_cnt_t t = f + tfp; - const float ph = m_lfo1_phase + lfo1_po; - m_lfo1_s = Oscillator::moogSawSample( ph ); - if( t < m_parent->m_lfo1_att ) m_lfo1_s *= ( static_cast( t ) / m_parent->m_lfo1_att ); - m_lfo1_buf[f] = m_lfo1_s; - m_lfo1_phase += 1.0f / lfo1_r; - } - break; - case WAVE_SINABS: - for( f_cnt_t f = 0; f < _frames; f++ ) - { - const f_cnt_t t = f + tfp; - const float ph = m_lfo1_phase + lfo1_po; - m_lfo1_s = oscillate( WAVE_SINABS, ph, lfo1_r ); - if( t < m_parent->m_lfo1_att ) m_lfo1_s *= ( static_cast( t ) / m_parent->m_lfo1_att ); - m_lfo1_buf[f] = m_lfo1_s; - m_lfo1_phase += 1.0f / lfo1_r; - } - break; - case WAVE_EXP: - for( f_cnt_t f = 0; f < _frames; f++ ) - { - const f_cnt_t t = f + tfp; - const float ph = m_lfo1_phase + lfo1_po; - m_lfo1_s = Oscillator::expSample( ph ); - if( t < m_parent->m_lfo1_att ) m_lfo1_s *= ( static_cast( t ) / m_parent-> m_lfo1_att ); - m_lfo1_buf[f] = m_lfo1_s; - m_lfo1_phase += 1.0f / lfo1_r; - } - break; - case WAVE_RANDOM: - for( f_cnt_t f = 0; f < _frames; f++ ) - { - const f_cnt_t t = f + tfp; - if( t % static_cast( lfo1_r ) == 0 ) m_lfo1_last = Oscillator::noiseSample( 0.0f ); - m_lfo1_s = m_lfo1_last; - if( t < m_parent->m_lfo1_att ) m_lfo1_s *= ( static_cast( t ) / m_parent->m_lfo1_att ); - m_lfo1_buf[f] = m_lfo1_s; - } - m_lfo1_phase += static_cast( _frames ) / lfo1_r; - break; - case WAVE_RANDOM_SMOOTH: - default: - for( f_cnt_t f = 0; f < _frames; f++ ) - { - const f_cnt_t t = f + tfp; - const f_cnt_t tm = t % static_cast( lfo1_r ); - const float p = static_cast( tm ) / lfo1_r; - if( tm == 0 ) - { - m_lfo1_last = m_lfo1_s; - m_lfo1_s = Oscillator::noiseSample( 0.0f ); - } - m_lfo1_buf[f] = cosinusInterpolate( m_lfo1_last, m_lfo1_s, p ); - if( t < m_parent->m_lfo1_att ) m_lfo1_buf[f] *= ( static_cast( t ) / m_parent->m_lfo1_att ); - } - m_lfo1_phase += static_cast( _frames ) / lfo1_r; - break; - } - - // LFO 2 - - switch( m_parent->m_lfo2Wave.value() ) - { - case WAVE_SINE: - for( f_cnt_t f = 0; f < _frames; f++ ) - { - const f_cnt_t t = f + tfp; - const float ph = m_lfo2_phase + lfo2_po; - m_lfo2_s = Oscillator::sinSample( ph ); - if( t < m_parent->m_lfo2_att ) m_lfo2_s *= ( static_cast( t ) / m_parent-> m_lfo2_att ); - m_lfo2_buf[f] = m_lfo2_s; - m_lfo2_phase += 1.0f / lfo2_r; - } - break; - case WAVE_TRI: - for( f_cnt_t f = 0; f < _frames; f++ ) - { - const f_cnt_t t = f + tfp; - const float ph = m_lfo2_phase + lfo2_po; - m_lfo2_s = Oscillator::triangleSample( ph ); - if( t < m_parent->m_lfo2_att ) m_lfo2_s *= ( static_cast( t ) / m_parent->m_lfo2_att ); - m_lfo2_buf[f] = m_lfo2_s; - m_lfo2_phase += 1.0f / lfo2_r; - } - break; - case WAVE_SAW: - for( f_cnt_t f = 0; f < _frames; f++ ) - { - const f_cnt_t t = f + tfp; - const float ph = m_lfo2_phase + lfo2_po; - m_lfo2_s = Oscillator::sawSample( ph ); - if( t < m_parent->m_lfo2_att ) m_lfo2_s *= ( static_cast( t ) / m_parent->m_lfo2_att ); - m_lfo2_buf[f] = m_lfo2_s; - m_lfo2_phase += 1.0f / lfo2_r; - } - break; - case WAVE_RAMP: - for( f_cnt_t f = 0; f < _frames; f++ ) - { - const f_cnt_t t = f + tfp; - const float ph = m_lfo2_phase + lfo2_po; - m_lfo2_s = Oscillator::sawSample( ph ) * -1.0f; - if( t < m_parent->m_lfo2_att ) m_lfo2_s *= ( static_cast( t ) / m_parent->m_lfo2_att ); - m_lfo2_buf[f] = m_lfo2_s; - m_lfo2_phase += 1.0f / lfo2_r; - } - break; - case WAVE_SQR: - for( f_cnt_t f = 0; f < _frames; f++ ) - { - const f_cnt_t t = f + tfp; - const float ph = m_lfo2_phase + lfo2_po; - m_lfo2_s = Oscillator::squareSample( ph ); - if( t < m_parent->m_lfo2_att ) m_lfo2_s *= ( static_cast( t ) / m_parent->m_lfo2_att ); - m_lfo2_buf[f] = m_lfo2_s; - m_lfo2_phase += 1.0f / lfo2_r; - } - break; - case WAVE_SQRSOFT: - for( f_cnt_t f = 0; f < _frames; f++ ) - { - const f_cnt_t t = f + tfp; - const float ph = m_lfo2_phase + lfo2_po; - m_lfo2_s = oscillate( WAVE_SQRSOFT, ph, lfo2_r ); - if( t < m_parent->m_lfo2_att ) m_lfo2_s *= ( static_cast( t ) / m_parent->m_lfo2_att ); - m_lfo2_buf[f] = m_lfo2_s; - m_lfo2_phase += 1.0f / lfo2_r; - } - break; - case WAVE_MOOG: - for( f_cnt_t f = 0; f < _frames; f++ ) - { - const f_cnt_t t = f + tfp; - const float ph = m_lfo2_phase + lfo2_po; - m_lfo2_s = Oscillator::moogSawSample( ph ); - if( t < m_parent->m_lfo2_att ) m_lfo2_s *= ( static_cast( t ) / m_parent->m_lfo2_att ); - m_lfo2_buf[f] = m_lfo2_s; - m_lfo2_phase += 1.0f / lfo2_r; - } - break; - case WAVE_SINABS: - for( f_cnt_t f = 0; f < _frames; f++ ) - { - const f_cnt_t t = f + tfp; - const float ph = m_lfo2_phase + lfo2_po; - m_lfo2_s = oscillate( WAVE_SINABS, ph, lfo2_r ); - if( t < m_parent->m_lfo2_att ) m_lfo2_s *= ( static_cast( t ) / m_parent->m_lfo2_att ); - m_lfo2_buf[f] = m_lfo2_s; - m_lfo2_phase += 1.0f / lfo2_r; - } - break; - case WAVE_EXP: - for( f_cnt_t f = 0; f < _frames; f++ ) - { - const f_cnt_t t = f + tfp; - const float ph = m_lfo2_phase + lfo2_po; - m_lfo2_s = Oscillator::expSample( ph ); - if( t < m_parent->m_lfo2_att ) m_lfo2_s *= ( static_cast( t ) / m_parent-> m_lfo2_att ); - m_lfo2_buf[f] = m_lfo2_s; - m_lfo2_phase += 1.0f / lfo2_r; - } - break; - case WAVE_RANDOM: - for( f_cnt_t f = 0; f < _frames; f++ ) - { - const f_cnt_t t = f + tfp; - if( t % static_cast( lfo2_r ) == 0 ) m_lfo2_last = Oscillator::noiseSample( 0.0f ); - m_lfo2_s = m_lfo2_last; - if( t < m_parent->m_lfo2_att ) m_lfo2_s *= ( static_cast( t ) / m_parent->m_lfo2_att ); - m_lfo2_buf[f] = m_lfo2_s; - } - m_lfo2_phase += static_cast( _frames ) / lfo2_r; - break; - case WAVE_RANDOM_SMOOTH: - default: - for( f_cnt_t f = 0; f < _frames; f++ ) - { - const f_cnt_t t = f + tfp; - const f_cnt_t tm = t % static_cast( lfo2_r ); - const float p = static_cast( tm ) / lfo2_r; - if( tm == 0 ) - { - m_lfo2_last = m_lfo2_s; - m_lfo2_s = Oscillator::noiseSample( 0.0f ); - } - m_lfo2_buf[f] = cosinusInterpolate( m_lfo2_last, m_lfo2_s, p ); - if( t < m_parent->m_lfo2_att ) m_lfo2_buf[f] *= ( static_cast( t ) / m_parent->m_lfo2_att ); - } - m_lfo2_phase += static_cast( _frames ) / lfo2_r; - break; - } - - ///////////////////////////////////////////// - // - // - // envelopes - // - // - ///////////////////////////////////////////// - - const float env1_sus = m_parent-> m_env1Sus.value(); - const float env2_sus = m_parent-> m_env2Sus.value(); - - for( f_cnt_t f = 0; f < _frames; f++ ) - { - // envelope 1 - - // adjust phase for release - if( m_env1_phase < 4.0f && m_nph->isReleased() && f >= m_nph->framesBeforeRelease() ) + switch( m_lfovalue[i] ) { - if( m_env1_phase < 1.0f ) m_env1_phase = 5.0f; - else if( m_env1_phase < 2.0f ) m_env1_phase = 5.0f - fraction( m_env1_phase ); - else if( m_env1_phase < 3.0f ) m_env1_phase = 4.0f; - else m_env1_phase = 4.0f + fraction( m_env1_phase ); + case WAVE_SINE: + m_lfo[i] = Oscillator::sinSample( m_lfo_phase[i] ); + break; + case WAVE_TRI: + m_lfo[i] = Oscillator::triangleSample( m_lfo_phase[i] ); + break; + case WAVE_SAW: + m_lfo[i] = Oscillator::sawSample( m_lfo_phase[i] ); + break; + case WAVE_RAMP: + m_lfo[i] = Oscillator::sawSample( m_lfo_phase[i] ) * -1.0f; + break; + case WAVE_SQR: + m_lfo[i] = Oscillator::squareSample( m_lfo_phase[i] ); + break; + case WAVE_SQRSOFT: + m_lfo[i] = oscillate( WAVE_SQRSOFT, m_lfo_phase[i], 0 ); + break; + case WAVE_MOOG: + m_lfo[i] = Oscillator::moogSawSample( m_lfo_phase[i] ); + break; + case WAVE_SINABS: + m_lfo[i] = oscillate( WAVE_SINABS, m_lfo_phase[i], 0 ); + break; + case WAVE_EXP: + m_lfo[i] = Oscillator::expSample( m_lfo_phase[i] ); + break; + case WAVE_RANDOM: + if( tfp % static_cast( m_lfo_rate[i] ) == 0 ) m_lfo_last[i] = Oscillator::noiseSample( 0.0f ); + m_lfo[i] = m_lfo_last[i]; + break; + case WAVE_RANDOM_SMOOTH: + const f_cnt_t tm = tfp % static_cast( m_lfo_rate[i] ); + if( tm == 0 ) + { + m_lfo_last[i] = m_lfo_next[i]; + m_lfo_next[i] = Oscillator::noiseSample( 0.0f ); + } + m_lfo[i] = cosinusInterpolate( m_lfo_last[i], m_lfo_next[i], static_cast( tm ) / m_lfo_rate[i] ); + break; + } + + // attack + if( tfp < m_lfoatt[i] ) m_lfo[i] *= ( static_cast( tfp ) / m_lfoatt[i] ); + + // increment phase + m_lfo_phase[i] += m_lfo_inc[i]; + + + ///////////////////////////////////////////// + // // + // // + // envelopes // + // // + // // + ///////////////////////////////////////////// + + if( m_env_phase[i] < 4.0f && m_nph->isReleased() && frame >= m_nph->framesBeforeRelease() ) + { + if( m_env_phase[i] < 1.0f ) m_env_phase[i] = 5.0f; + else if( m_env_phase[i] < 2.0f ) m_env_phase[i] = 5.0f - fraction( m_env_phase[i] ); + else if( m_env_phase[i] < 3.0f ) m_env_phase[i] = 4.0f; + else m_env_phase[i] = 4.0f + fraction( m_env_phase[i] ); } // process envelope - if( m_env1_phase < 1.0f ) // pre-delay phase + if( m_env_phase[i] < 1.0f ) // pre-delay phase { - m_env1_buf[f] = 0.0f; - m_env1_phase = qMin( 1.0f, m_env1_phase + m_parent->m_env1_pre ); + m_env[i] = 0.0f; + m_env_phase[i] = qMin( 1.0f, m_env_phase[i] + m_env_pre[i] ); } - else if( m_env1_phase < 2.0f ) // attack phase + else if( m_env_phase[i] < 2.0f ) // attack phase { - m_env1_buf[f] = calcSlope1( fraction( m_env1_phase ) ); - m_env1_phase = qMin( 2.0f, m_env1_phase + m_parent->m_env1_att ); + m_env[i] = calcSlope1( fraction( m_env_phase[i] ) ); + m_env_phase[i] = qMin( 2.0f, m_env_phase[i] + m_env_att[i] ); } - else if( m_env1_phase < 3.0f ) // hold phase + else if( m_env_phase[i] < 3.0f ) // hold phase { - m_env1_buf[f] = 1.0f; - m_env1_phase = qMin( 3.0f, m_env1_phase + m_parent->m_env1_hold ); + m_env[i] = 1.0f; + m_env_phase[i] = qMin( 3.0f, m_env_phase[i] + m_env_hold[i] ); } - else if( m_env1_phase < 4.0f ) // decay phase + else if( m_env_phase[i] < 4.0f ) // decay phase { - const sample_t s = calcSlope1( 1.0f - fraction( m_env1_phase ) ); - if( s <= env1_sus ) + const sample_t s = calcSlope1( 1.0f - fraction( m_env_phase[i] ) ); + if( s <= m_env_sus[i] ) { - m_env1_buf[f] = env1_sus; + m_env[i] = m_env_sus[i]; } else { - m_env1_buf[f] = s; - m_env1_phase = qMin( 4.0f - env1_sus, m_env1_phase + m_parent->m_env1_dec ); - if( m_env1_phase == 4.0f ) m_env1_phase = 5.0f; // jump over release if sustain is zero - fix for clicking + m_env[i] = s; + m_env_phase[i] = qMin( 4.0f - m_env_sus[i], m_env_phase[i] + m_env_dec[i] ); + if( m_env_phase[i] == 4.0f ) m_env_phase[i] = 5.0f; // jump over release if sustain is zero - fix for clicking } } - else if( m_env1_phase < 5.0f ) // release phase + else if( m_env_phase[i] < 5.0f ) // release phase { - m_env1_buf[f] = calcSlope1( 1.0f - fraction( m_env1_phase ) ); - m_env1_phase += m_parent->m_env1_rel; + m_env[i] = calcSlope1( 1.0f - fraction( m_env_phase[i] ) ); + m_env_phase[i] += m_env_rel[i]; } - else m_env1_buf[f] = 0.0f; - -// qDebug( "env1 %f", m_env1_buf[f] ); - - // envelope 2 - - - - // adjust phase for release - if( m_env2_phase < 4.0f && m_nph->isReleased() && f >= m_nph->framesBeforeRelease() ) - { - if( m_env2_phase < 1.0f ) m_env2_phase = 5.0f; - else if( m_env2_phase < 2.0f ) m_env2_phase = 5.0f - fraction( m_env2_phase ); - else if( m_env2_phase < 3.0f ) m_env2_phase = 4.0f; - else m_env2_phase = 4.0f + fraction( m_env2_phase ); - } - - // process envelope - if( m_env2_phase < 1.0f ) // pre-delay phase - { - m_env2_buf[f] = 0.0f; - m_env2_phase = qMin( 1.0f, m_env2_phase + m_parent->m_env2_pre ); - } - else if( m_env2_phase < 2.0f ) // attack phase - { - m_env2_buf[f] = calcSlope2( fraction( m_env2_phase ) ); - m_env2_phase = qMin( 2.0f, m_env2_phase + m_parent->m_env2_att ); - } - else if( m_env2_phase < 3.0f ) // hold phase - { - m_env2_buf[f] = 1.0f; - m_env2_phase = qMin( 3.0f, m_env2_phase + m_parent->m_env2_hold ); - } - else if( m_env2_phase < 4.0f ) // decay phase - { - const sample_t s = calcSlope2( 1.0f - fraction( m_env2_phase ) ); - if( s <= env2_sus ) - { - m_env2_buf[f] = env2_sus; - } - else - { - m_env2_buf[f] = s; - m_env2_phase = qMin( 4.0f - env2_sus, m_env2_phase + m_parent->m_env2_dec ); - if( m_env2_phase == 4.0f ) m_env2_phase = 5.0f; // jump over release if sustain is zero - fix for clicking - } - } - else if( m_env2_phase < 5.0f ) // release phase - { - m_env2_buf[f] = calcSlope2( 1.0f - fraction( m_env2_phase) ); - m_env2_phase += m_parent->m_env2_rel; - } - else m_env2_buf[f] = 0.0f; - + else m_env[i] = 0.0f; } - } @@ -2072,7 +1815,7 @@ QWidget * MonstroView::setupOperatorsView( QWidget * _parent ) m_lfo2RateKnob -> setWhatsThis( tr( "Rate sets the speed of the LFO, measured in milliseconds per cycle. Can be synced to tempo. " ) ); m_lfo1PhsKnob -> setWhatsThis( tr( "PHS controls the phase offset of the LFO. " ) ); m_lfo2PhsKnob -> setWhatsThis( tr( "PHS controls the phase offset of the LFO. " ) ); - + m_env1PreKnob -> setWhatsThis( tr( "PRE, or pre-delay, delays the start of the envelope from the start of the note. 0 means no delay. " ) ); m_env2PreKnob -> setWhatsThis( tr( "PRE, or pre-delay, delays the start of the envelope from the start of the note. 0 means no delay. " ) ); m_env1AttKnob -> setWhatsThis( tr( "ATT, or attack, controls how fast the envelope ramps up at start, measured in milliseconds. " diff --git a/plugins/monstro/Monstro.h b/plugins/monstro/Monstro.h index 4b2066c88..b0e2c1bcd 100644 --- a/plugins/monstro/Monstro.h +++ b/plugins/monstro/Monstro.h @@ -208,12 +208,10 @@ private: const sample_rate_t m_samplerate; fpp_t m_fpp; - sample_t * m_env1_buf; - sample_t * m_env2_buf; - sample_t * m_lfo1_buf; - sample_t * m_lfo2_buf; + sample_t m_env [2]; + sample_t m_lfo [2]; - void renderModulators( fpp_t _frames ); + inline void updateModulators( int frame ); // linear interpolation /* inline sample_t interpolate( sample_t s1, sample_t s2, float x ) @@ -307,17 +305,21 @@ private: float m_osc3l_phase; float m_osc3r_phase; - sample_t m_env1_phase; - sample_t m_env2_phase; - - float m_lfo1_phase; - float m_lfo2_phase; + sample_t m_env_phase [2]; + float m_lfo_phase [2]; + sample_t m_lfo_last [2]; + sample_t m_lfo_next [2]; + float m_lfo_inc [2]; + float m_lfo_rate [2]; + float m_env_sus [2]; - sample_t m_lfo1_last; - sample_t m_lfo2_last; - - sample_t m_lfo1_s; - sample_t m_lfo2_s; + int m_lfovalue[2]; + int m_lfoatt[2]; + float m_env_pre[2]; + float m_env_att[2]; + float m_env_hold[2]; + float m_env_dec[2]; + float m_env_rel[2]; sample_t m_osc1l_last; sample_t m_osc1r_last;