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:
dave
2014-11-16 15:02:15 +00:00
parent 6d2b91054b
commit 4c82ba22a9
10 changed files with 115 additions and 104 deletions

View File

@@ -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&apos;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>

View File

@@ -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"

View File

@@ -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;

View File

@@ -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:" ) + " ", "");

View File

@@ -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"
{

View File

@@ -40,6 +40,10 @@ public:
{
return &m_delayControls;
}
private slots:
void sampleRateChanged();
private:
DelayControls m_delayControls;
StereoDelay* m_delay;

View File

@@ -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;

View File

@@ -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:

View File

@@ -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;
}

View File

@@ -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;