mirror of
https://github.com/LMMS/lmms.git
synced 2025-12-24 07:08:28 -05:00
ValueBuffer related cleanups
* Move implementation to a new cpp file * Use std::vector as base class instead of doing our own memory management * Remove unused dangerous functions * Make more use of std algorithms * Some cleanups in code using ValueBuffer
This commit is contained in:
@@ -25,12 +25,10 @@
|
||||
#ifndef EDITOR_COMMON_H
|
||||
#define EDITOR_COMMON_H
|
||||
|
||||
#include <QAction>
|
||||
#include <QMainWindow>
|
||||
#include <QToolBar>
|
||||
|
||||
#include "TimeLineWidget.h"
|
||||
#include "ToolButton.h"
|
||||
class QAction;
|
||||
|
||||
class DropToolBar;
|
||||
|
||||
|
||||
@@ -31,133 +31,23 @@
|
||||
#include <string.h>
|
||||
#include "MemoryManager.h"
|
||||
|
||||
class ValueBuffer
|
||||
class ValueBuffer : public std::vector<float>
|
||||
{
|
||||
MM_OPERATORS
|
||||
public:
|
||||
ValueBuffer()
|
||||
{
|
||||
m_values = NULL;
|
||||
m_length = 0;
|
||||
}
|
||||
ValueBuffer();
|
||||
ValueBuffer(int length);
|
||||
|
||||
void fill(float value);
|
||||
|
||||
float value(int offset ) const;
|
||||
|
||||
const float * values() const;
|
||||
float * values();
|
||||
|
||||
ValueBuffer( int length )
|
||||
{
|
||||
m_values = new float[length];
|
||||
m_length = length;
|
||||
}
|
||||
int length() const;
|
||||
|
||||
ValueBuffer( float * values, int length )
|
||||
{
|
||||
m_values = new float[length];
|
||||
m_length = length;
|
||||
memcpy( m_values, values, sizeof(float) * length );
|
||||
}
|
||||
|
||||
ValueBuffer( float value, int length )
|
||||
{
|
||||
m_values = new float[length];
|
||||
m_length = length;
|
||||
for( int i = 0; i < length; i++ )
|
||||
{
|
||||
m_values[i] = value;
|
||||
}
|
||||
}
|
||||
|
||||
virtual ~ValueBuffer()
|
||||
{
|
||||
delete[] m_values;
|
||||
}
|
||||
|
||||
void clear()
|
||||
{
|
||||
delete[] m_values;
|
||||
m_values = NULL;
|
||||
m_length = 0;
|
||||
}
|
||||
|
||||
void fill( float value )
|
||||
{
|
||||
for( int i = 0; i < m_length; i++ )
|
||||
{
|
||||
m_values[i] = value;
|
||||
}
|
||||
}
|
||||
|
||||
float value( int offset ) const
|
||||
{
|
||||
return m_values[ offset % m_length ];
|
||||
}
|
||||
|
||||
void setValue( int offset, float value )
|
||||
{
|
||||
m_values[ offset % m_length ] = value;
|
||||
}
|
||||
|
||||
float * values() const
|
||||
{
|
||||
return m_values;
|
||||
}
|
||||
|
||||
void setValues( float * values )
|
||||
{
|
||||
m_values = values;
|
||||
}
|
||||
|
||||
int length() const
|
||||
{
|
||||
return m_length;
|
||||
}
|
||||
|
||||
void setLength( const int length )
|
||||
{
|
||||
m_length = length;
|
||||
}
|
||||
|
||||
void interpolate( float start, float end )
|
||||
{
|
||||
float f = 0.0f;
|
||||
const float fstep = 1.0f / static_cast<float>( m_length );
|
||||
for( int i = 0; i < m_length; i++ )
|
||||
{
|
||||
f += fstep;
|
||||
m_values[i] = linearInterpolate( start, end, f );
|
||||
}
|
||||
}
|
||||
|
||||
void multiply( float f )
|
||||
{
|
||||
for( int i = 0; i < m_length; i++ )
|
||||
{
|
||||
m_values[i] *= f;
|
||||
}
|
||||
}
|
||||
|
||||
ValueBuffer & operator*=( const float & f )
|
||||
{
|
||||
multiply( f );
|
||||
return *this;
|
||||
}
|
||||
|
||||
ValueBuffer & operator+=( const ValueBuffer & v )
|
||||
{
|
||||
for( int i = 0; i < qMin( m_length, v.length() ); i++ )
|
||||
{
|
||||
m_values[i] += v.values()[i];
|
||||
}
|
||||
return *this;
|
||||
}
|
||||
|
||||
static ValueBuffer interpolatedBuffer( float start, float end, int length )
|
||||
{
|
||||
ValueBuffer vb = ValueBuffer( length );
|
||||
vb.interpolate( start, end );
|
||||
return vb;
|
||||
}
|
||||
|
||||
private:
|
||||
float * m_values;
|
||||
int m_length;
|
||||
void interpolate(float start, float end);
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
@@ -75,10 +75,10 @@ bool AmplifierEffect::processAudioBuffer( sampleFrame* buf, const fpp_t frames )
|
||||
const float d = dryLevel();
|
||||
const float w = wetLevel();
|
||||
|
||||
ValueBuffer * volBuf = m_ampControls.m_volumeModel.valueBuffer();
|
||||
ValueBuffer * panBuf = m_ampControls.m_panModel.valueBuffer();
|
||||
ValueBuffer * leftBuf = m_ampControls.m_leftModel.valueBuffer();
|
||||
ValueBuffer * rightBuf = m_ampControls.m_rightModel.valueBuffer();
|
||||
const ValueBuffer * volBuf = m_ampControls.m_volumeModel.valueBuffer();
|
||||
const ValueBuffer * panBuf = m_ampControls.m_panModel.valueBuffer();
|
||||
const ValueBuffer * leftBuf = m_ampControls.m_leftModel.valueBuffer();
|
||||
const ValueBuffer * rightBuf = m_ampControls.m_rightModel.valueBuffer();
|
||||
|
||||
for( fpp_t f = 0; f < frames; ++f )
|
||||
{
|
||||
@@ -90,8 +90,8 @@ bool AmplifierEffect::processAudioBuffer( sampleFrame* buf, const fpp_t frames )
|
||||
// vol knob
|
||||
if( volBuf )
|
||||
{
|
||||
s[0] *= volBuf->values()[ f ] * 0.01f;
|
||||
s[1] *= volBuf->values()[ f ] * 0.01f;
|
||||
s[0] *= volBuf->value( f ) * 0.01f;
|
||||
s[1] *= volBuf->value( f ) * 0.01f;
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -101,7 +101,7 @@ bool AmplifierEffect::processAudioBuffer( sampleFrame* buf, const fpp_t frames )
|
||||
|
||||
// convert pan values to left/right values
|
||||
const float pan = panBuf
|
||||
? panBuf->values()[ f ]
|
||||
? panBuf->value( f )
|
||||
: m_ampControls.m_panModel.value();
|
||||
const float left1 = pan <= 0
|
||||
? 1.0
|
||||
@@ -112,10 +112,10 @@ bool AmplifierEffect::processAudioBuffer( sampleFrame* buf, const fpp_t frames )
|
||||
|
||||
// second stage amplification
|
||||
const float left2 = leftBuf
|
||||
? leftBuf->values()[ f ]
|
||||
? leftBuf->value( f )
|
||||
: m_ampControls.m_leftModel.value();
|
||||
const float right2 = rightBuf
|
||||
? rightBuf->values()[ f ]
|
||||
? rightBuf->value( f )
|
||||
: m_ampControls.m_rightModel.value();
|
||||
|
||||
s[0] *= left1 * left2 * 0.01;
|
||||
|
||||
@@ -83,45 +83,30 @@ bool BassBoosterEffect::processAudioBuffer( sampleFrame* buf, const fpp_t frames
|
||||
if( m_bbControls.m_gainModel.isValueChanged() ) { changeGain(); }
|
||||
if( m_bbControls.m_ratioModel.isValueChanged() ) { changeRatio(); }
|
||||
|
||||
float gain = m_bbControls.m_gainModel.value();
|
||||
ValueBuffer *gainBuffer = m_bbControls.m_gainModel.valueBuffer();
|
||||
int gainInc = gainBuffer ? 1 : 0;
|
||||
float *gainPtr = gainBuffer ? &( gainBuffer->values()[ 0 ] ) : &gain;
|
||||
const float const_gain = m_bbControls.m_gainModel.value();
|
||||
const ValueBuffer *gainBuffer = m_bbControls.m_gainModel.valueBuffer();
|
||||
|
||||
double outSum = 0.0;
|
||||
const float d = dryLevel();
|
||||
const float w = wetLevel();
|
||||
if( gainBuffer )
|
||||
|
||||
for( fpp_t f = 0; f < frames; ++f )
|
||||
{
|
||||
//process period using sample exact data
|
||||
for( fpp_t f = 0; f < frames; ++f )
|
||||
{
|
||||
m_bbFX.leftFX().setGain( *gainPtr );
|
||||
m_bbFX.rightFX().setGain( *gainPtr );
|
||||
outSum += buf[f][0]*buf[f][0] + buf[f][1]*buf[f][1];
|
||||
|
||||
sample_t s[2] = { buf[f][0], buf[f][1] };
|
||||
m_bbFX.nextSample( s[0], s[1] );
|
||||
|
||||
buf[f][0] = d * buf[f][0] + w * s[0];
|
||||
buf[f][1] = d * buf[f][1] + w * s[1];
|
||||
gainPtr += gainInc;
|
||||
float gain = const_gain;
|
||||
if (gainBuffer) {
|
||||
//process period using sample exact data
|
||||
gain = gainBuffer->value( f );
|
||||
}
|
||||
} else
|
||||
{
|
||||
//process period without sample exact data
|
||||
m_bbFX.leftFX().setGain( *gainPtr );
|
||||
m_bbFX.rightFX().setGain( *gainPtr );
|
||||
for( fpp_t f = 0; f < frames; ++f )
|
||||
{
|
||||
outSum += buf[f][0]*buf[f][0] + buf[f][1]*buf[f][1];
|
||||
//float gain = gainBuffer ? gainBuffer[f] : gain;
|
||||
m_bbFX.leftFX().setGain( const_gain );
|
||||
m_bbFX.rightFX().setGain( const_gain);
|
||||
outSum += buf[f][0]*buf[f][0] + buf[f][1]*buf[f][1];
|
||||
|
||||
sample_t s[2] = { buf[f][0], buf[f][1] };
|
||||
m_bbFX.nextSample( s[0], s[1] );
|
||||
sample_t s[2] = { buf[f][0], buf[f][1] };
|
||||
m_bbFX.nextSample( s[0], s[1] );
|
||||
|
||||
buf[f][0] = d * buf[f][0] + w * s[0];
|
||||
buf[f][1] = d * buf[f][1] + w * s[1];
|
||||
}
|
||||
buf[f][0] = d * buf[f][0] + w * s[0];
|
||||
buf[f][1] = d * buf[f][1] + w * s[1];
|
||||
}
|
||||
|
||||
checkGate( outSum / frames );
|
||||
|
||||
@@ -93,8 +93,8 @@ bool waveShaperEffect::processAudioBuffer( sampleFrame * _buf,
|
||||
int inputInc = inputBuffer ? 1 : 0;
|
||||
int outputInc = outputBufer ? 1 : 0;
|
||||
|
||||
float *inputPtr = inputBuffer ? &( inputBuffer->values()[ 0 ] ) : &input;
|
||||
float *outputPtr = outputBufer ? &( outputBufer->values()[ 0 ] ) : &output;
|
||||
const float *inputPtr = inputBuffer ? &( inputBuffer->values()[ 0 ] ) : &input;
|
||||
const float *outputPtr = outputBufer ? &( outputBufer->values()[ 0 ] ) : &output;
|
||||
|
||||
for( fpp_t f = 0; f < _frames; ++f )
|
||||
{
|
||||
|
||||
@@ -63,6 +63,7 @@ set(LMMS_SRCS
|
||||
core/ToolPlugin.cpp
|
||||
core/Track.cpp
|
||||
core/TrackContainer.cpp
|
||||
core/ValueBuffer.cpp
|
||||
core/VstSyncController.cpp
|
||||
|
||||
core/audio/AudioAlsa.cpp
|
||||
|
||||
@@ -136,11 +136,7 @@ ValueBuffer * Controller::valueBuffer()
|
||||
|
||||
void Controller::updateValueBuffer()
|
||||
{
|
||||
float * values = m_valueBuffer.values();
|
||||
for( int i = 0; i < m_valueBuffer.length(); i++ )
|
||||
{
|
||||
values[i] = 0.5f;
|
||||
}
|
||||
m_valueBuffer.fill(0.5f);
|
||||
m_bufferLastUpdated = s_periods;
|
||||
}
|
||||
|
||||
|
||||
@@ -86,7 +86,6 @@ LfoController::~LfoController()
|
||||
void LfoController::updateValueBuffer()
|
||||
{
|
||||
m_phaseOffset = m_phaseModel.value() / 360.0;
|
||||
float * values = m_valueBuffer.values();
|
||||
float phase = m_currentPhase + m_phaseOffset;
|
||||
|
||||
// roll phase up until we're in sync with period counter
|
||||
@@ -103,13 +102,13 @@ void LfoController::updateValueBuffer()
|
||||
int amountInc = amountBuffer ? 1 : 0;
|
||||
float *amountPtr = amountBuffer ? &(amountBuffer->values()[ 0 ] ) : &amount;
|
||||
|
||||
for( int i = 0; i < m_valueBuffer.length(); i++ )
|
||||
for( float& f : m_valueBuffer )
|
||||
{
|
||||
const float currentSample = m_sampleFunction != NULL
|
||||
? m_sampleFunction( phase )
|
||||
: m_userDefSampleBuffer->userWaveSample( phase );
|
||||
|
||||
values[i] = qBound( 0.0f, m_baseModel.value() + ( *amountPtr * currentSample / 2.0f ), 1.0f );
|
||||
f = qBound( 0.0f, m_baseModel.value() + ( *amountPtr * currentSample / 2.0f ), 1.0f );
|
||||
|
||||
phase += 1.0 / m_duration;
|
||||
amountPtr += amountInc;
|
||||
|
||||
41
src/core/ValueBuffer.cpp
Normal file
41
src/core/ValueBuffer.cpp
Normal file
@@ -0,0 +1,41 @@
|
||||
#include "ValueBuffer.h"
|
||||
|
||||
ValueBuffer::ValueBuffer()
|
||||
{}
|
||||
|
||||
ValueBuffer::ValueBuffer(int length)
|
||||
: std::vector<float>(length)
|
||||
{}
|
||||
|
||||
void ValueBuffer::fill(float value)
|
||||
{
|
||||
std::fill(begin(), end(), value);
|
||||
}
|
||||
|
||||
float ValueBuffer::value(int offset) const
|
||||
{
|
||||
return at(offset % length());
|
||||
}
|
||||
|
||||
const float *ValueBuffer::values() const
|
||||
{
|
||||
return data();
|
||||
}
|
||||
|
||||
float *ValueBuffer::values()
|
||||
{
|
||||
return data();
|
||||
}
|
||||
|
||||
int ValueBuffer::length() const
|
||||
{
|
||||
return size();
|
||||
}
|
||||
|
||||
void ValueBuffer::interpolate(float start, float end_)
|
||||
{
|
||||
float i = 0;
|
||||
std::generate(begin(), end(), [&]() {
|
||||
return linearInterpolate( start, end_, i++ / length());
|
||||
});
|
||||
}
|
||||
@@ -38,6 +38,8 @@
|
||||
#include "TextFloat.h"
|
||||
#include "ToolTip.h"
|
||||
|
||||
#include "Engine.h"
|
||||
|
||||
|
||||
QPixmap * AutomationPatternView::s_pat_rec = NULL;
|
||||
|
||||
|
||||
@@ -24,6 +24,8 @@
|
||||
|
||||
#include "Editor.h"
|
||||
|
||||
#include "Song.h"
|
||||
|
||||
#include "MainWindow.h"
|
||||
#include "embed.h"
|
||||
|
||||
|
||||
@@ -64,7 +64,6 @@
|
||||
#include "Pattern.h"
|
||||
#include "Piano.h"
|
||||
#include "PixmapButton.h"
|
||||
#include "Song.h"
|
||||
#include "SongEditor.h"
|
||||
#include "templates.h"
|
||||
#include "TextFloat.h"
|
||||
|
||||
Reference in New Issue
Block a user