Fixed issues with original verion, as directed in pull request.
corrected the typeo's, Used sampleFrame instead of float* making the code cleaner. Set up a socket to change the samplerate where required. Stopped using malloc ( yeah that was bad practice on my part ). Now using lmms_Math.h and the predefined versions of F_PI and F_2PI, I didn't know data from the knobs etc. was not updated over the course of a buffer, so have moved outside the processing loop, made appropriate functions inline, used sinf. Multiplication has replaced division where possible, zeroing of the buffer has been removed, as redundant.
This commit is contained in:
@@ -666,7 +666,7 @@ If you're interested in translating LMMS in another language or want to imp
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Lfo Ammount</source>
|
||||
<source>Lfo Amount</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
</context>
|
||||
@@ -685,7 +685,7 @@ If you're interested in translating LMMS in another language or want to imp
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Feedback Ammount:</source>
|
||||
<source>Feedback Amount:</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
|
||||
@@ -33,11 +33,11 @@ DelayControls::DelayControls(DelayEffect* effect):
|
||||
EffectControls( effect ),
|
||||
m_effect ( effect ),
|
||||
m_delayTimeModel( 2.0, 0.01, 20.0, 0.0001, 20000.0, this, tr( "Delay Samples" )) ,
|
||||
m_feebackModel(0.0f,0.0f,1.0f,0.01f,this,tr( "Feedback" ) ),
|
||||
m_feedbackModel(0.0f,0.0f,1.0f,0.01f,this,tr( "Feedback" ) ),
|
||||
m_lfoTimeModel(2.0, 0.01, 20.0, 0.0001, 20000.0, this, tr( "Lfo Frequency" ) ),
|
||||
m_lfoAmmountModel(0.0f,0.0f,0.5f,0.01f, this, tr ( "Lfo Ammount" ) )
|
||||
m_lfoAmountModel(0.0f,0.0f,0.5f,0.01f, this, tr ( "Lfo Amount" ) )
|
||||
{
|
||||
|
||||
//used to setup the controls
|
||||
}
|
||||
|
||||
|
||||
@@ -54,9 +54,9 @@ void DelayControls::changeControl()
|
||||
void DelayControls::loadSettings(const QDomElement &_this)
|
||||
{
|
||||
m_delayTimeModel.loadSettings(_this, "DelayTimeSamples" );
|
||||
m_feebackModel.loadSettings( _this, "FeebackAmmount" );
|
||||
m_feedbackModel.loadSettings( _this, "FeebackAmount" );
|
||||
m_lfoTimeModel.loadSettings( _this , "LfoFrequency");
|
||||
m_lfoAmmountModel.loadSettings( _this, "LfoAmmount");
|
||||
m_lfoAmountModel.loadSettings( _this, "LfoAmount");
|
||||
}
|
||||
|
||||
|
||||
@@ -65,9 +65,9 @@ void DelayControls::loadSettings(const QDomElement &_this)
|
||||
void DelayControls::saveSettings(QDomDocument& doc, QDomElement& _this)
|
||||
{
|
||||
m_delayTimeModel.saveSettings( doc, _this, "DelayTimeSamples");
|
||||
m_feebackModel.saveSettings( doc, _this ,"FeebackAmmount");
|
||||
m_feedbackModel.saveSettings( doc, _this ,"FeebackAmount");
|
||||
m_lfoTimeModel.saveSettings( doc, _this, "LfoFrequency");
|
||||
m_lfoAmmountModel.saveSettings( doc, _this ,"LfoAmmount");
|
||||
m_lfoAmountModel.saveSettings( doc, _this ,"LfoAmount");
|
||||
}
|
||||
|
||||
#include "moc_delaycontrols.cxx"
|
||||
|
||||
@@ -61,9 +61,9 @@ private slots:
|
||||
private:
|
||||
DelayEffect* m_effect;
|
||||
TempoSyncKnobModel m_delayTimeModel;
|
||||
FloatModel m_feebackModel;
|
||||
FloatModel m_feedbackModel;
|
||||
TempoSyncKnobModel m_lfoTimeModel;
|
||||
FloatModel m_lfoAmmountModel;
|
||||
FloatModel m_lfoAmountModel;
|
||||
|
||||
friend class DelayControlsDialog;
|
||||
friend class DelayEffect;
|
||||
|
||||
@@ -49,9 +49,9 @@ DelayControlsDialog::DelayControlsDialog(DelayControls *controls) :
|
||||
knob * feedbackKnob = new knob( knobBright_26, this);
|
||||
feedbackKnob->move( 60,30 );
|
||||
feedbackKnob->setVolumeKnob(true);
|
||||
feedbackKnob->setModel( &controls->m_feebackModel);
|
||||
feedbackKnob->setModel( &controls->m_feedbackModel);
|
||||
feedbackKnob->setLabel( tr( "Feedback" ) );
|
||||
feedbackKnob->setHintText( tr ( "Feedback Ammount:" ) + " ", "");
|
||||
feedbackKnob->setHintText( tr ( "Feedback Amount:" ) + " ", "");
|
||||
|
||||
TempoSyncKnob * lfoFreqKnob = new TempoSyncKnob( knobBright_26, this);
|
||||
lfoFreqKnob->move( 20,80 );
|
||||
@@ -63,7 +63,7 @@ DelayControlsDialog::DelayControlsDialog(DelayControls *controls) :
|
||||
knob * lfoAmtKnob = new knob( knobBright_26, this);
|
||||
lfoAmtKnob->move( 60,80 );
|
||||
lfoAmtKnob->setVolumeKnob(true);
|
||||
lfoAmtKnob->setModel( &controls->m_lfoAmmountModel);
|
||||
lfoAmtKnob->setModel( &controls->m_lfoAmountModel);
|
||||
lfoAmtKnob->setLabel( tr( "Lfo Amt" ) );
|
||||
lfoAmtKnob->setHintText( tr ( "Lfo Amt:" ) + " ", "");
|
||||
|
||||
|
||||
@@ -51,12 +51,14 @@ DelayEffect::DelayEffect( Model* parent, const Plugin::Descriptor::SubPluginFeat
|
||||
m_delayControls( this )
|
||||
{
|
||||
m_delay = 0;
|
||||
m_delay = new StereoDelay( engine::mixer()->processingSampleRate()* 20 );
|
||||
m_delay = new StereoDelay( 192000 * 20 );
|
||||
m_lfo = new Lfo( engine::mixer()->processingSampleRate() );
|
||||
connect( engine::mixer(), SIGNAL( sampleRateChanged() ), this, SLOT( sampleRateChanged() ) );
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
DelayEffect::~DelayEffect()
|
||||
{
|
||||
if( m_delay )
|
||||
@@ -81,16 +83,16 @@ bool DelayEffect::processAudioBuffer(sampleFrame* buf, const fpp_t frames)
|
||||
double outSum = 0.0;
|
||||
const float d = dryLevel();
|
||||
const float w = wetLevel();
|
||||
m_lfo->setAmplitude( m_delayControls.m_lfoAmountModel.value() );
|
||||
m_lfo->setFrequency( 1.0 / m_delayControls.m_lfoTimeModel.value() );
|
||||
m_delay->setFeedback( m_delayControls.m_feedbackModel.value() );
|
||||
sample_t dryS[2];
|
||||
for( fpp_t f = 0; f < frames; ++f )
|
||||
{
|
||||
dryS[0] = buf[f][0];
|
||||
dryS[1] = buf[f][1];
|
||||
m_lfo->setAmplitude( m_delayControls.m_lfoAmmountModel.value( f ) );
|
||||
m_lfo->setFrequency( 1.0 / m_delayControls.m_lfoTimeModel.value( f ) );
|
||||
m_delay->setLength( m_delayControls.m_delayTimeModel.value(f) * engine::mixer()->processingSampleRate() * m_lfo->tick() );
|
||||
m_delay->setFeedback( m_delayControls.m_feebackModel.value( f ) );
|
||||
m_delay->tick( &buf[f][0], &buf[f][1] );
|
||||
m_delay->tick( buf[f] );
|
||||
|
||||
buf[f][0] = ( d * dryS[0] ) + ( w * buf[f][0] );
|
||||
buf[f][1] = ( d * dryS[1] ) + ( w * buf[f][1] );
|
||||
@@ -102,6 +104,15 @@ bool DelayEffect::processAudioBuffer(sampleFrame* buf, const fpp_t frames)
|
||||
|
||||
|
||||
|
||||
|
||||
void DelayEffect::sampleRateChanged()
|
||||
{
|
||||
m_lfo->setSamplerate(engine::mixer()->processingSampleRate());
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
extern "C"
|
||||
{
|
||||
|
||||
|
||||
@@ -40,6 +40,10 @@ public:
|
||||
{
|
||||
return &m_delayControls;
|
||||
}
|
||||
|
||||
private slots:
|
||||
void sampleRateChanged();
|
||||
|
||||
private:
|
||||
DelayControls m_delayControls;
|
||||
StereoDelay* m_delay;
|
||||
|
||||
@@ -23,7 +23,7 @@
|
||||
*/
|
||||
|
||||
#include "lfo.h"
|
||||
#include <math.h>
|
||||
#include "lmms_math.h"
|
||||
|
||||
|
||||
|
||||
@@ -31,31 +31,7 @@
|
||||
Lfo::Lfo( int samplerate )
|
||||
{
|
||||
m_samplerate = samplerate;
|
||||
m_twoPiOverSr = TWOPI / samplerate;
|
||||
}
|
||||
|
||||
|
||||
|
||||
void Lfo::setFrequency( double frequency )
|
||||
{
|
||||
if( frequency < 0 || frequency > ( m_samplerate / 2.0 ) || frequency == m_frequency )
|
||||
{
|
||||
return;
|
||||
}
|
||||
m_frequency = frequency;
|
||||
m_increment = m_frequency * m_twoPiOverSr;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
void Lfo::setAmplitude( float amplitude )
|
||||
{
|
||||
if( amplitude < 0.0 || amplitude > 1.0 )
|
||||
{
|
||||
return;
|
||||
}
|
||||
m_amplitude = amplitude;
|
||||
m_twoPiOverSr = F_2PI / samplerate;
|
||||
}
|
||||
|
||||
|
||||
@@ -63,15 +39,12 @@ void Lfo::setAmplitude( float amplitude )
|
||||
|
||||
float Lfo::tick()
|
||||
{
|
||||
float output = ( float )sin( m_phase );
|
||||
float output = sinf( m_phase );
|
||||
m_phase += m_increment;
|
||||
if( m_phase >= TWOPI )
|
||||
{
|
||||
m_phase -= TWOPI;
|
||||
}
|
||||
|
||||
if( m_amplitude > 0.0001 )
|
||||
{
|
||||
return ( ( output + 1.0 ) / 2.0 ) * m_amplitude;
|
||||
return ( ( output + 1.0 ) * 0.5 ) * m_amplitude;
|
||||
} else
|
||||
{
|
||||
return 1;
|
||||
|
||||
@@ -25,10 +25,7 @@
|
||||
#ifndef LFO_H
|
||||
#define LFO_H
|
||||
|
||||
#ifndef M_PI
|
||||
#define M_PI (3.14159265358979321 )
|
||||
#endif
|
||||
#define TWOPI ( 2.0 * M_PI )
|
||||
#include "lmms_math.h"
|
||||
|
||||
class Lfo
|
||||
{
|
||||
@@ -37,8 +34,50 @@ public:
|
||||
~Lfo()
|
||||
{
|
||||
}
|
||||
void setFrequency( double frequency );
|
||||
void setAmplitude( float amplitude );
|
||||
|
||||
|
||||
|
||||
|
||||
inline void setFrequency( double frequency )
|
||||
{
|
||||
if( frequency < 0 || frequency > ( m_samplerate / 2.0 ) || frequency == m_frequency )
|
||||
{
|
||||
return;
|
||||
}
|
||||
m_frequency = frequency;
|
||||
m_increment = m_frequency * m_twoPiOverSr;
|
||||
|
||||
if( m_phase >= F_2PI )
|
||||
{
|
||||
m_phase -= F_2PI;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
inline void setAmplitude( float amplitude )
|
||||
{
|
||||
if( amplitude < 0.0 || amplitude > 1.0 )
|
||||
{
|
||||
return;
|
||||
}
|
||||
m_amplitude = amplitude;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
inline void setSamplerate ( int samplerate )
|
||||
{
|
||||
m_samplerate = samplerate;
|
||||
m_twoPiOverSr = F_2PI / samplerate;
|
||||
m_increment = m_frequency * m_twoPiOverSr;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
float tick();
|
||||
|
||||
private:
|
||||
|
||||
@@ -24,17 +24,18 @@
|
||||
|
||||
#include "stereodelay.h"
|
||||
#include <cstdlib>
|
||||
#include "lmms_basics.h"
|
||||
|
||||
|
||||
StereoDelay::StereoDelay(int maxLength)
|
||||
StereoDelay::StereoDelay( int maxLength )
|
||||
{
|
||||
m_buffer = 0;
|
||||
m_buffer = ( float* )malloc(maxLength*2*sizeof( float ) );
|
||||
m_buffer = new sampleFrame[maxLength];
|
||||
m_maxLength = maxLength;
|
||||
m_length = m_maxLength;
|
||||
m_index = 0;
|
||||
m_feedback = 0.0f;
|
||||
setLength( 0 );
|
||||
// setLength( 0 );
|
||||
}
|
||||
|
||||
|
||||
@@ -44,53 +45,23 @@ StereoDelay::~StereoDelay()
|
||||
{
|
||||
if( m_buffer )
|
||||
{
|
||||
free( m_buffer );
|
||||
delete m_buffer;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
void StereoDelay::setLength( int length )
|
||||
sampleFrame oldFrame;
|
||||
void StereoDelay::tick( sampleFrame frame )
|
||||
{
|
||||
if( length <= m_maxLength && length >= 0 )
|
||||
{
|
||||
if( length < m_length )
|
||||
{
|
||||
for( int i = length * 2; i < m_length *2; i++)
|
||||
{
|
||||
m_buffer[i] = 0.0f;
|
||||
}
|
||||
}
|
||||
m_length = length;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
void StereoDelay::setFeedback( float feedback )
|
||||
{
|
||||
m_feedback = feedback;
|
||||
}
|
||||
|
||||
|
||||
|
||||
float m_oldLeft;
|
||||
float m_oldRight;
|
||||
void StereoDelay::tick( float* left, float* right )
|
||||
{
|
||||
m_oldLeft = m_buffer[m_index];
|
||||
m_oldRight = m_buffer[m_index+1];
|
||||
m_buffer[m_index] = *left + ( m_oldLeft * m_feedback );
|
||||
m_buffer[m_index+1] = *right + ( m_oldRight * m_feedback );
|
||||
*left = m_oldLeft;
|
||||
*right = m_oldRight;
|
||||
m_index++; m_index++;
|
||||
if( m_index > m_length )
|
||||
{
|
||||
m_index = 0;
|
||||
}
|
||||
oldFrame[0] = m_buffer[m_index][0];
|
||||
oldFrame[1] = m_buffer[m_index][1];
|
||||
m_buffer[m_index][0] = frame[0] + ( oldFrame[0] * m_feedback );
|
||||
m_buffer[m_index][1] = frame[1] + ( oldFrame[1] * m_feedback );
|
||||
frame[0] = oldFrame[0];
|
||||
frame[1] = oldFrame[1];
|
||||
m_index = m_index + 1 < m_length ? m_index + 1 : 0;
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -25,16 +25,29 @@
|
||||
#ifndef STEREODELAY_H
|
||||
#define STEREODELAY_H
|
||||
|
||||
#include "lmms_basics.h"
|
||||
|
||||
class StereoDelay
|
||||
{
|
||||
public:
|
||||
StereoDelay( int maxLength );
|
||||
~StereoDelay();
|
||||
void setLength( int length );
|
||||
void setFeedback( float feedback );
|
||||
void tick( float* left, float* right );
|
||||
inline void setLength( int length )
|
||||
{
|
||||
if( length <= m_maxLength && length >= 0 )
|
||||
{
|
||||
m_length = length;
|
||||
}
|
||||
}
|
||||
|
||||
inline void setFeedback( float feedback )
|
||||
{
|
||||
m_feedback = feedback;
|
||||
}
|
||||
|
||||
void tick( sampleFrame frame );
|
||||
private:
|
||||
float *m_buffer;
|
||||
sampleFrame* m_buffer;
|
||||
int m_maxLength;
|
||||
int m_length;
|
||||
int m_index;
|
||||
|
||||
Reference in New Issue
Block a user