diff --git a/CMakeLists.txt b/CMakeLists.txt
index 61ca5a66a..4e2109d68 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -15,7 +15,7 @@ INCLUDE(FindPkgConfig)
SET(VERSION_MAJOR "1")
SET(VERSION_MINOR "0")
-SET(VERSION_PATCH "98")
+SET(VERSION_PATCH "100")
#SET(VERSION_SUFFIX "")
SET(VERSION "${VERSION_MAJOR}.${VERSION_MINOR}.${VERSION_PATCH}")
IF(VERSION_SUFFIX)
diff --git a/data/presets/Kicker/Kick power.xpf b/data/presets/Kicker/KickPower.xpf
similarity index 54%
rename from data/presets/Kicker/Kick power.xpf
rename to data/presets/Kicker/KickPower.xpf
index b4e1daba3..27259ce25 100644
--- a/data/presets/Kicker/Kick power.xpf
+++ b/data/presets/Kicker/KickPower.xpf
@@ -1,20 +1,20 @@
-
+
-
+
-
+
-
-
-
-
+
+
+
+
-
-
-
+
+
+
diff --git a/data/presets/Kicker/SnareMarch.xpf b/data/presets/Kicker/SnareMarch.xpf
new file mode 100644
index 000000000..d4d1ad0db
--- /dev/null
+++ b/data/presets/Kicker/SnareMarch.xpf
@@ -0,0 +1,161 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/data/presets/Kicker/TR909-RimShot.xpf b/data/presets/Kicker/TR909-RimShot.xpf
new file mode 100644
index 000000000..e8626db29
--- /dev/null
+++ b/data/presets/Kicker/TR909-RimShot.xpf
@@ -0,0 +1,21 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/include/AutomatableSlider.h b/include/AutomatableSlider.h
index 1cd1405b1..7627ddd95 100644
--- a/include/AutomatableSlider.h
+++ b/include/AutomatableSlider.h
@@ -1,5 +1,5 @@
/*
- * AutomatableSlider.h - class automatableSlider, a QSlider with automation
+ * AutomatableSlider.h - class AutomatableSlider, a QSlider with automation
*
* Copyright (c) 2006-2008 Javier Serrano Polo
*
diff --git a/include/BasicFilters.h b/include/BasicFilters.h
index cd4687ef0..e6dfbcbe3 100644
--- a/include/BasicFilters.h
+++ b/include/BasicFilters.h
@@ -75,68 +75,69 @@ public:
inline void setCoeffs( float freq )
{
// wc
- const float wc = F_2PI * freq;
- const float wc2 = wc * wc;
- const float wc3 = wc2 * wc;
+ const double wc = D_2PI * freq;
+ const double wc2 = wc * wc;
+ const double wc3 = wc2 * wc;
m_wc4 = wc2 * wc2;
// k
- const float k = wc / tanf( F_PI * freq / m_sampleRate );
- const float k2 = k * k;
- const float k3 = k2 * k;
+ const double k = wc / tan( D_PI * freq / m_sampleRate );
+ const double k2 = k * k;
+ const double k3 = k2 * k;
m_k4 = k2 * k2;
// a
- static const float sqrt2 = sqrtf( 2.0f );
- const float sq_tmp1 = sqrt2 * wc3 * k;
- const float sq_tmp2 = sqrt2 * wc * k3;
- m_a = 4.0f * wc2 * k2 + 2.0f * sq_tmp1 + m_k4 + 2.0f * sq_tmp2 + m_wc4;
+ static const double sqrt2 = sqrt( 2.0 );
+ const double sq_tmp1 = sqrt2 * wc3 * k;
+ const double sq_tmp2 = sqrt2 * wc * k3;
+
+ m_a = 1.0 / ( 4.0 * wc2 * k2 + 2.0 * sq_tmp1 + m_k4 + 2.0 * sq_tmp2 + m_wc4 );
// b
- m_b1 = ( 4.0f * ( m_wc4 + sq_tmp1 - m_k4 - sq_tmp2 ) ) / m_a;
- m_b2 = ( 6.0f * m_wc4 - 8.0f * wc2 * k2 + 6.0f * m_k4 ) / m_a;
- m_b3 = ( 4.0f * ( m_wc4 - sq_tmp1 + sq_tmp2 - m_k4 ) ) / m_a;
- m_b4 = ( m_k4 - 2.0f * sq_tmp1 + m_wc4 - 2.0f * sq_tmp2 + 4.0f * wc2 * k2 ) / m_a;
+ m_b1 = ( 4.0 * ( m_wc4 + sq_tmp1 - m_k4 - sq_tmp2 ) ) * m_a;
+ m_b2 = ( 6.0 * m_wc4 - 8.0 * wc2 * k2 + 6.0 * m_k4 ) * m_a;
+ m_b3 = ( 4.0 * ( m_wc4 - sq_tmp1 + sq_tmp2 - m_k4 ) ) * m_a;
+ m_b4 = ( m_k4 - 2.0 * sq_tmp1 + m_wc4 - 2.0 * sq_tmp2 + 4.0 * wc2 * k2 ) * m_a;
}
inline void setLowpass( float freq )
{
setCoeffs( freq );
- m_a0 = m_wc4 / m_a;
- m_a1 = 4.0f * m_a0;
- m_a2 = 6.0f * m_a0;
+ m_a0 = m_wc4 * m_a;
+ m_a1 = 4.0 * m_a0;
+ m_a2 = 6.0 * m_a0;
}
inline void setHighpass( float freq )
{
setCoeffs( freq );
- m_a0 = m_k4 / m_a;
- m_a1 = 4.0f * m_a0;
- m_a2 = 6.0f * m_a0;
+ m_a0 = m_k4 * m_a;
+ m_a1 = -4.0 * m_a0;
+ m_a2 = 6.0 * m_a0;
}
inline float update( float in, ch_cnt_t ch )
{
- const float a0in = m_a0 * in;
- const float a1in = m_a1 * in;
- const float out = m_z1[ch] + a0in;
+ const double x = in - ( m_z1[ch] * m_b1 ) - ( m_z2[ch] * m_b2 ) -
+ ( m_z3[ch] * m_b3 ) - ( m_z4[ch] * m_b4 );
+ const double y = ( m_a0 * x ) + ( m_z1[ch] * m_a1 ) + ( m_z2[ch] * m_a2 ) +
+ ( m_z3[ch] * m_a1 ) + ( m_z4[ch] * m_a0 );
+ m_z4[ch] = m_z3[ch];
+ m_z3[ch] = m_z2[ch];
+ m_z2[ch] = m_z1[ch];
+ m_z1[ch] = x;
- m_z1[ch] = a1in + m_z2[ch] - ( m_b1 * out );
- m_z2[ch] = ( m_a2 * in ) + m_z3[ch] - ( m_b2 * out );
- m_z3[ch] = a1in + m_z4[ch] - ( m_b3 * out );
- m_z4[ch] = a0in - ( m_b4 * out );
-
- return out;
+ return y;
}
private:
float m_sampleRate;
- float m_wc4;
- float m_k4;
- float m_a, m_a0, m_a1, m_a2;
- float m_b1, m_b2, m_b3, m_b4;
+ double m_wc4;
+ double m_k4;
+ double m_a, m_a0, m_a1, m_a2;
+ double m_b1, m_b2, m_b3, m_b4;
- typedef float frame[CHANNELS];
+ typedef double frame[CHANNELS];
frame m_z1, m_z2, m_z3, m_z4;
};
typedef LinkwitzRiley<2> StereoLinkwitzRiley;
@@ -289,7 +290,6 @@ public:
m_sampleRatio( 1.0f / m_sampleRate ),
m_subFilter( NULL )
{
- m_svsr = 1.0f - expf( -4646.39874051f / m_sampleRate );
clearHistory();
}
@@ -326,7 +326,6 @@ public:
m_delay2[_chnl] = 0.0f;
m_delay3[_chnl] = 0.0f;
m_delay4[_chnl] = 0.0f;
- m_sva[_chnl] = 0.0f;
}
}
@@ -409,7 +408,6 @@ public:
case Lowpass_SV:
case Bandpass_SV:
{
- m_sva[_chnl] += ( qAbs( _in0 ) - m_sva[_chnl] ) * m_svsr;
float highpass;
for( int i = 0; i < 2; ++i ) // 2x oversample
@@ -425,14 +423,13 @@ public:
/* mix filter output into output buffer */
return m_type == Lowpass_SV
- ? atanf( 3.0f * m_delay4[_chnl] * m_sva[_chnl] )
- : atanf( 3.0f * m_delay3[_chnl] * m_sva[_chnl] );
+ ? m_delay4[_chnl]
+ : m_delay3[_chnl];
break;
}
case Highpass_SV:
{
- m_sva[_chnl] += ( qAbs( _in0 ) - m_sva[_chnl] ) * m_svsr;
float hp;
for( int i = 0; i < 2; ++i ) // 2x oversample
@@ -442,13 +439,12 @@ public:
m_delay1[_chnl] = m_svf1 * hp + m_delay1[_chnl];
}
- return atanf( 3.0f * hp * m_sva[_chnl] );
+ return hp;
break;
}
case Notch_SV:
{
- m_sva[_chnl] += ( qAbs( _in0 ) - m_sva[_chnl] ) * m_svsr;
float hp1, hp2;
for( int i = 0; i < 2; ++i ) // 2x oversample
@@ -463,7 +459,7 @@ public:
}
/* mix filter output into output buffer */
- return atanf( 1.5f * ( m_delay4[_chnl] + hp1 ) * m_sva[_chnl] );
+ return m_delay4[_chnl] + hp1;
break;
}
@@ -899,7 +895,7 @@ private:
float m_vfa[4], m_vfb[4], m_vfc[4], m_vfq;
// coeffs for Lowpass_SV (state-variant lowpass)
- float m_svf1, m_svf2, m_svq, m_svsr;
+ float m_svf1, m_svf2, m_svq;
typedef sample_t frame[CHANNELS];
@@ -916,7 +912,7 @@ private:
frame m_vfbp[6], m_vfhp[6], m_vflast[6];
// in/out history for Lowpass_SV (state-variant lowpass)
- frame m_delay1, m_delay2, m_delay3, m_delay4, m_sva;
+ frame m_delay1, m_delay2, m_delay3, m_delay4;
FilterTypes m_type;
bool m_doubleFilter;
diff --git a/include/Fader.h b/include/Fader.h
index efbc4ebf1..3e808802a 100644
--- a/include/Fader.h
+++ b/include/Fader.h
@@ -57,13 +57,14 @@
class TextFloat;
-class Fader : public QWidget, public FloatModelView
+class EXPORT Fader : public QWidget, public FloatModelView
{
Q_OBJECT
public:
Q_PROPERTY( QColor peakGreen READ peakGreen WRITE setPeakGreen )
Q_PROPERTY( QColor peakRed READ peakRed WRITE setPeakRed )
Fader( FloatModel * _model, const QString & _name, QWidget * _parent );
+ Fader( FloatModel * _model, const QString & _name, QWidget * _parent, QPixmap * back, QPixmap * leds, QPixmap * knob );
virtual ~Fader();
void setPeak_L( float fPeak );
@@ -76,6 +77,17 @@ public:
QColor peakRed() const;
void setPeakGreen( const QColor & c );
void setPeakRed( const QColor & c );
+
+ void setDisplayConversion( bool b )
+ {
+ m_displayConversion = b;
+ }
+ inline void setHintText( const QString & _txt_before,
+ const QString & _txt_after )
+ {
+ setDescription( _txt_before );
+ setUnit( _txt_after );
+ }
private:
virtual void contextMenuEvent( QContextMenuEvent * _me );
@@ -91,7 +103,7 @@ private:
float fRange = m_model->maxValue() - m_model->minValue();
float realVal = m_model->value() - m_model->minValue();
- return height() - ( ( height() - ( *s_knob ).height() ) * ( realVal / fRange ) );
+ return height() - ( ( height() - m_knob->height() ) * ( realVal / fRange ) );
}
FloatModel * m_model;
@@ -112,6 +124,12 @@ private:
static QPixmap * s_back;
static QPixmap * s_leds;
static QPixmap * s_knob;
+
+ QPixmap * m_back;
+ QPixmap * m_leds;
+ QPixmap * m_knob;
+
+ bool m_displayConversion;
int m_moveStartPoint;
float m_startValue;
diff --git a/include/ProjectJournal.h b/include/ProjectJournal.h
index 20ff70959..5cb7920f6 100644
--- a/include/ProjectJournal.h
+++ b/include/ProjectJournal.h
@@ -74,7 +74,7 @@ public:
}
void clearJournal();
-
+ void stopAllJournalling();
JournallingObject * journallingObject( const jo_id_t _id )
{
if( m_joIDs.contains( _id ) )
diff --git a/include/Song.h b/include/Song.h
index d0dac5a9c..81f12303d 100644
--- a/include/Song.h
+++ b/include/Song.h
@@ -263,7 +263,7 @@ public slots:
void playAndRecord();
void playTrack( Track * _trackToPlay );
void playBB();
- void playPattern( Pattern* patternToPlay, bool _loop = true );
+ void playPattern(const Pattern* patternToPlay, bool _loop = true );
void togglePause();
void stop();
@@ -354,7 +354,7 @@ private:
tact_t m_length;
Track * m_trackToPlay;
- Pattern* m_patternToPlay;
+ const Pattern* m_patternToPlay;
bool m_loopPattern;
double m_elapsedMilliSeconds;
diff --git a/include/Track.h b/include/Track.h
index 8c7e05f23..396c41e52 100644
--- a/include/Track.h
+++ b/include/Track.h
@@ -468,7 +468,7 @@ public:
int numOfTCOs();
TrackContentObject * getTCO( int _tco_num );
- int getTCONum( TrackContentObject * _tco );
+ int getTCONum(const TrackContentObject* _tco );
const tcoVector & getTCOs() const
{
diff --git a/include/interpolation.h b/include/interpolation.h
index 113058e4f..cbe274d42 100644
--- a/include/interpolation.h
+++ b/include/interpolation.h
@@ -32,6 +32,7 @@
#include
#include "lmms_constants.h"
+#include "lmms_math.h"
inline float hermiteInterpolate( float x0, float x1, float x2, float x3,
float frac_pos )
@@ -80,24 +81,13 @@ inline float cubicInterpolate( float v0, float v1, float v2, float v3, float x )
inline float cosinusInterpolate( float v0, float v1, float x )
{
const float f = ( 1.0f - cosf( x * F_PI ) ) * 0.5f;
-#ifdef FP_FAST_FMAF
- return fmaf( f, v1-v0, v0 );
-#else
- return f * (v1-v0) + v0;
-#endif
-// return( v0*f + v1*( 1.0f-f ) );
+ return fastFmaf( f, v1-v0, v0 );
}
inline float linearInterpolate( float v0, float v1, float x )
{
-// take advantage of fma function if present in hardware
-
-#ifdef FP_FAST_FMAF
- return fmaf( x, v1-v0, v0 );
-#else
- return x * (v1-v0) + v0;
-#endif
+ return fastFmaf( x, v1-v0, v0 );
}
diff --git a/include/lmms_constants.h b/include/lmms_constants.h
index 629db886c..6f50c6f8e 100644
--- a/include/lmms_constants.h
+++ b/include/lmms_constants.h
@@ -25,15 +25,28 @@
#ifndef LMMS_CONSTANTS_H
#define LMMS_CONSTANTS_H
-const double D_PI = 3.14159265358979323846;
-const double D_2PI = D_PI * 2.0;
-const double D_PI_2 = D_PI * 0.5;
-const double D_E = 2.71828182845904523536;
+const long double LD_PI = 3.14159265358979323846264338327950288419716939937510;
+const long double LD_2PI = LD_PI * 2.0;
+const long double LD_PI_2 = LD_PI * 0.5;
+const long double LD_PI_R = 1.0 / LD_PI;
+const long double LD_PI_SQR = LD_PI * LD_PI;
+const long double LD_E = 2.71828182845904523536028747135266249775724709369995;
+const long double LD_E_R = 1.0 / LD_E;
-const float F_PI = (float) D_PI;
-const float F_2PI = (float) D_2PI;
-const float F_PI_2 = (float) D_PI_2;
-const float F_E = (float) D_E;
+const double D_PI = (double) LD_PI;
+const double D_2PI = (double) LD_2PI;
+const double D_PI_2 = (double) LD_PI_2;
+const double D_PI_R = (double) LD_PI_R;
+const double D_PI_SQR = (double) LD_PI_SQR;
+const double D_E = (double) LD_E;
+const double D_E_R = (double) LD_E_R;
+const float F_PI = (float) LD_PI;
+const float F_2PI = (float) LD_2PI;
+const float F_PI_2 = (float) LD_PI_2;
+const float F_PI_R = (float) LD_PI_R;
+const float F_PI_SQR = (float) LD_PI_SQR;
+const float F_E = (float) LD_E;
+const float F_E_R = (float) LD_E_R;
#endif
diff --git a/include/lmms_math.h b/include/lmms_math.h
index 1177c6921..7cde29153 100644
--- a/include/lmms_math.h
+++ b/include/lmms_math.h
@@ -130,7 +130,55 @@ static inline int fast_rand()
return( (unsigned)( next / 65536 ) % 32768 );
}
+static inline double fastRand( double range )
+{
+ static const double fast_rand_ratio = 1.0 / FAST_RAND_MAX;
+ return fast_rand() * range * fast_rand_ratio;
+}
+static inline float fastRandf( float range )
+{
+ static const float fast_rand_ratio = 1.0f / FAST_RAND_MAX;
+ return fast_rand() * range * fast_rand_ratio;
+}
+
+//! @brief Takes advantage of fmal() function if present in hardware
+static inline long double fastFmal( long double a, long double b, long double c )
+{
+#ifdef FP_FAST_FMAL
+ #ifdef __clang__
+ return fma( a, b, c );
+ #else
+ return fmal( a, b, c );
+ #endif
+#else
+ return a * b + c;
+#endif
+}
+
+//! @brief Takes advantage of fmaf() function if present in hardware
+static inline float fastFmaf( float a, float b, float c )
+{
+#ifdef FP_FAST_FMAF
+ #ifdef __clang__
+ return fma( a, b, c );
+ #else
+ return fmaf( a, b, c );
+ #endif
+#else
+ return a * b + c;
+#endif
+}
+
+//! @brief Takes advantage of fma() function if present in hardware
+static inline double fastFma( double a, double b, double c )
+{
+#ifdef FP_FAST_FMA
+ return fma( a, b, c );
+#else
+ return a * b + c;
+#endif
+}
// source: http://martin.ankerl.com/2007/10/04/optimized-pow-approximation-for-java-and-c-c/
static inline double fastPow( double a, double b )
@@ -241,5 +289,18 @@ static inline float fastSqrt( float n )
return u.f;
}
+//! returns value furthest from zero
+template
+static inline T absMax( T a, T b )
+{
+ return qAbs(a) > qAbs(b) ? a : b;
+}
+
+//! returns value nearest to zero
+template
+static inline T absMin( T a, T b )
+{
+ return qAbs(a) < qAbs(b) ? a : b;
+}
#endif
diff --git a/plugins/Amplifier/AmplifierControlDialog.cpp b/plugins/Amplifier/AmplifierControlDialog.cpp
index 360458827..50396a551 100644
--- a/plugins/Amplifier/AmplifierControlDialog.cpp
+++ b/plugins/Amplifier/AmplifierControlDialog.cpp
@@ -45,26 +45,26 @@ AmplifierControlDialog::AmplifierControlDialog( AmplifierControls* controls ) :
volumeKnob -> setVolumeKnob( true );
volumeKnob->setModel( &controls->m_volumeModel );
volumeKnob->setLabel( tr( "VOL" ) );
- volumeKnob->setHintText( tr( "Volume:" ) + " ", "%" );
+ volumeKnob->setHintText( tr( "Volume:" ) , "%" );
Knob * panKnob = new Knob( knobBright_26, this);
panKnob -> move( 60, 30 );
panKnob->setModel( &controls->m_panModel );
panKnob->setLabel( tr( "PAN" ) );
- panKnob->setHintText( tr( "Panning:" ) + " ", "" );
+ panKnob->setHintText( tr( "Panning:" ) , "" );
Knob * leftKnob = new Knob( knobBright_26, this);
leftKnob -> move( 20, 80 );
leftKnob -> setVolumeKnob( true );
leftKnob->setModel( &controls->m_leftModel );
leftKnob->setLabel( tr( "LEFT" ) );
- leftKnob->setHintText( tr( "Left gain:" ) + " ", "%" );
+ leftKnob->setHintText( tr( "Left gain:" ) , "%" );
Knob * rightKnob = new Knob( knobBright_26, this);
rightKnob -> move( 60, 80 );
rightKnob -> setVolumeKnob( true );
rightKnob->setModel( &controls->m_rightModel );
rightKnob->setLabel( tr( "RIGHT" ) );
- rightKnob->setHintText( tr( "Right gain:" ) + " ", "%" );
+ rightKnob->setHintText( tr( "Right gain:" ) , "%" );
}
diff --git a/plugins/BassBooster/BassBoosterControlDialog.cpp b/plugins/BassBooster/BassBoosterControlDialog.cpp
index cd299fb6d..fa4eac97d 100644
--- a/plugins/BassBooster/BassBoosterControlDialog.cpp
+++ b/plugins/BassBooster/BassBoosterControlDialog.cpp
@@ -47,17 +47,17 @@ BassBoosterControlDialog::BassBoosterControlDialog( BassBoosterControls* control
Knob * freqKnob = new Knob( knobBright_26, this);
freqKnob->setModel( &controls->m_freqModel );
freqKnob->setLabel( tr( "FREQ" ) );
- freqKnob->setHintText( tr( "Frequency:" ) + " ", "Hz" );
+ freqKnob->setHintText( tr( "Frequency:" ) , "Hz" );
Knob * gainKnob = new Knob( knobBright_26, this );
gainKnob->setModel( &controls->m_gainModel );
gainKnob->setLabel( tr( "GAIN" ) );
- gainKnob->setHintText( tr( "Gain:" ) + " ", "" );
+ gainKnob->setHintText( tr( "Gain:" ) , "" );
Knob * ratioKnob = new Knob( knobBright_26, this );
ratioKnob->setModel( &controls->m_ratioModel );
ratioKnob->setLabel( tr( "RATIO" ) );
- ratioKnob->setHintText( tr( "Ratio:" ) + " ", "" );
+ ratioKnob->setHintText( tr( "Ratio:" ) , "" );
l->addWidget( freqKnob );
l->addWidget( gainKnob );
diff --git a/plugins/Bitcrush/Bitcrush.cpp b/plugins/Bitcrush/Bitcrush.cpp
new file mode 100644
index 000000000..84f5b45ba
--- /dev/null
+++ b/plugins/Bitcrush/Bitcrush.cpp
@@ -0,0 +1,252 @@
+/*
+ * Bitcrush.cpp - A native bitcrusher
+ *
+ * Copyright (c) 2014 Vesa Kivimäki
+ * Copyright (c) 2006-2014 Tobias Doerffel
+ *
+ * This file is part of LMMS - http://lmms.io
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public
+ * License along with this program (see COPYING); if not, write to the
+ * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301 USA.
+ *
+ */
+
+#include "Bitcrush.h"
+#include "embed.cpp"
+
+const int OS_RATE = 5;
+const float OS_RATIO = 1.0f / OS_RATE;
+const float CUTOFF_RATIO = 0.353553391f;
+const int SILENCEFRAMES = 10;
+const float OS_RESAMPLE [5] = { 0.0001490062883964112, 0.1645978376763992, 0.6705063120704088,
+ 0.1645978376763992, 0.0001490062883964112 };
+
+extern "C"
+{
+
+Plugin::Descriptor PLUGIN_EXPORT bitcrush_plugin_descriptor =
+{
+ STRINGIFY( PLUGIN_NAME ),
+ "Bitcrush",
+ QT_TRANSLATE_NOOP( "pluginBrowser", "An oversampling bitcrusher" ),
+ "Vesa Kivimäki ",
+ 0x0100,
+ Plugin::Effect,
+ new PluginPixmapLoader( "logo" ),
+ NULL,
+ NULL
+};
+
+}
+
+BitcrushEffect::BitcrushEffect( Model * parent, const Descriptor::SubPluginFeatures::Key * key ) :
+ Effect( &bitcrush_plugin_descriptor, parent, key ),
+ m_controls( this ),
+ m_sampleRate( Engine::mixer()->processingSampleRate() ),
+ m_filter( m_sampleRate )
+{
+ m_buffer = MM_ALLOC( sampleFrame, Engine::mixer()->framesPerPeriod() * OS_RATE );
+ m_filter.setLowpass( m_sampleRate * ( CUTOFF_RATIO * OS_RATIO ) );
+ m_needsUpdate = true;
+
+ m_bitCounterL = 0.0f;
+ m_bitCounterR = 0.0f;
+
+ m_left = 0.0f;
+ m_right = 0.0f;
+
+ m_silenceCounter = 0;
+}
+
+BitcrushEffect::~BitcrushEffect()
+{
+ MM_FREE( m_buffer );
+}
+
+
+void BitcrushEffect::sampleRateChanged()
+{
+ m_sampleRate = Engine::mixer()->processingSampleRate();
+ m_filter.setSampleRate( m_sampleRate );
+ m_filter.setLowpass( m_sampleRate * ( CUTOFF_RATIO * OS_RATIO ) );
+ m_needsUpdate = true;
+}
+
+
+inline float BitcrushEffect::depthCrush( float in )
+{
+ return roundf( in * (float) m_levels ) * m_levelsRatio;
+}
+
+inline float BitcrushEffect::noise( float amt )
+{
+ return fastRandf( amt * 2.0f ) - amt;
+}
+
+bool BitcrushEffect::processAudioBuffer( sampleFrame* buf, const fpp_t frames )
+{
+ if( !isEnabled() || !isRunning () )
+ {
+ return( false );
+ }
+
+ // update values
+ if( m_needsUpdate || m_controls.m_rateEnabled.isValueChanged() )
+ {
+ m_rateEnabled = m_controls.m_rateEnabled.value();
+ m_bitCounterL = 0.0f;
+ m_bitCounterR = 0.0f;
+ }
+ if( m_needsUpdate || m_controls.m_depthEnabled.isValueChanged() )
+ {
+ m_depthEnabled = m_controls.m_depthEnabled.value();
+ }
+ if( m_needsUpdate || m_controls.m_rate.isValueChanged() || m_controls.m_stereoDiff.isValueChanged() )
+ {
+ const float rate = m_controls.m_rate.value();
+ const float diff = m_controls.m_stereoDiff.value() * 0.005 * rate;
+
+ m_rateCoeffL = ( m_sampleRate * OS_RATE ) / ( rate - diff );
+ m_rateCoeffR = ( m_sampleRate * OS_RATE ) / ( rate + diff );
+
+ m_bitCounterL = 0.0f;
+ m_bitCounterR = 0.0f;
+ }
+ if( m_needsUpdate || m_controls.m_levels.isValueChanged() )
+ {
+ m_levels = m_controls.m_levels.value();
+ m_levelsRatio = 1.0f / (float) m_levels;
+ }
+ if( m_needsUpdate || m_controls.m_inGain.isValueChanged() )
+ {
+ m_inGain = dbvToAmp( m_controls.m_inGain.value() );
+ }
+ if( m_needsUpdate || m_controls.m_outGain.isValueChanged() )
+ {
+ m_outGain = dbvToAmp( m_controls.m_outGain.value() );
+ }
+ if( m_needsUpdate || m_controls.m_outClip.isValueChanged() )
+ {
+ m_outClip = dbvToAmp( m_controls.m_outClip.value() );
+ }
+ m_needsUpdate = false;
+
+ const float noiseAmt = m_controls.m_inNoise.value() * 0.01f;
+
+ // read input buffer and write it to oversampled buffer
+ if( m_rateEnabled ) // rate crushing enabled so do that
+ {
+ for( int f = 0; f < frames; ++f )
+ {
+ for( int o = 0; o < OS_RATE; ++o )
+ {
+ m_buffer[f * OS_RATE + o][0] = m_left;
+ m_buffer[f * OS_RATE + o][1] = m_right;
+ m_bitCounterL += 1.0f;
+ m_bitCounterR += 1.0f;
+ if( m_bitCounterL > m_rateCoeffL )
+ {
+ m_bitCounterL -= m_rateCoeffL;
+ m_left = m_depthEnabled
+ ? depthCrush( buf[f][0] * m_inGain + noise( buf[f][0] * noiseAmt ) )
+ : buf[f][0] * m_inGain + noise( buf[f][0] * noiseAmt );
+ }
+ if( m_bitCounterR > m_rateCoeffR )
+ {
+ m_bitCounterR -= m_rateCoeffR;
+ m_right = m_depthEnabled
+ ? depthCrush( buf[f][1] * m_inGain + noise( buf[f][1] * noiseAmt ) )
+ : buf[f][1] * m_inGain + noise( buf[f][1] * noiseAmt );
+ }
+ }
+ }
+ }
+ else // rate crushing disabled: simply oversample with zero-order hold
+ {
+ for( int f = 0; f < frames; ++f )
+ {
+ for( int o = 0; o < OS_RATE; ++o )
+ {
+ m_buffer[f * OS_RATE + o][0] = m_depthEnabled
+ ? depthCrush( buf[f][0] * m_inGain + noise( buf[f][0] * noiseAmt ) )
+ : buf[f][0] * m_inGain + noise( buf[f][0] * noiseAmt );
+ m_buffer[f * OS_RATE + o][1] = m_depthEnabled
+ ? depthCrush( buf[f][1] * m_inGain + noise( buf[f][1] * noiseAmt ) )
+ : buf[f][1] * m_inGain + noise( buf[f][1] * noiseAmt );
+ }
+ }
+ }
+
+ // the oversampled buffer is now written, so filter it to reduce aliasing
+
+ for( int f = 0; f < frames * OS_RATE; ++f )
+ {
+ if( qMax( qAbs( m_buffer[f][0] ), qAbs( m_buffer[f][1] ) ) >= 1.0e-10f )
+ {
+ m_silenceCounter = 0;
+ m_buffer[f][0] = m_filter.update( m_buffer[f][0], 0 );
+ m_buffer[f][1] = m_filter.update( m_buffer[f][1], 1 );
+ }
+ else
+ {
+ if( m_silenceCounter > SILENCEFRAMES )
+ {
+ m_buffer[f][0] = m_buffer[f][1] = 0.0f;
+ }
+ else
+ {
+ ++m_silenceCounter;
+ m_buffer[f][0] = m_filter.update( m_buffer[f][0], 0 );
+ m_buffer[f][1] = m_filter.update( m_buffer[f][1], 1 );
+ }
+ }
+ }
+
+
+ // now downsample and write it back to main buffer
+
+ double outSum = 0.0;
+ const float d = dryLevel();
+ const float w = wetLevel();
+ for( int f = 0; f < frames; ++f )
+ {
+ float lsum = 0.0f;
+ float rsum = 0.0f;
+ for( int o = 0; o < OS_RATE; ++o )
+ {
+ lsum += m_buffer[f * OS_RATE + o][0] * OS_RESAMPLE[o];
+ rsum += m_buffer[f * OS_RATE + o][1] * OS_RESAMPLE[o];
+ }
+ buf[f][0] = d * buf[f][0] + w * qBound( -m_outClip, lsum, m_outClip ) * m_outGain;
+ buf[f][1] = d * buf[f][1] + w * qBound( -m_outClip, rsum, m_outClip ) * m_outGain;
+ outSum += buf[f][0]*buf[f][0] + buf[f][1]*buf[f][1];
+ }
+
+ checkGate( outSum / frames );
+
+ return isRunning();
+}
+
+
+extern "C"
+{
+
+// necessary for getting instance out of shared lib
+Plugin * PLUGIN_EXPORT lmms_plugin_main( Model* parent, void* data )
+{
+ return new BitcrushEffect( parent, static_cast( data ) );
+}
+
+}
diff --git a/plugins/Bitcrush/Bitcrush.h b/plugins/Bitcrush/Bitcrush.h
new file mode 100644
index 000000000..0c599e107
--- /dev/null
+++ b/plugins/Bitcrush/Bitcrush.h
@@ -0,0 +1,83 @@
+/*
+ * Bitcrush.h - A native bitcrusher
+ *
+ * Copyright (c) 2014 Vesa Kivimäki
+ * Copyright (c) 2006-2014 Tobias Doerffel
+ *
+ * This file is part of LMMS - http://lmms.io
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public
+ * License along with this program (see COPYING); if not, write to the
+ * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301 USA.
+ *
+ */
+
+
+#ifndef BITCRUSH_H
+#define BITCRUSH_H
+
+#include "Effect.h"
+#include "BitcrushControls.h"
+#include "ValueBuffer.h"
+#include "lmms_math.h"
+#include "BasicFilters.h"
+
+class BitcrushEffect : public Effect
+{
+public:
+ BitcrushEffect( Model* parent, const Descriptor::SubPluginFeatures::Key* key );
+ virtual ~BitcrushEffect();
+ virtual bool processAudioBuffer( sampleFrame* buf, const fpp_t frames );
+
+ virtual EffectControls* controls()
+ {
+ return &m_controls;
+ }
+
+private:
+ void sampleRateChanged();
+ float depthCrush( float in );
+ float noise( float amt );
+
+ BitcrushControls m_controls;
+
+ sampleFrame * m_buffer;
+ float m_sampleRate;
+ StereoLinkwitzRiley m_filter;
+
+ float m_bitCounterL;
+ float m_rateCoeffL;
+ float m_bitCounterR;
+ float m_rateCoeffR;
+ bool m_rateEnabled;
+
+ float m_left;
+ float m_right;
+
+ int m_levels;
+ float m_levelsRatio;
+ bool m_depthEnabled;
+
+ float m_inGain;
+ float m_outGain;
+ float m_outClip;
+
+ bool m_needsUpdate;
+
+ int m_silenceCounter;
+
+ friend class BitcrushControls;
+};
+
+#endif
diff --git a/plugins/Bitcrush/BitcrushControlDialog.cpp b/plugins/Bitcrush/BitcrushControlDialog.cpp
new file mode 100644
index 000000000..3faa7e52c
--- /dev/null
+++ b/plugins/Bitcrush/BitcrushControlDialog.cpp
@@ -0,0 +1,113 @@
+/*
+ * BitcrushControlDialog.cpp - A native bitcrusher
+ *
+ * Copyright (c) 2014 Vesa Kivimäki
+ * Copyright (c) 2006-2014 Tobias Doerffel
+ *
+ * This file is part of LMMS - http://lmms.io
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public
+ * License along with this program (see COPYING); if not, write to the
+ * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301 USA.
+ *
+ */
+
+
+#include
+#include
+
+#include "BitcrushControlDialog.h"
+#include "BitcrushControls.h"
+#include "embed.h"
+#include "ToolTip.h"
+#include "LedCheckbox.h"
+#include "Knob.h"
+
+BitcrushControlDialog::BitcrushControlDialog( BitcrushControls * controls ) :
+ EffectControlDialog( controls )
+{
+ setAutoFillBackground( true );
+ QPalette pal;
+ pal.setBrush( backgroundRole(), PLUGIN_NAME::getIconPixmap( "artwork" ) );
+ setPalette( pal );
+ setFixedSize( 215, 120 );
+
+ // labels
+ QLabel * inLabel = new QLabel( tr( "IN" ), this );
+ inLabel->move( 12, 10);
+
+ QLabel * outLabel = new QLabel( tr( "OUT" ), this );
+ outLabel->move( 176, 10 );
+
+ // input knobs
+ Knob * inGain = new Knob( knobBright_26, this );
+ inGain->move( 12, 25 );
+ inGain->setModel( & controls->m_inGain );
+ inGain->setLabel( tr( "GAIN" ) );
+ inGain->setHintText( tr( "Input Gain:" ) + " ", " dBV" );
+
+ Knob * inNoise = new Knob( knobBright_26, this );
+ inNoise->move( 12, 70 );
+ inNoise->setModel( & controls->m_inNoise );
+ inNoise->setLabel( tr( "NOIS" ) );
+ inNoise->setHintText( tr( "Input Noise:" ) + " ", "%" );
+
+
+ // output knobs
+ Knob * outGain = new Knob( knobBright_26, this );
+ outGain->move( 176, 25 );
+ outGain->setModel( & controls->m_outGain );
+ outGain->setLabel( tr( "GAIN" ) );
+ outGain->setHintText( tr( "Output Gain:" ) + " ", " dBV" );
+
+ Knob * outClip = new Knob( knobBright_26, this );
+ outClip->move( 176, 70 );
+ outClip->setModel( & controls->m_outClip );
+ outClip->setLabel( tr( "CLIP" ) );
+ outClip->setHintText( tr( "Output Clip:" ) + " ", "%" );
+
+
+ // leds
+ LedCheckBox * rateEnabled = new LedCheckBox( tr( "Rate" ), this, tr( "Rate Enabled" ), LedCheckBox::Green );
+ rateEnabled->move( 50, 30 );
+ rateEnabled->setModel( & controls->m_rateEnabled );
+ ToolTip::add( rateEnabled, tr( "Enable samplerate-crushing" ) );
+
+ LedCheckBox * depthEnabled = new LedCheckBox( tr( "Depth" ), this, tr( "Depth Enabled" ), LedCheckBox::Green );
+ depthEnabled->move( 50, 80 );
+ depthEnabled->setModel( & controls->m_depthEnabled );
+ ToolTip::add( depthEnabled, tr( "Enable bitdepth-crushing" ) );
+
+
+ // rate crushing knobs
+ Knob * rate = new Knob( knobBright_26, this );
+ rate->move( 100, 20 );
+ rate->setModel( & controls->m_rate );
+ rate->setLabel( tr( "Rate" ) );
+ rate->setHintText( tr( "Sample rate:" ) + " ", " Hz" );
+
+ Knob * stereoDiff = new Knob( knobBright_26, this );
+ stereoDiff->move( 140, 20 );
+ stereoDiff->setModel( & controls->m_stereoDiff );
+ stereoDiff->setLabel( tr( "STD" ) );
+ stereoDiff->setHintText( tr( "Stereo difference:" ) + " ", "%" );
+
+
+ // depth crushing knob
+ Knob * levels = new Knob( knobBright_26, this );
+ levels->move( 140, 70 );
+ levels->setModel( & controls->m_levels );
+ levels->setLabel( tr( "Levels" ) );
+ levels->setHintText( tr( "Levels:" ) + " ", "" );
+}
diff --git a/plugins/Bitcrush/BitcrushControlDialog.h b/plugins/Bitcrush/BitcrushControlDialog.h
new file mode 100644
index 000000000..69c4dd5f5
--- /dev/null
+++ b/plugins/Bitcrush/BitcrushControlDialog.h
@@ -0,0 +1,44 @@
+/*
+ * BitcrushControlDialog.h - A native bitcrusher
+ *
+ * Copyright (c) 2014 Vesa Kivimäki
+ * Copyright (c) 2006-2014 Tobias Doerffel
+ *
+ * This file is part of LMMS - http://lmms.io
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public
+ * License along with this program (see COPYING); if not, write to the
+ * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301 USA.
+ *
+ */
+
+
+#ifndef BITCRUSH_CONTROL_DIALOG_H
+#define BITCRUSH_CONTROL_DIALOG_H
+
+#include "EffectControlDialog.h"
+
+class BitcrushControls;
+
+class BitcrushControlDialog : public EffectControlDialog
+{
+ Q_OBJECT
+public:
+ BitcrushControlDialog( BitcrushControls * controls );
+ virtual ~BitcrushControlDialog()
+ {
+ }
+};
+
+#endif
diff --git a/plugins/Bitcrush/BitcrushControls.cpp b/plugins/Bitcrush/BitcrushControls.cpp
new file mode 100644
index 000000000..e67cef0d1
--- /dev/null
+++ b/plugins/Bitcrush/BitcrushControls.cpp
@@ -0,0 +1,89 @@
+/*
+ * BitcrushControls.cpp - A native bitcrusher
+ *
+ * Copyright (c) 2014 Vesa Kivimäki
+ * Copyright (c) 2006-2014 Tobias Doerffel
+ *
+ * This file is part of LMMS - http://lmms.io
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public
+ * License along with this program (see COPYING); if not, write to the
+ * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301 USA.
+ *
+ */
+
+
+#include
+
+#include "BitcrushControls.h"
+#include "Bitcrush.h"
+#include "lmms_math.h"
+
+
+BitcrushControls::BitcrushControls( BitcrushEffect * eff ) :
+ EffectControls( eff ),
+ m_effect( eff ),
+ m_inGain( 0.0f, -20.0f, 20.0f, 0.1f, this, "Input gain" ),
+ m_inNoise( 0.0f, 0.0f, 100.0f, 0.1f, this, "Input noise" ),
+ m_outGain( 0.0f, -20.0f, 20.0f, 0.1f, this, "Output gain" ),
+ m_outClip( 0.0f, -20.0f, 20.0f, 0.1f, this, "Output clip" ),
+ m_rate( 44100.f, 20.f, 44100.f, 1.0f, this, "Samplerate" ),
+ m_stereoDiff( 0.f, 0.f, 50.f, 0.1f, this, "Stereo difference" ),
+ m_levels( 256.f, 1.f, 256.f, 1.0f, this, "Levels" ),
+ m_rateEnabled( true, this, "Rate enabled" ),
+ m_depthEnabled( true, this, "Depth enabled" )
+{
+ m_rate.setStrictStepSize( true );
+ m_levels.setStrictStepSize( true );
+
+ connect( Engine::mixer(), SIGNAL( sampleRateChanged() ), this, SLOT( sampleRateChanged() ) );
+}
+
+BitcrushControls::~BitcrushControls()
+{
+}
+
+void BitcrushControls::saveSettings( QDomDocument & doc, QDomElement & elem )
+{
+ m_inGain.saveSettings( doc, elem, "ingain" );
+ m_inNoise.saveSettings( doc, elem, "innoise" );
+ m_outGain.saveSettings( doc, elem, "outgain" );
+ m_outClip.saveSettings( doc, elem, "outclip" );
+ m_rate.saveSettings( doc, elem, "rate" );
+ m_stereoDiff.saveSettings( doc, elem, "stereodiff" );
+ m_levels.saveSettings( doc, elem, "levels" );
+ m_rateEnabled.saveSettings( doc, elem, "rateon" );
+ m_depthEnabled.saveSettings( doc, elem, "depthon" );
+}
+
+
+void BitcrushControls::loadSettings( const QDomElement & elem )
+{
+ m_inGain.loadSettings( elem, "ingain" );
+ m_inNoise.loadSettings( elem, "innoise" );
+ m_outGain.loadSettings( elem, "outgain" );
+ m_outClip.loadSettings( elem, "outclip" );
+ m_rate.loadSettings( elem, "rate" );
+ m_stereoDiff.loadSettings( elem, "stereodiff" );
+ m_levels.loadSettings( elem, "levels" );
+ m_rateEnabled.loadSettings( elem, "rateon" );
+ m_depthEnabled.loadSettings( elem, "depthon" );
+
+ m_effect->m_needsUpdate = true;
+}
+
+void BitcrushControls::sampleRateChanged()
+{
+ m_effect->sampleRateChanged();
+}
diff --git a/plugins/Bitcrush/BitcrushControls.h b/plugins/Bitcrush/BitcrushControls.h
new file mode 100644
index 000000000..42ec34e38
--- /dev/null
+++ b/plugins/Bitcrush/BitcrushControls.h
@@ -0,0 +1,82 @@
+/*
+ * BitcrushControls.h - A native bitcrusher
+ *
+ * Copyright (c) 2014 Vesa Kivimäki
+ * Copyright (c) 2006-2014 Tobias Doerffel
+ *
+ * This file is part of LMMS - http://lmms.io
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public
+ * License along with this program (see COPYING); if not, write to the
+ * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301 USA.
+ *
+ */
+
+#ifndef BITCRUSH_CONTROLS_H
+#define BITCRUSH_CONTROLS_H
+
+#include "EffectControls.h"
+#include "BitcrushControlDialog.h"
+
+class BitcrushEffect;
+
+class BitcrushControls : public EffectControls
+{
+ Q_OBJECT
+public:
+ BitcrushControls( BitcrushEffect * eff );
+ virtual ~BitcrushControls();
+
+ virtual void saveSettings( QDomDocument & doc, QDomElement & elem );
+ virtual void loadSettings( const QDomElement & elem );
+ inline virtual QString nodeName() const
+ {
+ return( "bitcrushcontrols" );
+ }
+
+ virtual int controlCount()
+ {
+ return( 9 );
+ }
+
+ virtual EffectControlDialog * createView()
+ {
+ return( new BitcrushControlDialog( this ) );
+ }
+
+private slots:
+ void sampleRateChanged();
+
+private:
+ BitcrushEffect * m_effect;
+
+ FloatModel m_inGain;
+ FloatModel m_inNoise;
+
+ FloatModel m_outGain;
+ FloatModel m_outClip;
+
+ FloatModel m_rate;
+ FloatModel m_stereoDiff;
+
+ FloatModel m_levels;
+
+ BoolModel m_rateEnabled;
+ BoolModel m_depthEnabled;
+
+ friend class BitcrushControlDialog;
+ friend class BitcrushEffect;
+};
+
+#endif
diff --git a/plugins/Bitcrush/CMakeLists.txt b/plugins/Bitcrush/CMakeLists.txt
new file mode 100644
index 000000000..ca70afceb
--- /dev/null
+++ b/plugins/Bitcrush/CMakeLists.txt
@@ -0,0 +1,3 @@
+INCLUDE(BuildPlugin)
+
+BUILD_PLUGIN(bitcrush Bitcrush.cpp BitcrushControls.cpp BitcrushControlDialog.cpp MOCFILES BitcrushControls.h BitcrushControlDialog.h EMBEDDED_RESOURCES "${CMAKE_CURRENT_SOURCE_DIR}/*.png")
diff --git a/plugins/Bitcrush/artwork.png b/plugins/Bitcrush/artwork.png
new file mode 100644
index 000000000..c0c97bdd5
Binary files /dev/null and b/plugins/Bitcrush/artwork.png differ
diff --git a/plugins/CMakeLists.txt b/plugins/CMakeLists.txt
index e6f3509ee..cf7a5a94e 100644
--- a/plugins/CMakeLists.txt
+++ b/plugins/CMakeLists.txt
@@ -2,9 +2,11 @@ ADD_SUBDIRECTORY(Amplifier)
ADD_SUBDIRECTORY(audio_file_processor)
ADD_SUBDIRECTORY(BassBooster)
ADD_SUBDIRECTORY(bit_invader)
+ADD_SUBDIRECTORY(Bitcrush)
ADD_SUBDIRECTORY(carlabase)
ADD_SUBDIRECTORY(carlapatchbay)
ADD_SUBDIRECTORY(carlarack)
+ADD_SUBDIRECTORY(CrossoverEQ)
ADD_SUBDIRECTORY(delay)
ADD_SUBDIRECTORY(DualFilter)
ADD_SUBDIRECTORY(dynamics_processor)
diff --git a/plugins/CrossoverEQ/CMakeLists.txt b/plugins/CrossoverEQ/CMakeLists.txt
new file mode 100644
index 000000000..fbc8407d9
--- /dev/null
+++ b/plugins/CrossoverEQ/CMakeLists.txt
@@ -0,0 +1,3 @@
+INCLUDE(BuildPlugin)
+
+BUILD_PLUGIN(crossovereq CrossoverEQ.cpp CrossoverEQControls.cpp CrossoverEQControlDialog.cpp MOCFILES CrossoverEQControls.h CrossoverEQControlDialog.h EMBEDDED_RESOURCES "${CMAKE_CURRENT_SOURCE_DIR}/*.png")
diff --git a/plugins/CrossoverEQ/CrossoverEQ.cpp b/plugins/CrossoverEQ/CrossoverEQ.cpp
new file mode 100644
index 000000000..a50b6381f
--- /dev/null
+++ b/plugins/CrossoverEQ/CrossoverEQ.cpp
@@ -0,0 +1,219 @@
+/*
+ * CrossoverEQ.cpp - A native 4-band Crossover Equalizer
+ * good for simulating tonestacks or simple peakless (flat-band) equalization
+ *
+ * Copyright (c) 2014 Vesa Kivimäki
+ * Copyright (c) 2006-2014 Tobias Doerffel
+ *
+ * This file is part of LMMS - http://lmms.io
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public
+ * License along with this program (see COPYING); if not, write to the
+ * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301 USA.
+ *
+ */
+
+#include "CrossoverEQ.h"
+#include "lmms_math.h"
+#include "embed.cpp"
+
+extern "C"
+{
+
+Plugin::Descriptor PLUGIN_EXPORT crossovereq_plugin_descriptor =
+{
+ STRINGIFY( PLUGIN_NAME ),
+ "Crossover Equalizer",
+ QT_TRANSLATE_NOOP( "pluginBrowser", "A 4-band Crossover Equalizer" ),
+ "Vesa Kivimäki ",
+ 0x0100,
+ Plugin::Effect,
+ new PluginPixmapLoader( "logo" ),
+ NULL,
+ NULL
+};
+
+}
+
+
+CrossoverEQEffect::CrossoverEQEffect( Model* parent, const Descriptor::SubPluginFeatures::Key* key ) :
+ Effect( &crossovereq_plugin_descriptor, parent, key ),
+ m_controls( this ),
+ m_sampleRate( Engine::mixer()->processingSampleRate() ),
+ m_lp1( m_sampleRate ),
+ m_lp2( m_sampleRate ),
+ m_lp3( m_sampleRate ),
+ m_hp2( m_sampleRate ),
+ m_hp3( m_sampleRate ),
+ m_hp4( m_sampleRate ),
+ m_needsUpdate( true )
+{
+ m_tmp1 = MM_ALLOC( sampleFrame, Engine::mixer()->framesPerPeriod() );
+ m_tmp2 = MM_ALLOC( sampleFrame, Engine::mixer()->framesPerPeriod() );
+ m_work = MM_ALLOC( sampleFrame, Engine::mixer()->framesPerPeriod() );
+}
+
+CrossoverEQEffect::~CrossoverEQEffect()
+{
+ MM_FREE( m_tmp1 );
+ MM_FREE( m_tmp2 );
+ MM_FREE( m_work );
+}
+
+void CrossoverEQEffect::sampleRateChanged()
+{
+ m_sampleRate = Engine::mixer()->processingSampleRate();
+ m_lp1.setSampleRate( m_sampleRate );
+ m_lp2.setSampleRate( m_sampleRate );
+ m_lp3.setSampleRate( m_sampleRate );
+ m_hp2.setSampleRate( m_sampleRate );
+ m_hp3.setSampleRate( m_sampleRate );
+ m_hp4.setSampleRate( m_sampleRate );
+ m_needsUpdate = true;
+}
+
+
+bool CrossoverEQEffect::processAudioBuffer( sampleFrame* buf, const fpp_t frames )
+{
+ if( !isEnabled() || !isRunning () )
+ {
+ return( false );
+ }
+
+ // filters update
+ if( m_needsUpdate || m_controls.m_xover12.isValueChanged() )
+ {
+ m_lp1.setLowpass( m_controls.m_xover12.value() );
+ m_lp1.clearHistory();
+ m_hp2.setHighpass( m_controls.m_xover12.value() );
+ m_hp2.clearHistory();
+ }
+ if( m_needsUpdate || m_controls.m_xover23.isValueChanged() )
+ {
+ m_lp2.setLowpass( m_controls.m_xover23.value() );
+ m_lp2.clearHistory();
+ m_hp3.setHighpass( m_controls.m_xover23.value() );
+ m_hp3.clearHistory();
+ }
+ if( m_needsUpdate || m_controls.m_xover34.isValueChanged() )
+ {
+ m_lp3.setLowpass( m_controls.m_xover34.value() );
+ m_lp3.clearHistory();
+ m_hp4.setHighpass( m_controls.m_xover34.value() );
+ m_hp4.clearHistory();
+ }
+
+ // gain values update
+ if( m_needsUpdate || m_controls.m_gain1.isValueChanged() )
+ {
+ m_gain1 = dbvToAmp( m_controls.m_gain1.value() );
+ }
+ if( m_needsUpdate || m_controls.m_gain2.isValueChanged() )
+ {
+ m_gain2 = dbvToAmp( m_controls.m_gain2.value() );
+ }
+ if( m_needsUpdate || m_controls.m_gain3.isValueChanged() )
+ {
+ m_gain3 = dbvToAmp( m_controls.m_gain3.value() );
+ }
+ if( m_needsUpdate || m_controls.m_gain4.isValueChanged() )
+ {
+ m_gain4 = dbvToAmp( m_controls.m_gain4.value() );
+ }
+
+ // mute values update
+ const bool mute1 = m_controls.m_mute1.value();
+ const bool mute2 = m_controls.m_mute2.value();
+ const bool mute3 = m_controls.m_mute3.value();
+ const bool mute4 = m_controls.m_mute4.value();
+
+ m_needsUpdate = false;
+
+ memset( m_work, 0, sizeof( sampleFrame ) * frames );
+
+ // run temp bands
+ for( int f = 0; f < frames; ++f )
+ {
+ m_tmp1[f][0] = m_lp2.update( buf[f][0], 0 );
+ m_tmp1[f][1] = m_lp2.update( buf[f][1], 1 );
+ m_tmp2[f][0] = m_hp3.update( buf[f][0], 0 );
+ m_tmp2[f][1] = m_hp3.update( buf[f][1], 1 );
+ }
+
+ // run band 1
+ if( ! mute1 )
+ {
+ for( int f = 0; f < frames; ++f )
+ {
+ m_work[f][0] += m_lp1.update( m_tmp1[f][0], 0 ) * m_gain1;
+ m_work[f][1] += m_lp1.update( m_tmp1[f][1], 1 ) * m_gain1;
+ }
+ }
+
+ // run band 2
+ if( ! mute2 )
+ {
+ for( int f = 0; f < frames; ++f )
+ {
+ m_work[f][0] += m_hp2.update( m_tmp1[f][0], 0 ) * m_gain2;
+ m_work[f][1] += m_hp2.update( m_tmp1[f][1], 1 ) * m_gain2;
+ }
+ }
+
+ // run band 3
+ if( ! mute3 )
+ {
+ for( int f = 0; f < frames; ++f )
+ {
+ m_work[f][0] += m_lp3.update( m_tmp2[f][0], 0 ) * m_gain3;
+ m_work[f][1] += m_lp3.update( m_tmp2[f][1], 1 ) * m_gain3;
+ }
+ }
+
+ // run band 4
+ if( ! mute4 )
+ {
+ for( int f = 0; f < frames; ++f )
+ {
+ m_work[f][0] += m_hp4.update( m_tmp2[f][0], 0 ) * m_gain4;
+ m_work[f][1] += m_hp4.update( m_tmp2[f][1], 1 ) * m_gain4;
+ }
+ }
+
+ const float d = dryLevel();
+ const float w = wetLevel();
+ double outSum = 0.0;
+ for( int f = 0; f < frames; ++f )
+ {
+ buf[f][0] = d * buf[f][0] + w * m_work[f][0];
+ buf[f][1] = d * buf[f][1] + w * m_work[f][1];
+ outSum = buf[f][0] * buf[f][0] + buf[f][1] * buf[f][1];
+ }
+
+ checkGate( outSum );
+
+ return isRunning();
+}
+
+
+extern "C"
+{
+
+// necessary for getting instance out of shared lib
+Plugin * PLUGIN_EXPORT lmms_plugin_main( Model* parent, void* data )
+{
+ return new CrossoverEQEffect( parent, static_cast( data ) );
+}
+
+}
diff --git a/plugins/CrossoverEQ/CrossoverEQ.h b/plugins/CrossoverEQ/CrossoverEQ.h
new file mode 100644
index 000000000..36b3a6bc5
--- /dev/null
+++ b/plugins/CrossoverEQ/CrossoverEQ.h
@@ -0,0 +1,77 @@
+/*
+ * CrossoverEQ.h - A native 4-band Crossover Equalizer
+ * good for simulating tonestacks or simple peakless (flat-band) equalization
+ *
+ * Copyright (c) 2014 Vesa Kivimäki
+ * Copyright (c) 2006-2014 Tobias Doerffel
+ *
+ * This file is part of LMMS - http://lmms.io
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public
+ * License along with this program (see COPYING); if not, write to the
+ * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301 USA.
+ *
+ */
+
+#ifndef CROSSOVEREQ_H
+#define CROSSOVEREQ_H
+
+#include "Effect.h"
+#include "CrossoverEQControls.h"
+#include "ValueBuffer.h"
+#include "lmms_math.h"
+#include "BasicFilters.h"
+
+class CrossoverEQEffect : public Effect
+{
+public:
+ CrossoverEQEffect( Model* parent, const Descriptor::SubPluginFeatures::Key* key );
+ virtual ~CrossoverEQEffect();
+ virtual bool processAudioBuffer( sampleFrame* buf, const fpp_t frames );
+
+ virtual EffectControls* controls()
+ {
+ return &m_controls;
+ }
+
+private:
+ CrossoverEQControls m_controls;
+
+ void sampleRateChanged();
+
+ float m_sampleRate;
+
+ float m_gain1;
+ float m_gain2;
+ float m_gain3;
+ float m_gain4;
+
+ StereoLinkwitzRiley m_lp1;
+ StereoLinkwitzRiley m_lp2;
+ StereoLinkwitzRiley m_lp3;
+
+ StereoLinkwitzRiley m_hp2;
+ StereoLinkwitzRiley m_hp3;
+ StereoLinkwitzRiley m_hp4;
+
+ sampleFrame * m_tmp1;
+ sampleFrame * m_tmp2;
+ sampleFrame * m_work;
+
+ bool m_needsUpdate;
+
+ friend class CrossoverEQControls;
+};
+
+#endif
diff --git a/plugins/CrossoverEQ/CrossoverEQControlDialog.cpp b/plugins/CrossoverEQ/CrossoverEQControlDialog.cpp
new file mode 100644
index 000000000..8a9eecf4d
--- /dev/null
+++ b/plugins/CrossoverEQ/CrossoverEQControlDialog.cpp
@@ -0,0 +1,115 @@
+/*
+ * CrossoverEQControlDialog.cpp - A native 4-band Crossover Equalizer
+ * good for simulating tonestacks or simple peakless (flat-band) equalization
+ *
+ * Copyright (c) 2014 Vesa Kivimäki
+ * Copyright (c) 2006-2014 Tobias Doerffel
+ *
+ * This file is part of LMMS - http://lmms.io
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public
+ * License along with this program (see COPYING); if not, write to the
+ * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301 USA.
+ *
+ */
+
+#include
+#include
+
+#include "CrossoverEQControlDialog.h"
+#include "CrossoverEQControls.h"
+#include "embed.h"
+#include "ToolTip.h"
+#include "LedCheckbox.h"
+#include "Knob.h"
+#include "Fader.h"
+
+CrossoverEQControlDialog::CrossoverEQControlDialog( CrossoverEQControls * controls ) :
+ EffectControlDialog( controls )
+{
+ setAutoFillBackground( true );
+ QPalette pal;
+ pal.setBrush( backgroundRole(), PLUGIN_NAME::getIconPixmap( "artwork" ) );
+ setPalette( pal );
+ setFixedSize( 167, 188 );
+
+ // knobs
+ Knob * xover12 = new Knob( knobBright_26, this );
+ xover12->move( 29, 15 );
+ xover12->setModel( & controls->m_xover12 );
+ xover12->setLabel( "1/2" );
+ xover12->setHintText( tr( "Band 1/2 Crossover:" ), " Hz" );
+
+ Knob * xover23 = new Knob( knobBright_26, this );
+ xover23->move( 69, 15 );
+ xover23->setModel( & controls->m_xover23 );
+ xover23->setLabel( "2/3" );
+ xover23->setHintText( tr( "Band 2/3 Crossover:" ), " Hz" );
+
+ Knob * xover34 = new Knob( knobBright_26, this );
+ xover34->move( 109, 15 );
+ xover34->setModel( & controls->m_xover34 );
+ xover34->setLabel( "3/4" );
+ xover34->setHintText( tr( "Band 3/4 Crossover:" ), " Hz" );
+
+ m_fader_bg = QPixmap( PLUGIN_NAME::getIconPixmap( "fader_bg" ) );
+ m_fader_empty = QPixmap( PLUGIN_NAME::getIconPixmap( "fader_empty" ) );
+ m_fader_knob = QPixmap( PLUGIN_NAME::getIconPixmap( "fader_knob2" ) );
+
+ // faders
+ Fader * gain1 = new Fader( &controls->m_gain1, "Band 1 Gain", this,
+ &m_fader_bg, &m_fader_empty, &m_fader_knob );
+ gain1->move( 7, 56 );
+ gain1->setDisplayConversion( false );
+ gain1->setHintText( tr( "Band 1 Gain:" ), " dBV" );
+
+ Fader * gain2 = new Fader( &controls->m_gain2, "Band 2 Gain", this,
+ &m_fader_bg, &m_fader_empty, &m_fader_knob );
+ gain2->move( 47, 56 );
+ gain2->setDisplayConversion( false );
+ gain2->setHintText( tr( "Band 2 Gain:" ), " dBV" );
+
+ Fader * gain3 = new Fader( &controls->m_gain3, "Band 3 Gain", this,
+ &m_fader_bg, &m_fader_empty, &m_fader_knob );
+ gain3->move( 87, 56 );
+ gain3->setDisplayConversion( false );
+ gain3->setHintText( tr( "Band 3 Gain:" ), " dBV" );
+
+ Fader * gain4 = new Fader( &controls->m_gain4, "Band 4 Gain", this,
+ &m_fader_bg, &m_fader_empty, &m_fader_knob );
+ gain4->move( 127, 56 );
+ gain4->setDisplayConversion( false );
+ gain4->setHintText( tr( "Band 4 Gain:" ), " dBV" );
+
+ // leds
+ LedCheckBox * mute1 = new LedCheckBox( "M", this, tr( "Band 1 Mute" ), LedCheckBox::Red );
+ mute1->move( 11, 158 );
+ mute1->setModel( & controls->m_mute1 );
+ ToolTip::add( mute1, tr( "Mute Band 1" ) );
+
+ LedCheckBox * mute2 = new LedCheckBox( "M", this, tr( "Band 2 Mute" ), LedCheckBox::Red );
+ mute2->move( 51, 158 );
+ mute2->setModel( & controls->m_mute2 );
+ ToolTip::add( mute2, tr( "Mute Band 2" ) );
+
+ LedCheckBox * mute3 = new LedCheckBox( "M", this, tr( "Band 3 Mute" ), LedCheckBox::Red );
+ mute3->move( 91, 158 );
+ mute3->setModel( & controls->m_mute3 );
+ ToolTip::add( mute3, tr( "Mute Band 3" ) );
+
+ LedCheckBox * mute4 = new LedCheckBox( "M", this, tr( "Band 4 Mute" ), LedCheckBox::Red );
+ mute4->move( 131, 158 );
+ mute4->setModel( & controls->m_mute4 );
+ ToolTip::add( mute4, tr( "Mute Band 4" ) );
+}
diff --git a/plugins/CrossoverEQ/CrossoverEQControlDialog.h b/plugins/CrossoverEQ/CrossoverEQControlDialog.h
new file mode 100644
index 000000000..08c678886
--- /dev/null
+++ b/plugins/CrossoverEQ/CrossoverEQControlDialog.h
@@ -0,0 +1,50 @@
+/*
+ * CrossoverEQControlDialog.h - A native 4-band Crossover Equalizer
+ * good for simulating tonestacks or simple peakless (flat-band) equalization
+ *
+ * Copyright (c) 2014 Vesa Kivimäki
+ * Copyright (c) 2006-2014 Tobias Doerffel
+ *
+ * This file is part of LMMS - http://lmms.io
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public
+ * License along with this program (see COPYING); if not, write to the
+ * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301 USA.
+ *
+ */
+
+#ifndef CROSSOVEREQ_CONTROL_DIALOG_H
+#define CROSSOVEREQ_CONTROL_DIALOG_H
+
+#include
+#include "EffectControlDialog.h"
+
+class CrossoverEQControls;
+
+class CrossoverEQControlDialog : public EffectControlDialog
+{
+ Q_OBJECT
+public:
+ CrossoverEQControlDialog( CrossoverEQControls * controls );
+ virtual ~CrossoverEQControlDialog()
+ {
+ }
+
+private:
+ QPixmap m_fader_bg;
+ QPixmap m_fader_empty;
+ QPixmap m_fader_knob;
+};
+
+#endif
diff --git a/plugins/CrossoverEQ/CrossoverEQControls.cpp b/plugins/CrossoverEQ/CrossoverEQControls.cpp
new file mode 100644
index 000000000..9c58eabff
--- /dev/null
+++ b/plugins/CrossoverEQ/CrossoverEQControls.cpp
@@ -0,0 +1,116 @@
+/*
+ * CrossoverEQControls.cpp - A native 4-band Crossover Equalizer
+ * good for simulating tonestacks or simple peakless (flat-band) equalization
+ *
+ * Copyright (c) 2014 Vesa Kivimäki
+ * Copyright (c) 2006-2014 Tobias Doerffel
+ *
+ * This file is part of LMMS - http://lmms.io
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public
+ * License along with this program (see COPYING); if not, write to the
+ * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301 USA.
+ *
+ */
+
+#include "CrossoverEQControls.h"
+#include "CrossoverEQ.h"
+
+CrossoverEQControls::CrossoverEQControls( CrossoverEQEffect * eff ) :
+ EffectControls( eff ),
+ m_effect( eff ),
+ m_xover12( 125.f, 50.f, 10000.f, 1.0f, this, "Band 1/2 Crossover" ),
+ m_xover23( 1250.f, 50.f, 20000.f, 1.0f, this, "Band 2/3 Crossover" ),
+ m_xover34( 5000.f, 50.f, 20000.f, 1.0f, this, "Band 3/4 Crossover" ),
+ m_gain1( 0.f, -60.f, 30.f, 0.1f, this, "Band 1 Gain" ),
+ m_gain2( 0.f, -60.f, 30.f, 0.1f, this, "Band 2 Gain" ),
+ m_gain3( 0.f, -60.f, 30.f, 0.1f, this, "Band 3 Gain" ),
+ m_gain4( 0.f, -60.f, 30.f, 0.1f, this, "Band 4 Gain" ),
+ m_mute1( false, this, "Mute Band 1" ),
+ m_mute2( false, this, "Mute Band 2" ),
+ m_mute3( false, this, "Mute Band 3" ),
+ m_mute4( false, this, "Mute Band 4" )
+{
+ connect( Engine::mixer(), SIGNAL( sampleRateChanged() ), this, SLOT( sampleRateChanged() ) );
+ connect( &m_xover12, SIGNAL( dataChanged() ), this, SLOT( xover12Changed() ) );
+ connect( &m_xover23, SIGNAL( dataChanged() ), this, SLOT( xover23Changed() ) );
+ connect( &m_xover34, SIGNAL( dataChanged() ), this, SLOT( xover34Changed() ) );
+
+ m_xover12.setScaleLogarithmic( true );
+ m_xover23.setScaleLogarithmic( true );
+ m_xover34.setScaleLogarithmic( true );
+}
+
+void CrossoverEQControls::saveSettings( QDomDocument & doc, QDomElement & elem )
+{
+ m_xover12.saveSettings( doc, elem, "xover12" );
+ m_xover23.saveSettings( doc, elem, "xover23" );
+ m_xover34.saveSettings( doc, elem, "xover34" );
+
+ m_gain1.saveSettings( doc, elem, "gain1" );
+ m_gain2.saveSettings( doc, elem, "gain2" );
+ m_gain3.saveSettings( doc, elem, "gain3" );
+ m_gain4.saveSettings( doc, elem, "gain4" );
+
+ m_mute1.saveSettings( doc, elem, "mute1" );
+ m_mute2.saveSettings( doc, elem, "mute2" );
+ m_mute3.saveSettings( doc, elem, "mute3" );
+ m_mute4.saveSettings( doc, elem, "mute4" );
+}
+
+void CrossoverEQControls::loadSettings( const QDomElement & elem )
+{
+ m_xover12.loadSettings( elem, "xover12" );
+ m_xover23.loadSettings( elem, "xover23" );
+ m_xover34.loadSettings( elem, "xover34" );
+
+ m_gain1.loadSettings( elem, "gain1" );
+ m_gain2.loadSettings( elem, "gain2" );
+ m_gain3.loadSettings( elem, "gain3" );
+ m_gain4.loadSettings( elem, "gain4" );
+
+ m_mute1.loadSettings( elem, "mute1" );
+ m_mute2.loadSettings( elem, "mute2" );
+ m_mute3.loadSettings( elem, "mute3" );
+ m_mute4.loadSettings( elem, "mute4" );
+
+ m_effect->m_needsUpdate = true;
+}
+
+void CrossoverEQControls::xover12Changed()
+{
+ float v = m_xover12.value();
+ if( m_xover23.value() < v ) { m_xover23.setValue( v ); }
+ if( m_xover34.value() < v ) { m_xover34.setValue( v ); }
+}
+
+void CrossoverEQControls::xover23Changed()
+{
+ float v = m_xover23.value();
+ if( m_xover12.value() > v ) { m_xover12.setValue( v ); }
+ if( m_xover34.value() < v ) { m_xover34.setValue( v ); }
+}
+
+void CrossoverEQControls::xover34Changed()
+{
+ float v = m_xover34.value();
+ if( m_xover12.value() > v ) { m_xover12.setValue( v ); }
+ if( m_xover23.value() > v ) { m_xover23.setValue( v ); }
+}
+
+
+void CrossoverEQControls::sampleRateChanged()
+{
+ m_effect->sampleRateChanged();
+}
diff --git a/plugins/CrossoverEQ/CrossoverEQControls.h b/plugins/CrossoverEQ/CrossoverEQControls.h
new file mode 100644
index 000000000..18e87baee
--- /dev/null
+++ b/plugins/CrossoverEQ/CrossoverEQControls.h
@@ -0,0 +1,86 @@
+/*
+ * CrossoverEQControls.h - A native 4-band Crossover Equalizer
+ * good for simulating tonestacks or simple peakless (flat-band) equalization
+ *
+ * Copyright (c) 2014 Vesa Kivimäki
+ * Copyright (c) 2006-2014 Tobias Doerffel
+ *
+ * This file is part of LMMS - http://lmms.io
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public
+ * License along with this program (see COPYING); if not, write to the
+ * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301 USA.
+ *
+ */
+
+#ifndef CROSSOVEREQ_CONTROLS_H
+#define CROSSOVEREQ_CONTROLS_H
+
+#include "EffectControls.h"
+#include "CrossoverEQControlDialog.h"
+
+class CrossoverEQEffect;
+
+class CrossoverEQControls : public EffectControls
+{
+ Q_OBJECT
+public:
+ CrossoverEQControls( CrossoverEQEffect * eff );
+ virtual ~CrossoverEQControls() {}
+
+ virtual void saveSettings( QDomDocument & doc, QDomElement & elem );
+ virtual void loadSettings( const QDomElement & elem );
+ inline virtual QString nodeName() const
+ {
+ return( "crossoevereqcontrols" );
+ }
+
+ virtual int controlCount()
+ {
+ return( 11 );
+ }
+
+ virtual EffectControlDialog * createView()
+ {
+ return( new CrossoverEQControlDialog( this ) );
+ }
+
+private slots:
+ void xover12Changed();
+ void xover23Changed();
+ void xover34Changed();
+ void sampleRateChanged();
+
+private:
+ CrossoverEQEffect * m_effect;
+
+ FloatModel m_xover12;
+ FloatModel m_xover23;
+ FloatModel m_xover34;
+
+ FloatModel m_gain1;
+ FloatModel m_gain2;
+ FloatModel m_gain3;
+ FloatModel m_gain4;
+
+ BoolModel m_mute1;
+ BoolModel m_mute2;
+ BoolModel m_mute3;
+ BoolModel m_mute4;
+
+ friend class CrossoverEQControlDialog;
+ friend class CrossoverEQEffect;
+};
+
+#endif
diff --git a/plugins/CrossoverEQ/artwork.png b/plugins/CrossoverEQ/artwork.png
new file mode 100644
index 000000000..5510d2b3c
Binary files /dev/null and b/plugins/CrossoverEQ/artwork.png differ
diff --git a/plugins/CrossoverEQ/fader_bg.png b/plugins/CrossoverEQ/fader_bg.png
new file mode 100644
index 000000000..abe281105
Binary files /dev/null and b/plugins/CrossoverEQ/fader_bg.png differ
diff --git a/plugins/CrossoverEQ/fader_empty.png b/plugins/CrossoverEQ/fader_empty.png
new file mode 100644
index 000000000..4a95f05aa
Binary files /dev/null and b/plugins/CrossoverEQ/fader_empty.png differ
diff --git a/plugins/CrossoverEQ/fader_knob2.png b/plugins/CrossoverEQ/fader_knob2.png
new file mode 100644
index 000000000..252b485ee
Binary files /dev/null and b/plugins/CrossoverEQ/fader_knob2.png differ
diff --git a/plugins/DualFilter/DualFilterControlDialog.cpp b/plugins/DualFilter/DualFilterControlDialog.cpp
index 368d9dd34..4a769e410 100644
--- a/plugins/DualFilter/DualFilterControlDialog.cpp
+++ b/plugins/DualFilter/DualFilterControlDialog.cpp
@@ -38,7 +38,7 @@
name -> move( x, y ); \
name ->setModel( &controls-> model ); \
name ->setLabel( tr( label ) ); \
- name ->setHintText( tr( hint ) + " ", unit );
+ name ->setHintText( tr( hint ) , unit );
diff --git a/plugins/DualFilter/DualFilterControls.cpp b/plugins/DualFilter/DualFilterControls.cpp
index c7f2ba48a..b25b8953c 100644
--- a/plugins/DualFilter/DualFilterControls.cpp
+++ b/plugins/DualFilter/DualFilterControls.cpp
@@ -39,7 +39,7 @@ DualFilterControls::DualFilterControls( DualFilterEffect* effect ) :
m_enabled1Model( true, this, tr( "Filter 1 enabled" ) ),
m_filter1Model( this, tr( "Filter 1 type" ) ),
- m_cut1Model( 7000.0f, 1.0f, 14000.0f, 1.0f, this, tr( "Cutoff 1 frequency" ) ),
+ m_cut1Model( 7000.0f, 1.0f, 20000.0f, 1.0f, this, tr( "Cutoff 1 frequency" ) ),
m_res1Model( 0.5, BasicFilters<0>::minQ(), 10.0, 0.01, this, tr( "Q/Resonance 1" ) ),
m_gain1Model( 100.0f, 0.0f, 200.0f, 0.1f, this, tr( "Gain 1" ) ),
@@ -47,7 +47,7 @@ DualFilterControls::DualFilterControls( DualFilterEffect* effect ) :
m_enabled2Model( true, this, tr( "Filter 2 enabled" ) ),
m_filter2Model( this, tr( "Filter 2 type" ) ),
- m_cut2Model( 7000.0f, 1.0f, 14000.0f, 1.0f, this, tr( "Cutoff 2 frequency" ) ),
+ m_cut2Model( 7000.0f, 1.0f, 20000.0f, 1.0f, this, tr( "Cutoff 2 frequency" ) ),
m_res2Model( 0.5, BasicFilters<0>::minQ(), 10.0, 0.01, this, tr( "Q/Resonance 2" ) ),
m_gain2Model( 100.0f, 0.0f, 200.0f, 0.1f, this, tr( "Gain 2" ) )
{
diff --git a/plugins/MultitapEcho/MultitapEchoControlDialog.cpp b/plugins/MultitapEcho/MultitapEchoControlDialog.cpp
index 7780bf94c..5ff5fa900 100644
--- a/plugins/MultitapEcho/MultitapEchoControlDialog.cpp
+++ b/plugins/MultitapEcho/MultitapEchoControlDialog.cpp
@@ -82,19 +82,19 @@ MultitapEchoControlDialog::MultitapEchoControlDialog( MultitapEchoControls * con
stepLength->move( 100, 245 );
stepLength->setModel( & controls->m_stepLength );
stepLength->setLabel( tr( "Length" ) );
- stepLength->setHintText( tr( "Step length:" ) + " ", " ms" );
+ stepLength->setHintText( tr( "Step length:" ) , " ms" );
Knob * dryGain = new Knob( knobBright_26, this );
dryGain->move( 150, 245 );
dryGain->setModel( & controls->m_dryGain );
dryGain->setLabel( tr( "Dry" ) );
- dryGain->setHintText( tr( "Dry Gain:" ) + " ", " dBV" );
+ dryGain->setHintText( tr( "Dry Gain:" ) , " dBV" );
Knob * stages = new Knob( knobBright_26, this );
stages->move( 200, 245 );
stages->setModel( & controls->m_stages );
stages->setLabel( tr( "Stages" ) );
- stages->setHintText( tr( "Lowpass stages:" ) + " ", "x" );
+ stages->setHintText( tr( "Lowpass stages:" ) , "x" );
// switch led
LedCheckBox * swapInputs = new LedCheckBox( "Swap inputs", this, tr( "Swap inputs" ), LedCheckBox::Green );
diff --git a/plugins/audio_file_processor/audio_file_processor.cpp b/plugins/audio_file_processor/audio_file_processor.cpp
index d18145b70..ce390192a 100644
--- a/plugins/audio_file_processor/audio_file_processor.cpp
+++ b/plugins/audio_file_processor/audio_file_processor.cpp
@@ -543,7 +543,7 @@ AudioFileProcessorView::AudioFileProcessorView( Instrument * _instrument,
m_ampKnob = new Knob( knobBright_26, this );
m_ampKnob->setVolumeKnob( true );
m_ampKnob->move( 5, 108 );
- m_ampKnob->setHintText( tr( "Amplify:" )+" ", "%" );
+ m_ampKnob->setHintText( tr( "Amplify:" ), "%" );
m_ampKnob->setWhatsThis(
tr( "With this knob you can set the amplify ratio. When you "
"set a value of 100% your sample isn't changed. "
@@ -552,21 +552,21 @@ AudioFileProcessorView::AudioFileProcessorView( Instrument * _instrument,
m_startKnob = new AudioFileProcessorWaveView::knob( this );
m_startKnob->move( 45, 108 );
- m_startKnob->setHintText( tr( "Startpoint:" )+" ", "" );
+ m_startKnob->setHintText( tr( "Startpoint:" ), "" );
m_startKnob->setWhatsThis(
tr( "With this knob you can set the point where "
"AudioFileProcessor should begin playing your sample. " ) );
m_endKnob = new AudioFileProcessorWaveView::knob( this );
m_endKnob->move( 125, 108 );
- m_endKnob->setHintText( tr( "Endpoint:" )+" ", "" );
+ m_endKnob->setHintText( tr( "Endpoint:" ), "" );
m_endKnob->setWhatsThis(
tr( "With this knob you can set the point where "
"AudioFileProcessor should stop playing your sample. " ) );
m_loopKnob = new AudioFileProcessorWaveView::knob( this );
m_loopKnob->move( 85, 108 );
- m_loopKnob->setHintText( tr( "Loopback point:" )+" ", "" );
+ m_loopKnob->setHintText( tr( "Loopback point:" ), "" );
m_loopKnob->setWhatsThis(
tr( "With this knob you can set the point where "
"the loop starts. " ) );
diff --git a/plugins/bit_invader/bit_invader.cpp b/plugins/bit_invader/bit_invader.cpp
index 9fc371ae9..668a761c8 100644
--- a/plugins/bit_invader/bit_invader.cpp
+++ b/plugins/bit_invader/bit_invader.cpp
@@ -335,7 +335,7 @@ bitInvaderView::bitInvaderView( Instrument * _instrument,
m_sampleLengthKnob = new Knob( knobDark_28, this );
m_sampleLengthKnob->move( 6, 201 );
- m_sampleLengthKnob->setHintText( tr( "Sample Length" ) + " ", "" );
+ m_sampleLengthKnob->setHintText( tr( "Sample Length" ), "" );
m_graph = new Graph( this, Graph::NearestStyle, 204, 134 );
m_graph->move(23,59); // 55,120 - 2px border
diff --git a/plugins/carlabase/carla.cpp b/plugins/carlabase/carla.cpp
index ca2ebab13..0831bba50 100644
--- a/plugins/carlabase/carla.cpp
+++ b/plugins/carlabase/carla.cpp
@@ -251,16 +251,16 @@ intptr_t CarlaInstrument::handleDispatcher(const NativeHostDispatcherOpcode opco
switch (opcode)
{
- case HOST_OPCODE_NULL:
+ case NATIVE_HOST_OPCODE_NULL:
break;
- case HOST_OPCODE_UPDATE_PARAMETER:
- case HOST_OPCODE_UPDATE_MIDI_PROGRAM:
- case HOST_OPCODE_RELOAD_PARAMETERS:
- case HOST_OPCODE_RELOAD_MIDI_PROGRAMS:
- case HOST_OPCODE_RELOAD_ALL:
+ case NATIVE_HOST_OPCODE_UPDATE_PARAMETER:
+ case NATIVE_HOST_OPCODE_UPDATE_MIDI_PROGRAM:
+ case NATIVE_HOST_OPCODE_RELOAD_PARAMETERS:
+ case NATIVE_HOST_OPCODE_RELOAD_MIDI_PROGRAMS:
+ case NATIVE_HOST_OPCODE_RELOAD_ALL:
// nothing
break;
- case HOST_OPCODE_UI_UNAVAILABLE:
+ case NATIVE_HOST_OPCODE_UI_UNAVAILABLE:
handleUiClosed();
break;
}
@@ -459,7 +459,7 @@ PluginView* CarlaInstrument::instantiateView(QWidget* parent)
void CarlaInstrument::sampleRateChanged()
{
- fDescriptor->dispatcher(fHandle, PLUGIN_OPCODE_SAMPLE_RATE_CHANGED, 0, 0, nullptr, handleGetSampleRate());
+ fDescriptor->dispatcher(fHandle, NATIVE_PLUGIN_OPCODE_SAMPLE_RATE_CHANGED, 0, 0, nullptr, handleGetSampleRate());
}
// -------------------------------------------------------------------
diff --git a/plugins/delay/delaycontrols.cpp b/plugins/delay/delaycontrols.cpp
index f819de810..cde18048b 100644
--- a/plugins/delay/delaycontrols.cpp
+++ b/plugins/delay/delaycontrols.cpp
@@ -32,7 +32,7 @@
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_delayTimeModel( 0.5, 0.01, 20.0, 0.0001, 20000.0, this, tr( "Delay Samples" )) ,
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_lfoAmountModel(0.0, 0.0, 2.0, 0.0001, 2000.0, this, tr ( "Lfo Amount" ) )
diff --git a/plugins/delay/delaycontrolsdialog.cpp b/plugins/delay/delaycontrolsdialog.cpp
index fd4e6cfb9..80aeba068 100644
--- a/plugins/delay/delaycontrolsdialog.cpp
+++ b/plugins/delay/delaycontrolsdialog.cpp
@@ -31,40 +31,41 @@
DelayControlsDialog::DelayControlsDialog( DelayControls *controls ) :
- EffectControlDialog( controls )
+ EffectControlDialog( controls )
{
- setAutoFillBackground( true );
- QPalette pal;
- pal.setBrush( backgroundRole(), PLUGIN_NAME::getIconPixmap( "artwork" ) );
- setPalette( pal );
- setFixedSize( 200, 75 );
+ setAutoFillBackground( true );
+ QPalette pal;
+ pal.setBrush( backgroundRole(), PLUGIN_NAME::getIconPixmap( "artwork" ) );
+ setPalette( pal );
+ setFixedSize( 200, 75 );
TempoSyncKnob* sampleDelayKnob = new TempoSyncKnob( knobBright_26, this );
sampleDelayKnob->move( 20,10 );
sampleDelayKnob->setVolumeKnob( false );
sampleDelayKnob->setModel( &controls->m_delayTimeModel );
sampleDelayKnob->setLabel( tr( "Delay" ) );
- sampleDelayKnob->setHintText( tr( "Delay Time Seconds:" ) + " ", "" );
+ sampleDelayKnob->setHintText( tr( "Delay Time" ) + " ", " s" );
Knob * feedbackKnob = new Knob( knobBright_26, this );
feedbackKnob->move( 63,10 );
feedbackKnob->setVolumeKnob( true) ;
feedbackKnob->setModel( &controls->m_feedbackModel);
feedbackKnob->setLabel( tr( "Regen" ) );
- feedbackKnob->setHintText( tr ( "Feedback Amount:" ) + " ", "" );
+ feedbackKnob->setHintText( tr ( "Feedback Amount" ) + " " , "" );
TempoSyncKnob * lfoFreqKnob = new TempoSyncKnob( knobBright_26, this );
lfoFreqKnob->move( 106,10 );
lfoFreqKnob->setVolumeKnob( false );
lfoFreqKnob->setModel( &controls->m_lfoTimeModel );
lfoFreqKnob->setLabel( tr( "Rate" ) );
- lfoFreqKnob->setHintText( tr ( "Lfo Seconds:" ) + " ", "" );
+ lfoFreqKnob->setHintText( tr ( "Lfo") + " ", " s" );
TempoSyncKnob * lfoAmtKnob = new TempoSyncKnob( knobBright_26, this );
lfoAmtKnob->move( 150,10 );
lfoAmtKnob->setVolumeKnob( false );
lfoAmtKnob->setModel( &controls->m_lfoAmountModel );
lfoAmtKnob->setLabel( tr( "Lfo" ) );
- lfoAmtKnob->setHintText( tr ( "Lfo Amt:" ) + " ", "" );
+ lfoAmtKnob->setHintText( tr ( "Lfo Amt" ) + " " , " s" );
+
}
diff --git a/plugins/dynamics_processor/dynamics_processor_control_dialog.cpp b/plugins/dynamics_processor/dynamics_processor_control_dialog.cpp
index 9b5037106..5b820e1fa 100644
--- a/plugins/dynamics_processor/dynamics_processor_control_dialog.cpp
+++ b/plugins/dynamics_processor/dynamics_processor_control_dialog.cpp
@@ -63,7 +63,7 @@ dynProcControlDialog::dynProcControlDialog(
inputKnob -> move( 14, 251 );
inputKnob->setModel( &_controls->m_inputModel );
inputKnob->setLabel( tr( "INPUT" ) );
- inputKnob->setHintText( tr( "Input gain:" ) + " ", "" );
+ inputKnob->setHintText( tr( "Input gain:" ) , "" );
Knob * outputKnob = new Knob( knobBright_26, this );
outputKnob -> setVolumeKnob( true );
@@ -71,19 +71,19 @@ dynProcControlDialog::dynProcControlDialog(
outputKnob -> move( 54, 251 );
outputKnob->setModel( &_controls->m_outputModel );
outputKnob->setLabel( tr( "OUTPUT" ) );
- outputKnob->setHintText( tr( "Output gain:" ) + " ", "" );
+ outputKnob->setHintText( tr( "Output gain:" ) , "" );
Knob * attackKnob = new Knob( knobBright_26, this);
attackKnob -> move( 11, 291 );
attackKnob->setModel( &_controls->m_attackModel );
attackKnob->setLabel( tr( "ATTACK" ) );
- attackKnob->setHintText( tr( "Peak attack time:" ) + " ", "ms" );
+ attackKnob->setHintText( tr( "Peak attack time:" ) , "ms" );
Knob * releaseKnob = new Knob( knobBright_26, this );
releaseKnob -> move( 52, 291 );
releaseKnob->setModel( &_controls->m_releaseModel );
releaseKnob->setLabel( tr( "RELEASE" ) );
- releaseKnob->setHintText( tr( "Peak release time:" ) + " ", "ms" );
+ releaseKnob->setHintText( tr( "Peak release time:" ) , "ms" );
//waveform control buttons
diff --git a/plugins/flanger/flangercontrolsdialog.cpp b/plugins/flanger/flangercontrolsdialog.cpp
index 971208771..8b3c61df4 100644
--- a/plugins/flanger/flangercontrolsdialog.cpp
+++ b/plugins/flanger/flangercontrolsdialog.cpp
@@ -32,51 +32,51 @@
FlangerControlsDialog::FlangerControlsDialog( FlangerControls *controls ) :
- EffectControlDialog( controls )
+ EffectControlDialog( controls )
{
- setAutoFillBackground( true );
- QPalette pal;
- pal.setBrush( backgroundRole(), PLUGIN_NAME::getIconPixmap( "artwork" ) );
- setPalette( pal );
- setFixedSize( 200, 75 );
+ setAutoFillBackground( true );
+ QPalette pal;
+ pal.setBrush( backgroundRole(), PLUGIN_NAME::getIconPixmap( "artwork" ) );
+ setPalette( pal );
+ setFixedSize( 200, 75 );
- Knob* delayKnob = new Knob( knobBright_26, this );
- delayKnob->move( 20,10 );
- delayKnob->setVolumeKnob( false );
- delayKnob->setModel( &controls->m_delayTimeModel );
- delayKnob->setLabel( tr( "Delay" ) );
- delayKnob->setHintText( tr( "Delay Time :" ) + " ", "" );
+ Knob* delayKnob = new Knob( knobBright_26, this );
+ delayKnob->move( 20,10 );
+ delayKnob->setVolumeKnob( false );
+ delayKnob->setModel( &controls->m_delayTimeModel );
+ delayKnob->setLabel( tr( "Delay" ) );
+ delayKnob->setHintText( tr( "Delay Time:" ) + " ", "" );
- TempoSyncKnob * lfoFreqKnob = new TempoSyncKnob( knobBright_26, this );
- lfoFreqKnob->move( 53,10 );
- lfoFreqKnob->setVolumeKnob( false );
- lfoFreqKnob->setModel( &controls->m_lfoFrequencyModel );
- lfoFreqKnob->setLabel( tr( "Lfo Hz" ) );
- lfoFreqKnob->setHintText( tr ( "Lfo Hz:" ) + " ", "" );
+ TempoSyncKnob * lfoFreqKnob = new TempoSyncKnob( knobBright_26, this );
+ lfoFreqKnob->move( 53,10 );
+ lfoFreqKnob->setVolumeKnob( false );
+ lfoFreqKnob->setModel( &controls->m_lfoFrequencyModel );
+ lfoFreqKnob->setLabel( tr( "Lfo Hz" ) );
+ lfoFreqKnob->setHintText( tr ( "Lfo:" ) , "s" );
- Knob * lfoAmtKnob = new Knob( knobBright_26, this );
- lfoAmtKnob->move( 86,10 );
- lfoAmtKnob->setVolumeKnob( false );
- lfoAmtKnob->setModel( &controls->m_lfoAmountModel );
- lfoAmtKnob->setLabel( tr( "Amt" ) );
- lfoAmtKnob->setHintText( tr ( "Amt" ) + " ", "" );
+ Knob * lfoAmtKnob = new Knob( knobBright_26, this );
+ lfoAmtKnob->move( 86,10 );
+ lfoAmtKnob->setVolumeKnob( false );
+ lfoAmtKnob->setModel( &controls->m_lfoAmountModel );
+ lfoAmtKnob->setLabel( tr( "Amt" ) );
+ lfoAmtKnob->setHintText( tr ( "Amt:" ) , "" );
- Knob * feedbackKnob = new Knob( knobBright_26, this );
- feedbackKnob->move( 119,10 );
- feedbackKnob->setVolumeKnob( true) ;
- feedbackKnob->setModel( &controls->m_feedbackModel );
- feedbackKnob->setLabel( tr( "Regen" ) );
- feedbackKnob->setHintText( tr ( "Feedback Amount:" ) + " ", "" );
+ Knob * feedbackKnob = new Knob( knobBright_26, this );
+ feedbackKnob->move( 119,10 );
+ feedbackKnob->setVolumeKnob( true) ;
+ feedbackKnob->setModel( &controls->m_feedbackModel );
+ feedbackKnob->setLabel( tr( "Regen" ) );
+ feedbackKnob->setHintText( tr ( "Feedback Amount:" ) , "" );
- Knob * whiteNoiseKnob = new Knob( knobBright_26, this );
- whiteNoiseKnob->move( 150,10 );
- whiteNoiseKnob->setVolumeKnob( true) ;
- whiteNoiseKnob->setModel( &controls->m_whiteNoiseAmountModel );
- whiteNoiseKnob->setLabel( tr( "Noise" ) );
- whiteNoiseKnob->setHintText( tr ( "White Noise Amount:" ) + " ", "" );
+ Knob * whiteNoiseKnob = new Knob( knobBright_26, this );
+ whiteNoiseKnob->move( 150,10 );
+ whiteNoiseKnob->setVolumeKnob( true) ;
+ whiteNoiseKnob->setModel( &controls->m_whiteNoiseAmountModel );
+ whiteNoiseKnob->setLabel( tr( "Noise" ) );
+ whiteNoiseKnob->setHintText( tr ( "White Noise Amount:" ) , "" );
- LedCheckBox* invertCb = new LedCheckBox( tr( "" ), this );
- invertCb->move( 15,55 );
+ LedCheckBox* invertCb = new LedCheckBox( tr( "" ), this );
+ invertCb->move( 15,55 );
diff --git a/plugins/kicker/kicker.cpp b/plugins/kicker/kicker.cpp
index a3868a257..38149519f 100644
--- a/plugins/kicker/kicker.cpp
+++ b/plugins/kicker/kicker.cpp
@@ -280,43 +280,43 @@ kickerInstrumentView::kickerInstrumentView( Instrument * _instrument,
const int END_COL = COL1 + 48;
m_startFreqKnob = new kickerLargeKnob( this );
- m_startFreqKnob->setHintText( tr( "Start frequency:" ) + " ", "Hz" );
+ m_startFreqKnob->setHintText( tr( "Start frequency:" ), "Hz" );
m_startFreqKnob->move( COL1, ROW1 );
m_endFreqKnob = new kickerLargeKnob( this );
- m_endFreqKnob->setHintText( tr( "End frequency:" ) + " ", "Hz" );
+ m_endFreqKnob->setHintText( tr( "End frequency:" ), "Hz" );
m_endFreqKnob->move( END_COL, ROW1 );
m_slopeKnob = new kickerKnob( this );
- m_slopeKnob->setHintText( tr( "Frequency Slope:" ) + " ", "" );
+ m_slopeKnob->setHintText( tr( "Frequency Slope:" ), "" );
m_slopeKnob->move( COL3, ROW1 );
m_gainKnob = new kickerKnob( this );
- m_gainKnob->setHintText( tr( "Gain:" ) + " ", "" );
+ m_gainKnob->setHintText( tr( "Gain:" ), "" );
m_gainKnob->move( COL1, ROW3 );
m_decayKnob = new kickerEnvKnob( this );
- m_decayKnob->setHintText( tr( "Envelope Length:" ) + " ", "ms" );
+ m_decayKnob->setHintText( tr( "Envelope Length:" ), "ms" );
m_decayKnob->move( COL2, ROW3 );
m_envKnob = new kickerKnob( this );
- m_envKnob->setHintText( tr( "Envelope Slope:" ) + " ", "" );
+ m_envKnob->setHintText( tr( "Envelope Slope:" ), "" );
m_envKnob->move( COL3, ROW3 );
m_clickKnob = new kickerKnob( this );
- m_clickKnob->setHintText( tr( "Click:" ) + " ", "" );
+ m_clickKnob->setHintText( tr( "Click:" ), "" );
m_clickKnob->move( COL5, ROW1 );
m_noiseKnob = new kickerKnob( this );
- m_noiseKnob->setHintText( tr( "Noise:" ) + " ", "" );
+ m_noiseKnob->setHintText( tr( "Noise:" ), "" );
m_noiseKnob->move( COL5, ROW3 );
m_distKnob = new kickerKnob( this );
- m_distKnob->setHintText( tr( "Distortion Start:" ) + " ", "" );
+ m_distKnob->setHintText( tr( "Distortion Start:" ), "" );
m_distKnob->move( COL4, ROW2 );
m_distEndKnob = new kickerKnob( this );
- m_distEndKnob->setHintText( tr( "Distortion End:" ) + " ", "" );
+ m_distEndKnob->setHintText( tr( "Distortion End:" ), "" );
m_distEndKnob->move( COL5, ROW2 );
m_startNoteToggle = new LedCheckBox( "", this, "", LedCheckBox::Green );
diff --git a/plugins/lb302/lb302.cpp b/plugins/lb302/lb302.cpp
index 46e7be982..14ecb8fa1 100644
--- a/plugins/lb302/lb302.cpp
+++ b/plugins/lb302/lb302.cpp
@@ -788,16 +788,18 @@ void lb302Synth::processNote( NotePlayHandle * _n )
void lb302Synth::play( sampleFrame * _working_buffer )
{
+ m_notesMutex.lock();
while( ! m_notes.isEmpty() )
{
processNote( m_notes.takeFirst() );
};
+ m_notesMutex.unlock();
const fpp_t frames = Engine::mixer()->framesPerPeriod();
process( _working_buffer, frames );
instrumentTrack()->processAudioBuffer( _working_buffer, frames, NULL );
- release_frame = 0;
+// release_frame = 0; //removed for issue # 1432
}
@@ -824,22 +826,22 @@ lb302SynthView::lb302SynthView( Instrument * _instrument, QWidget * _parent ) :
// GUI
m_vcfCutKnob = new Knob( knobBright_26, this );
m_vcfCutKnob->move( 75, 130 );
- m_vcfCutKnob->setHintText( tr( "Cutoff Freq:" ) + " ", "" );
+ m_vcfCutKnob->setHintText( tr( "Cutoff Freq:" ), "" );
m_vcfCutKnob->setLabel( "" );
m_vcfResKnob = new Knob( knobBright_26, this );
m_vcfResKnob->move( 120, 130 );
- m_vcfResKnob->setHintText( tr( "Resonance:" ) + " ", "" );
+ m_vcfResKnob->setHintText( tr( "Resonance:" ), "" );
m_vcfResKnob->setLabel( "" );
m_vcfModKnob = new Knob( knobBright_26, this );
m_vcfModKnob->move( 165, 130 );
- m_vcfModKnob->setHintText( tr( "Env Mod:" ) + " ", "" );
+ m_vcfModKnob->setHintText( tr( "Env Mod:" ), "" );
m_vcfModKnob->setLabel( "" );
m_vcfDecKnob = new Knob( knobBright_26, this );
m_vcfDecKnob->move( 210, 130 );
- m_vcfDecKnob->setHintText( tr( "Decay:" ) + " ", "" );
+ m_vcfDecKnob->setHintText( tr( "Decay:" ), "" );
m_vcfDecKnob->setLabel( "" );
m_slideToggle = new LedCheckBox( "", this );
@@ -860,12 +862,12 @@ lb302SynthView::lb302SynthView( Instrument * _instrument, QWidget * _parent ) :
m_slideDecKnob = new Knob( knobBright_26, this );
m_slideDecKnob->move( 210, 75 );
- m_slideDecKnob->setHintText( tr( "Slide Decay:" ) + " ", "" );
+ m_slideDecKnob->setHintText( tr( "Slide Decay:" ), "" );
m_slideDecKnob->setLabel( "");
m_distKnob = new Knob( knobBright_26, this );
m_distKnob->move( 210, 190 );
- m_distKnob->setHintText( tr( "DIST:" ) + " ", "" );
+ m_distKnob->setHintText( tr( "DIST:" ), "" );
m_distKnob->setLabel( tr( ""));
diff --git a/plugins/monstro/Monstro.h b/plugins/monstro/Monstro.h
index c041ffe38..95dfa2933 100644
--- a/plugins/monstro/Monstro.h
+++ b/plugins/monstro/Monstro.h
@@ -46,14 +46,14 @@
#define makeknob( name, x, y, hint, unit, oname ) \
name = new Knob( knobStyled, view ); \
name ->move( x, y ); \
- name ->setHintText( tr( hint ) + " ", unit ); \
+ name ->setHintText( tr( hint ), unit ); \
name ->setObjectName( oname ); \
name ->setFixedSize( 20, 20 );
#define maketsknob( name, x, y, hint, unit, oname ) \
name = new TempoSyncKnob( knobStyled, view ); \
name ->move( x, y ); \
- name ->setHintText( tr( hint ) + " ", unit ); \
+ name ->setHintText( tr( hint ), unit ); \
name ->setObjectName( oname ); \
name ->setFixedSize( 20, 20 );
diff --git a/plugins/nes/Nes.h b/plugins/nes/Nes.h
index 645a980dc..3a75a7c06 100644
--- a/plugins/nes/Nes.h
+++ b/plugins/nes/Nes.h
@@ -38,7 +38,7 @@
#define makeknob( name, x, y, hint, unit, oname ) \
name = new Knob( knobStyled, this ); \
name ->move( x, y ); \
- name ->setHintText( tr( hint ) + " ", unit ); \
+ name ->setHintText( tr( hint ), unit ); \
name ->setObjectName( oname ); \
name ->setFixedSize( 29, 29 );
diff --git a/plugins/opl2/opl2instrument.cpp b/plugins/opl2/opl2instrument.cpp
index f99c38296..d1613a1aa 100644
--- a/plugins/opl2/opl2instrument.cpp
+++ b/plugins/opl2/opl2instrument.cpp
@@ -497,7 +497,7 @@ void opl2instrument::loadPatch(unsigned char inst[14]) {
void opl2instrument::tuneEqual(int center, float Hz) {
float tmp;
for(int n=0; n<128; ++n) {
- tmp = Hz*pow( 2, ( n - center ) / 12.0 + pitchbend / 1200.0 );
+ tmp = Hz*pow( 2.0, ( n - center ) * ( 1.0 / 12.0 ) + pitchbend * ( 1.0 / 1200.0 ) );
fnums[n] = Hz2fnum( tmp );
}
}
@@ -505,7 +505,7 @@ void opl2instrument::tuneEqual(int center, float Hz) {
// Find suitable F number in lowest possible block
int opl2instrument::Hz2fnum(float Hz) {
for(int block=0; block<8; ++block) {
- unsigned int fnum = Hz * pow(2, 20-block) / 49716;
+ unsigned int fnum = Hz * pow( 2.0, 20.0 - (double)block ) * ( 1.0 / 49716.0 );
if(fnum<1023) {
return fnum + (block << 10);
}
@@ -586,7 +586,7 @@ opl2instrumentView::opl2instrumentView( Instrument * _instrument,
#define KNOB_GEN(knobname, hinttext, hintunit,xpos,ypos) \
knobname = new Knob( knobStyled, this );\
- knobname->setHintText( tr(hinttext) + "", hintunit );\
+ knobname->setHintText( tr(hinttext), hintunit );\
knobname->setFixedSize(22,22);\
knobname->setCenterPointX(11.0);\
knobname->setCenterPointY(11.0);\
diff --git a/plugins/organic/organic.cpp b/plugins/organic/organic.cpp
index 08699d18d..95e229613 100644
--- a/plugins/organic/organic.cpp
+++ b/plugins/organic/organic.cpp
@@ -433,7 +433,7 @@ organicInstrumentView::organicInstrumentView( Instrument * _instrument,
m_fx1Knob = new organicKnob( this );
m_fx1Knob->move( 15, 201 );
m_fx1Knob->setFixedSize( 37, 47 );
- m_fx1Knob->setHintText( tr( "Distortion:" ) + " ", QString() );
+ m_fx1Knob->setHintText( tr( "Distortion:" ), QString() );
m_fx1Knob->setObjectName( "fx1Knob" );
m_fx1Knob->setWhatsThis( tr( "The distortion knob adds distortion to the output of the instrument. " ) );
@@ -442,7 +442,7 @@ organicInstrumentView::organicInstrumentView( Instrument * _instrument,
m_volKnob->setVolumeKnob( true );
m_volKnob->move( 60, 201 );
m_volKnob->setFixedSize( 37, 47 );
- m_volKnob->setHintText( tr( "Volume:" ) + " ", "%" );
+ m_volKnob->setHintText( tr( "Volume:" ), "%" );
m_volKnob->setObjectName( "volKnob" );
m_volKnob->setWhatsThis( tr( "The volume knob controls the volume of the output of the instrument. "
"It is cumulative with the instrument window's volume control. " ) );
@@ -513,7 +513,7 @@ void organicInstrumentView::modelChanged()
connect( &oi->m_osc[i]->m_oscModel, SIGNAL( dataChanged() ),
this, SLOT( updateKnobHint() ) );
- oscKnob->setHintText( tr( "Osc %1 waveform:" ).arg( i + 1 ) + " ", QString() );
+ oscKnob->setHintText( tr( "Osc %1 waveform:" ).arg( i + 1 ), QString() );
// setup volume-knob
Knob * volKnob = new Knob( knobStyled, this );
@@ -521,19 +521,19 @@ void organicInstrumentView::modelChanged()
volKnob->move( x + i * colWidth, y + rowHeight*1 );
volKnob->setFixedSize( 21, 21 );
volKnob->setHintText( tr( "Osc %1 volume:" ).arg(
- i + 1 ) + " ", "%" );
+ i + 1 ), "%" );
// setup panning-knob
Knob * panKnob = new organicKnob( this );
panKnob->move( x + i * colWidth, y + rowHeight*2 );
panKnob->setHintText( tr("Osc %1 panning:").arg(
- i + 1 ) + " ", "" );
+ i + 1 ), "" );
// setup knob for fine-detuning
Knob * detuneKnob = new organicKnob( this );
detuneKnob->move( x + i * colWidth, y + rowHeight*3 );
detuneKnob->setHintText( tr( "Osc %1 stereo detuning" ).arg( i + 1 )
- + " ", " " +
+ , " " +
tr( "cents" ) );
m_oscKnobs[i] = OscillatorKnobs( harmKnob, volKnob, oscKnob, panKnob, detuneKnob );
@@ -557,9 +557,9 @@ void organicInstrumentView::updateKnobHint()
const float harm = oi->m_osc[i]->m_harmModel.value();
const float wave = oi->m_osc[i]->m_oscModel.value();
- m_oscKnobs[i].m_harmKnob->setHintText( tr( "Osc %1 harmonic:" ) + " ", " (" +
+ m_oscKnobs[i].m_harmKnob->setHintText( tr( "Osc %1 harmonic:" ), " (" +
HARMONIC_NAMES[ static_cast( harm ) ] + ")" );
- m_oscKnobs[i].m_oscKnob->setHintText( tr( "Osc %1 waveform:" ) + " ", " (" +
+ m_oscKnobs[i].m_oscKnob->setHintText( tr( "Osc %1 waveform:" ), " (" +
WAVEFORM_NAMES[ static_cast( wave ) ] + ")" );
}
}
diff --git a/plugins/papu/papu_instrument.cpp b/plugins/papu/papu_instrument.cpp
index 947c9d841..8e0118164 100644
--- a/plugins/papu/papu_instrument.cpp
+++ b/plugins/papu/papu_instrument.cpp
@@ -361,11 +361,11 @@ void papuInstrument::playNote( NotePlayHandle * _n,
//PRNG Frequency = (1048576 Hz / (ratio + 1)) / 2 ^ (shiftclockfreq + 1)
char sopt=0;
char ropt=1;
- float fopt = 524288.0 / ( ropt * pow( 2, sopt+1 ) );
+ float fopt = 524288.0 / ( ropt * pow( 2.0, sopt + 1.0 ) );
float f;
for ( char s=0; s<16; s++ )
for ( char r=0; r<8; r++ ) {
- f = 524288.0 / ( r * pow( 2, s+1 ) );
+ f = 524288.0 / ( r * pow( 2.0, s + 1.0 ) );
if( fabs( freq-fopt ) > fabs( freq-f ) ) {
fopt = f;
ropt = r;
@@ -456,7 +456,7 @@ papuInstrumentView::papuInstrumentView( Instrument * _instrument,
setPalette( pal );
m_ch1SweepTimeKnob = new papuKnob( this );
- m_ch1SweepTimeKnob->setHintText( tr( "Sweep Time:" ) + " ", "" );
+ m_ch1SweepTimeKnob->setHintText( tr( "Sweep Time:" ), "" );
m_ch1SweepTimeKnob->move( 5 + 4*32, 106 );
ToolTip::add( m_ch1SweepTimeKnob, tr( "Sweep Time" ) );
m_ch1SweepTimeKnob->setWhatsThis( tr( "The amount of increase or"
@@ -464,7 +464,7 @@ papuInstrumentView::papuInstrumentView( Instrument * _instrument,
m_ch1SweepRtShiftKnob = new papuKnob( this );
m_ch1SweepRtShiftKnob->setHintText( tr( "Sweep RtShift amount:" )
- + " ", "" );
+ , "" );
m_ch1SweepRtShiftKnob->move( 5 + 3*32, 106 );
ToolTip::add( m_ch1SweepRtShiftKnob, tr( "Sweep RtShift amount" ) );
m_ch1SweepRtShiftKnob->setWhatsThis( tr( "The rate at which increase or"
@@ -472,7 +472,7 @@ papuInstrumentView::papuInstrumentView( Instrument * _instrument,
m_ch1WavePatternDutyKnob = new papuKnob( this );
m_ch1WavePatternDutyKnob->setHintText( tr( "Wave pattern duty:" )
- + " ", "" );
+ , "" );
m_ch1WavePatternDutyKnob->move( 5 + 2*32, 106 );
ToolTip::add( m_ch1WavePatternDutyKnob, tr( "Wave Pattern Duty" ) );
m_ch1WavePatternDutyKnob->setWhatsThis( tr( "The duty cycle is the ratio of"
@@ -481,14 +481,14 @@ papuInstrumentView::papuInstrumentView( Instrument * _instrument,
m_ch1VolumeKnob = new papuKnob( this );
m_ch1VolumeKnob->setHintText( tr( "Square Channel 1 Volume:" )
- + " ", "" );
+ , "" );
m_ch1VolumeKnob->move( 5, 106 );
ToolTip::add( m_ch1VolumeKnob, tr( "Square Channel 1 Volume:" ) );
m_ch1VolumeKnob->setWhatsThis( tr( "Square Channel 1 Volume" ) );
m_ch1SweepStepLengthKnob = new papuKnob( this );
m_ch1SweepStepLengthKnob->setHintText( tr( "Length of each step in sweep:" )
- + " ", "" );
+ , "" );
m_ch1SweepStepLengthKnob->move( 5 + 32, 106 );
ToolTip::add( m_ch1SweepStepLengthKnob, tr( "Length of each step in sweep" ) );
m_ch1SweepStepLengthKnob->setWhatsThis( tr( "The delay between step change" ) );
@@ -497,7 +497,7 @@ papuInstrumentView::papuInstrumentView( Instrument * _instrument,
m_ch2WavePatternDutyKnob = new papuKnob( this );
m_ch2WavePatternDutyKnob->setHintText( tr( "Wave pattern duty:" )
- + " ", "" );
+ , "" );
m_ch2WavePatternDutyKnob->move( 5 + 2*32, 155 );
ToolTip::add( m_ch2WavePatternDutyKnob, tr( "Wave pattern duty" ) );
m_ch2WavePatternDutyKnob->setWhatsThis( tr( "The duty cycle is the ratio of"
@@ -506,14 +506,14 @@ papuInstrumentView::papuInstrumentView( Instrument * _instrument,
m_ch2VolumeKnob = new papuKnob( this );
m_ch2VolumeKnob->setHintText( tr( "Square Channel 2 Volume:" )
- + " ", "" );
+ , "" );
m_ch2VolumeKnob->move( 5, 155 );
ToolTip::add( m_ch2VolumeKnob, tr( "Square Channel 2 Volume" ) );
m_ch2VolumeKnob->setWhatsThis( tr( "Square Channel 2 Volume" ) );
m_ch2SweepStepLengthKnob = new papuKnob( this );
m_ch2SweepStepLengthKnob->setHintText( tr( "Length of each step in sweep:" )
- + " ", "" );
+ , "" );
m_ch2SweepStepLengthKnob->move( 5 + 32, 155 );
ToolTip::add( m_ch2SweepStepLengthKnob, tr( "Length of each step in sweep" ) );
m_ch2SweepStepLengthKnob->setWhatsThis( tr( "The delay between step change" ) );
@@ -521,7 +521,7 @@ papuInstrumentView::papuInstrumentView( Instrument * _instrument,
m_ch3VolumeKnob = new papuKnob( this );
- m_ch3VolumeKnob->setHintText( tr( "Wave Channel Volume:" ) + " ", "" );
+ m_ch3VolumeKnob->setHintText( tr( "Wave Channel Volume:" ), "" );
m_ch3VolumeKnob->move( 5, 204 );
ToolTip::add( m_ch3VolumeKnob, tr( "Wave Channel Volume" ) );
m_ch3VolumeKnob->setWhatsThis( tr( "Wave Channel Volume" ) );
@@ -529,14 +529,14 @@ papuInstrumentView::papuInstrumentView( Instrument * _instrument,
m_ch4VolumeKnob = new papuKnob( this );
- m_ch4VolumeKnob->setHintText( tr( "Noise Channel Volume:" ) + " ", "" );
+ m_ch4VolumeKnob->setHintText( tr( "Noise Channel Volume:" ), "" );
m_ch4VolumeKnob->move( 144, 155 );
ToolTip::add( m_ch4VolumeKnob, tr( "Noise Channel Volume" ) );
m_ch4VolumeKnob->setWhatsThis( tr( "Noise Channel Volume" ) );
m_ch4SweepStepLengthKnob = new papuKnob( this );
m_ch4SweepStepLengthKnob->setHintText( tr( "Length of each step in sweep:" )
- + " ", "" );
+ , "" );
m_ch4SweepStepLengthKnob->move( 144 + 32, 155 );
ToolTip::add( m_ch4SweepStepLengthKnob, tr( "Length of each step in sweep" ) );
m_ch4SweepStepLengthKnob->setWhatsThis( tr( "The delay between step change" ) );
@@ -544,22 +544,22 @@ papuInstrumentView::papuInstrumentView( Instrument * _instrument,
m_so1VolumeKnob = new papuKnob( this );
- m_so1VolumeKnob->setHintText( tr( "SO1 Volume (Right):" ) + " ", "" );
+ m_so1VolumeKnob->setHintText( tr( "SO1 Volume (Right):" ), "" );
m_so1VolumeKnob->move( 5, 58 );
ToolTip::add( m_so1VolumeKnob, tr( "SO1 Volume (Right)" ) );
m_so2VolumeKnob = new papuKnob( this );
- m_so2VolumeKnob->setHintText( tr( "SO2 Volume (Left):" ) + " ", "" );
+ m_so2VolumeKnob->setHintText( tr( "SO2 Volume (Left):" ), "" );
m_so2VolumeKnob->move( 5 + 32, 58 );
ToolTip::add( m_so2VolumeKnob, tr( "SO2 Volume (Left)" ) );
m_trebleKnob = new papuKnob( this );
- m_trebleKnob->setHintText( tr( "Treble:" ) + " ", "" );
+ m_trebleKnob->setHintText( tr( "Treble:" ), "" );
m_trebleKnob->move( 5 + 2*32, 58 );
ToolTip::add( m_trebleKnob, tr( "Treble" ) );
m_bassKnob = new papuKnob( this );
- m_bassKnob->setHintText( tr( "Bass:" ) + " ", "" );
+ m_bassKnob->setHintText( tr( "Bass:" ), "" );
m_bassKnob->move( 5 + 3*32, 58 );
ToolTip::add( m_bassKnob, tr( "Bass" ) );
diff --git a/plugins/peak_controller_effect/peak_controller_effect_control_dialog.cpp b/plugins/peak_controller_effect/peak_controller_effect_control_dialog.cpp
index e1b76d31e..7675da5d0 100644
--- a/plugins/peak_controller_effect/peak_controller_effect_control_dialog.cpp
+++ b/plugins/peak_controller_effect/peak_controller_effect_control_dialog.cpp
@@ -53,32 +53,32 @@ PeakControllerEffectControlDialog::PeakControllerEffectControlDialog(
m_baseKnob = new Knob( knobBright_26, this );
m_baseKnob->setLabel( tr( "BASE" ) );
m_baseKnob->setModel( &_controls->m_baseModel );
- m_baseKnob->setHintText( tr( "Base amount:" ) + " ", "" );
+ m_baseKnob->setHintText( tr( "Base amount:" ) , "" );
m_amountKnob = new Knob( knobBright_26, this );
m_amountKnob->setLabel( tr( "AMNT" ) );
m_amountKnob->setModel( &_controls->m_amountModel );
- m_amountKnob->setHintText( tr( "Modulation amount:" ) + " ", "" );
+ m_amountKnob->setHintText( tr( "Modulation amount:" ) , "" );
m_amountMultKnob = new Knob( knobBright_26, this );
m_amountMultKnob->setLabel( tr( "MULT" ) );
m_amountMultKnob->setModel( &_controls->m_amountMultModel );
- m_amountMultKnob->setHintText( tr( "Amount Multiplicator:" ) + " ", "" );
+ m_amountMultKnob->setHintText( tr( "Amount Multiplicator:" ) , "" );
m_attackKnob = new Knob( knobBright_26, this );
m_attackKnob->setLabel( tr( "ATCK" ) );
m_attackKnob->setModel( &_controls->m_attackModel );
- m_attackKnob->setHintText( tr( "Attack:" ) + " ", "" );
+ m_attackKnob->setHintText( tr( "Attack:" ) , "" );
m_decayKnob = new Knob( knobBright_26, this );
m_decayKnob->setLabel( tr( "DCAY" ) );
m_decayKnob->setModel( &_controls->m_decayModel );
- m_decayKnob->setHintText( tr( "Release:" ) + " ", "" );
+ m_decayKnob->setHintText( tr( "Release:" ) , "" );
m_tresholdKnob = new Knob( knobBright_26, this );
m_tresholdKnob->setLabel( tr( "TRES" ) );
m_tresholdKnob->setModel( &_controls->m_tresholdModel );
- m_tresholdKnob->setHintText( tr( "Treshold:" ) + " ", "" );
+ m_tresholdKnob->setHintText( tr( "Treshold:" ) , "" );
l->addWidget( m_baseKnob );
l->addWidget( m_amountKnob );
diff --git a/plugins/sf2_player/sf2_player.cpp b/plugins/sf2_player/sf2_player.cpp
index 3de39524b..91d9d6e8f 100644
--- a/plugins/sf2_player/sf2_player.cpp
+++ b/plugins/sf2_player/sf2_player.cpp
@@ -870,7 +870,7 @@ sf2InstrumentView::sf2InstrumentView( Instrument * _instrument, QWidget * _paren
// Gain
m_gainKnob = new sf2Knob( this );
- m_gainKnob->setHintText( tr("Gain") + " ", "" );
+ m_gainKnob->setHintText( tr("Gain"), "" );
m_gainKnob->move( 86, 55 );
// vl->addWidget( m_gainKnob );
@@ -891,19 +891,19 @@ sf2InstrumentView::sf2InstrumentView( Instrument * _instrument, QWidget * _paren
m_reverbRoomSizeKnob = new sf2Knob( this );
- m_reverbRoomSizeKnob->setHintText( tr("Reverb Roomsize:") + " ", "" );
+ m_reverbRoomSizeKnob->setHintText( tr("Reverb Roomsize:"), "" );
m_reverbRoomSizeKnob->move( 93, 160 );
m_reverbDampingKnob = new sf2Knob( this );
- m_reverbDampingKnob->setHintText( tr("Reverb Damping:") + " ", "" );
+ m_reverbDampingKnob->setHintText( tr("Reverb Damping:"), "" );
m_reverbDampingKnob->move( 130, 160 );
m_reverbWidthKnob = new sf2Knob( this );
- m_reverbWidthKnob->setHintText( tr("Reverb Width:") + " ", "" );
+ m_reverbWidthKnob->setHintText( tr("Reverb Width:"), "" );
m_reverbWidthKnob->move( 167, 160 );
m_reverbLevelKnob = new sf2Knob( this );
- m_reverbLevelKnob->setHintText( tr("Reverb Level:") + " ", "" );
+ m_reverbLevelKnob->setHintText( tr("Reverb Level:"), "" );
m_reverbLevelKnob->move( 204, 160 );
/* hl->addWidget( m_reverbOnLed );
@@ -930,19 +930,19 @@ sf2InstrumentView::sf2InstrumentView( Instrument * _instrument, QWidget * _paren
"files that support it." ) );
m_chorusNumKnob = new sf2Knob( this );
- m_chorusNumKnob->setHintText( tr("Chorus Lines:") + " ", "" );
+ m_chorusNumKnob->setHintText( tr("Chorus Lines:"), "" );
m_chorusNumKnob->move( 93, 206 );
m_chorusLevelKnob = new sf2Knob( this );
- m_chorusLevelKnob->setHintText( tr("Chorus Level:") + " ", "" );
+ m_chorusLevelKnob->setHintText( tr("Chorus Level:"), "" );
m_chorusLevelKnob->move( 130 , 206 );
m_chorusSpeedKnob = new sf2Knob( this );
- m_chorusSpeedKnob->setHintText( tr("Chorus Speed:") + " ", "" );
+ m_chorusSpeedKnob->setHintText( tr("Chorus Speed:"), "" );
m_chorusSpeedKnob->move( 167 , 206 );
m_chorusDepthKnob = new sf2Knob( this );
- m_chorusDepthKnob->setHintText( tr("Chorus Depth:") + " ", "" );
+ m_chorusDepthKnob->setHintText( tr("Chorus Depth:"), "" );
m_chorusDepthKnob->move( 204 , 206 );
/*
hl->addWidget( m_chorusOnLed );
diff --git a/plugins/sid/sid_instrument.cpp b/plugins/sid/sid_instrument.cpp
index 0e64e83d7..03090e94d 100644
--- a/plugins/sid/sid_instrument.cpp
+++ b/plugins/sid/sid_instrument.cpp
@@ -487,15 +487,15 @@ sidInstrumentView::sidInstrumentView( Instrument * _instrument,
setPalette( pal );
m_volKnob = new sidKnob( this );
- m_volKnob->setHintText( tr( "Volume:" ) + " ", "" );
+ m_volKnob->setHintText( tr( "Volume:" ), "" );
m_volKnob->move( 7, 64 );
m_resKnob = new sidKnob( this );
- m_resKnob->setHintText( tr( "Resonance:" ) + " ", "" );
+ m_resKnob->setHintText( tr( "Resonance:" ), "" );
m_resKnob->move( 7 + 28, 64 );
m_cutKnob = new sidKnob( this );
- m_cutKnob->setHintText( tr( "Cutoff frequency:" ) + " ", "Hz" );
+ m_cutKnob->setHintText( tr( "Cutoff frequency:" ), "Hz" );
m_cutKnob->move( 7 + 2*28, 64 );
PixmapButton * hp_btn = new PixmapButton( this, NULL );
@@ -547,32 +547,32 @@ sidInstrumentView::sidInstrumentView( Instrument * _instrument,
for( int i = 0; i < 3; i++ )
{
Knob *ak = new sidKnob( this );
- ak->setHintText( tr("Attack:") + " ", "" );
+ ak->setHintText( tr("Attack:"), "" );
ak->move( 7, 114 + i*50 );
ak->setWhatsThis( tr ( "Attack rate determines how rapidly the output "
"of Voice %1 rises from zero to peak amplitude." ).arg( i+1 ) );
Knob *dk = new sidKnob( this );
- dk->setHintText( tr("Decay:") + " ", "" );
+ dk->setHintText( tr("Decay:") , "" );
dk->move( 7 + 28, 114 + i*50 );
dk->setWhatsThis( tr ( "Decay rate determines how rapidly the output "
"falls from the peak amplitude to the selected Sustain level." ) );
Knob *sk = new sidKnob( this );
- sk->setHintText( tr("Sustain:") + " ", "" );
+ sk->setHintText( tr("Sustain:"), "" );
sk->move( 7 + 2*28, 114 + i*50 );
sk->setWhatsThis( tr ( "Output of Voice %1 will remain at the selected "
"Sustain amplitude as long as the note is held." ).arg( i+1 ) );
Knob *rk = new sidKnob( this );
- rk->setHintText( tr("Release:") + " ", "" );
+ rk->setHintText( tr("Release:"), "" );
rk->move( 7 + 3*28, 114 + i*50 );
rk->setWhatsThis( tr ( "The output of of Voice %1 will fall from "
"Sustain amplitude to zero amplitude at the selected Release "
"rate." ).arg( i+1 ) );
Knob *pwk = new sidKnob( this );
- pwk->setHintText( tr("Pulse Width:") + " ", "" );
+ pwk->setHintText( tr("Pulse Width:"), "" );
pwk->move( 7 + 4*28, 114 + i*50 );
pwk->setWhatsThis( tr ( "The Pulse Width resolution allows the width "
"to be smoothly swept with no discernable stepping. The Pulse "
@@ -580,7 +580,7 @@ sidInstrumentView::sidInstrumentView( Instrument * _instrument,
" effect." ).arg( i+1 ) );
Knob *crsk = new sidKnob( this );
- crsk->setHintText( tr("Coarse:") + " ", " semitones" );
+ crsk->setHintText( tr("Coarse:"), " semitones" );
crsk->move( 147, 114 + i*50 );
crsk->setWhatsThis( tr ( "The Coarse detuning allows to detune Voice "
"%1 one octave up or down." ).arg( i+1 ) );
diff --git a/plugins/stereo_enhancer/stereoenhancer_control_dialog.cpp b/plugins/stereo_enhancer/stereoenhancer_control_dialog.cpp
index 42fabf427..9fc3daafa 100644
--- a/plugins/stereo_enhancer/stereoenhancer_control_dialog.cpp
+++ b/plugins/stereo_enhancer/stereoenhancer_control_dialog.cpp
@@ -40,7 +40,7 @@ stereoEnhancerControlDialog::stereoEnhancerControlDialog(
Knob * widthKnob = new Knob( knobBright_26, this );
widthKnob->setModel( &_controls->m_widthModel );
widthKnob->setLabel( tr( "WIDE" ) );
- widthKnob->setHintText( tr( "Width:" ) + " ", "samples" );
+ widthKnob->setHintText( tr( "Width:" ) , "samples" );
l->addWidget( widthKnob );
diff --git a/plugins/stereo_matrix/stereomatrix_control_dialog.cpp b/plugins/stereo_matrix/stereomatrix_control_dialog.cpp
index 3017973ea..587787dc0 100644
--- a/plugins/stereo_matrix/stereomatrix_control_dialog.cpp
+++ b/plugins/stereo_matrix/stereomatrix_control_dialog.cpp
@@ -49,22 +49,22 @@ stereoMatrixControlDialog::stereoMatrixControlDialog(
Knob * llKnob = new Knob( knobSmall_17, this );
llKnob->setModel( &_controls->m_llModel );
- llKnob->setHintText( tr( "Left to Left Vol:" ) + " ", "" );
+ llKnob->setHintText( tr( "Left to Left Vol:" ) , "" );
llKnob->move( 40, 60 );
Knob * lrKnob = new Knob( knobSmall_17, this );
lrKnob->setModel( &_controls->m_lrModel );
- lrKnob->setHintText( tr( "Left to Right Vol:" ) + " ", "" );
+ lrKnob->setHintText( tr( "Left to Right Vol:" ) , "" );
lrKnob->move( 40+28, 60);
Knob * rlKnob = new Knob( knobSmall_17, this );
rlKnob->setModel( &_controls->m_rlModel );
- rlKnob->setHintText( tr( "Right to Left Vol:" ) + " ", "" );
+ rlKnob->setHintText( tr( "Right to Left Vol:" ) , "" );
rlKnob->move( 40, 60+28 );
Knob * rrKnob = new Knob( knobSmall_17, this );
rrKnob->setModel( &_controls->m_rrModel );
- rrKnob->setHintText( tr( "Right to Right Vol:" ) + " ", "" );
+ rrKnob->setHintText( tr( "Right to Right Vol:" ) , "" );
rrKnob->move( 40+28, 60+28 );
}
diff --git a/plugins/stk/mallets/mallets.cpp b/plugins/stk/mallets/mallets.cpp
index 433a6883b..70d93d068 100644
--- a/plugins/stk/mallets/mallets.cpp
+++ b/plugins/stk/mallets/mallets.cpp
@@ -334,7 +334,7 @@ malletsInstrumentView::malletsInstrumentView( malletsInstrument * _instrument,
m_spreadKnob = new Knob( knobVintage_32, this );
m_spreadKnob->setLabel( tr( "Spread" ) );
m_spreadKnob->move( 190, 140 );
- m_spreadKnob->setHintText( tr( "Spread:" ) + " ", "" );
+ m_spreadKnob->setHintText( tr( "Spread:" ), "" );
}
@@ -366,27 +366,27 @@ QWidget * malletsInstrumentView::setupModalBarControls( QWidget * _parent )
m_hardnessKnob = new Knob( knobVintage_32, widget );
m_hardnessKnob->setLabel( tr( "Hardness" ) );
m_hardnessKnob->move( 30, 90 );
- m_hardnessKnob->setHintText( tr( "Hardness:" ) + " ", "" );
+ m_hardnessKnob->setHintText( tr( "Hardness:" ), "" );
m_positionKnob = new Knob( knobVintage_32, widget );
m_positionKnob->setLabel( tr( "Position" ) );
m_positionKnob->move( 110, 90 );
- m_positionKnob->setHintText( tr( "Position:" ) + " ", "" );
+ m_positionKnob->setHintText( tr( "Position:" ), "" );
m_vibratoGainKnob = new Knob( knobVintage_32, widget );
m_vibratoGainKnob->setLabel( tr( "Vib Gain" ) );
m_vibratoGainKnob->move( 30, 140 );
- m_vibratoGainKnob->setHintText( tr( "Vib Gain:" ) + " ", "" );
+ m_vibratoGainKnob->setHintText( tr( "Vib Gain:" ), "" );
m_vibratoFreqKnob = new Knob( knobVintage_32, widget );
m_vibratoFreqKnob->setLabel( tr( "Vib Freq" ) );
m_vibratoFreqKnob->move( 110, 140 );
- m_vibratoFreqKnob->setHintText( tr( "Vib Freq:" ) + " ", "" );
+ m_vibratoFreqKnob->setHintText( tr( "Vib Freq:" ), "" );
m_stickKnob = new Knob( knobVintage_32, widget );
m_stickKnob->setLabel( tr( "Stick Mix" ) );
m_stickKnob->move( 190, 90 );
- m_stickKnob->setHintText( tr( "Stick Mix:" ) + " ", "" );
+ m_stickKnob->setHintText( tr( "Stick Mix:" ), "" );
return( widget );
}
@@ -402,27 +402,27 @@ QWidget * malletsInstrumentView::setupTubeBellControls( QWidget * _parent )
m_modulatorKnob = new Knob( knobVintage_32, widget );
m_modulatorKnob->setLabel( tr( "Modulator" ) );
m_modulatorKnob->move( 30, 90 );
- m_modulatorKnob->setHintText( tr( "Modulator:" ) + " ", "" );
+ m_modulatorKnob->setHintText( tr( "Modulator:" ), "" );
m_crossfadeKnob = new Knob( knobVintage_32, widget );
m_crossfadeKnob->setLabel( tr( "Crossfade" ) );
m_crossfadeKnob->move( 110, 90 );
- m_crossfadeKnob->setHintText( tr( "Crossfade:" ) + " ", "" );
+ m_crossfadeKnob->setHintText( tr( "Crossfade:" ), "" );
m_lfoSpeedKnob = new Knob( knobVintage_32, widget );
m_lfoSpeedKnob->setLabel( tr( "LFO Speed" ) );
m_lfoSpeedKnob->move( 30, 140 );
- m_lfoSpeedKnob->setHintText( tr( "LFO Speed:" ) + " ", "" );
+ m_lfoSpeedKnob->setHintText( tr( "LFO Speed:" ), "" );
m_lfoDepthKnob = new Knob( knobVintage_32, widget );
m_lfoDepthKnob->setLabel( tr( "LFO Depth" ) );
m_lfoDepthKnob->move( 110, 140 );
- m_lfoDepthKnob->setHintText( tr( "LFO Depth:" ) + " ", "" );
+ m_lfoDepthKnob->setHintText( tr( "LFO Depth:" ), "" );
m_adsrKnob = new Knob( knobVintage_32, widget );
m_adsrKnob->setLabel( tr( "ADSR" ) );
m_adsrKnob->move( 190, 90 );
- m_adsrKnob->setHintText( tr( "ADSR:" ) + " ", "" );
+ m_adsrKnob->setHintText( tr( "ADSR:" ), "" );
return( widget );
}
@@ -442,22 +442,22 @@ QWidget * malletsInstrumentView::setupBandedWGControls( QWidget * _parent )
m_pressureKnob = new Knob( knobVintage_32, widget );
m_pressureKnob->setLabel( tr( "Pressure" ) );
m_pressureKnob->move( 30, 90 );
- m_pressureKnob->setHintText( tr( "Pressure:" ) + " ", "" );
+ m_pressureKnob->setHintText( tr( "Pressure:" ), "" );
m_motionKnob = new Knob( knobVintage_32, widget );
m_motionKnob->setLabel( tr( "Motion" ) );
m_motionKnob->move( 110, 90 );
- m_motionKnob->setHintText( tr( "Motion:" ) + " ", "" );
+ m_motionKnob->setHintText( tr( "Motion:" ), "" );
m_velocityKnob = new Knob( knobVintage_32, widget );
m_velocityKnob->setLabel( tr( "Speed" ) );
m_velocityKnob->move( 30, 140 );
- m_velocityKnob->setHintText( tr( "Speed:" ) + " ", "" );
+ m_velocityKnob->setHintText( tr( "Speed:" ), "" );
m_vibratoKnob = new Knob( knobVintage_32, widget, tr( "Vibrato" ) );
m_vibratoKnob->setLabel( tr( "Vibrato" ) );
m_vibratoKnob->move( 110, 140 );
- m_vibratoKnob->setHintText( tr( "Vibrato:" ) + " ", "" );
+ m_vibratoKnob->setHintText( tr( "Vibrato:" ), "" );
return( widget );
}
diff --git a/plugins/triple_oscillator/TripleOscillator.cpp b/plugins/triple_oscillator/TripleOscillator.cpp
index 360b7ad24..cdb35606c 100644
--- a/plugins/triple_oscillator/TripleOscillator.cpp
+++ b/plugins/triple_oscillator/TripleOscillator.cpp
@@ -555,7 +555,7 @@ TripleOscillatorView::TripleOscillatorView( Instrument * _instrument,
vk->setFixedSize( 28, 35 );
vk->move( 6, knob_y );
vk->setHintText( tr( "Osc %1 volume:" ).arg(
- i+1 ) + " ", "%" );
+ i+1 ), "%" );
vk->setWhatsThis(
tr( "With this knob you can set the volume of "
"oscillator %1. When setting a value of 0 the "
@@ -566,7 +566,7 @@ TripleOscillatorView::TripleOscillatorView( Instrument * _instrument,
// setup panning-knob
Knob * pk = new TripleOscKnob( this );
pk->move( 35, knob_y );
- pk->setHintText( tr("Osc %1 panning:").arg( i + 1 ) + " ", "" );
+ pk->setHintText( tr("Osc %1 panning:").arg( i + 1 ), "" );
pk->setWhatsThis(
tr( "With this knob you can set the panning of the "
"oscillator %1. A value of -100 means 100% "
@@ -576,8 +576,8 @@ TripleOscillatorView::TripleOscillatorView( Instrument * _instrument,
// setup coarse-knob
Knob * ck = new TripleOscKnob( this );
ck->move( 82, knob_y );
- ck->setHintText( tr( "Osc %1 coarse detuning:" ).arg( i + 1 ) +
- " ", " " + tr( "semitones" ) );
+ ck->setHintText( tr( "Osc %1 coarse detuning:" ).arg( i + 1 )
+ , " " + tr( "semitones" ) );
ck->setWhatsThis(
tr( "With this knob you can set the coarse detuning of "
"oscillator %1. You can detune the oscillator "
@@ -590,7 +590,7 @@ TripleOscillatorView::TripleOscillatorView( Instrument * _instrument,
Knob * flk = new TripleOscKnob( this );
flk->move( 111, knob_y );
flk->setHintText( tr( "Osc %1 fine detuning left:" ).
- arg( i + 1 ) + " ",
+ arg( i + 1 ),
" " + tr( "cents" ) );
flk->setWhatsThis(
tr( "With this knob you can set the fine detuning of "
@@ -603,7 +603,7 @@ TripleOscillatorView::TripleOscillatorView( Instrument * _instrument,
Knob * frk = new TripleOscKnob( this );
frk->move( 140, knob_y );
frk->setHintText( tr( "Osc %1 fine detuning right:" ).
- arg( i + 1 ) + " ",
+ arg( i + 1 ),
" " + tr( "cents" ) );
frk->setWhatsThis(
tr( "With this knob you can set the fine detuning of "
@@ -617,7 +617,7 @@ TripleOscillatorView::TripleOscillatorView( Instrument * _instrument,
Knob * pok = new TripleOscKnob( this );
pok->move( 188, knob_y );
pok->setHintText( tr( "Osc %1 phase-offset:" ).
- arg( i + 1 ) + " ",
+ arg( i + 1 ),
" " + tr( "degrees" ) );
pok->setWhatsThis(
tr( "With this knob you can set the phase-offset of "
@@ -633,7 +633,7 @@ TripleOscillatorView::TripleOscillatorView( Instrument * _instrument,
Knob * spdk = new TripleOscKnob( this );
spdk->move( 217, knob_y );
spdk->setHintText( tr("Osc %1 stereo phase-detuning:" ).
- arg( i + 1 ) + " ",
+ arg( i + 1 ),
" " + tr( "degrees" ) );
spdk->setWhatsThis(
tr( "With this knob you can set the stereo phase-"
diff --git a/plugins/vibed/vibed.cpp b/plugins/vibed/vibed.cpp
index d48297779..d74b654e2 100644
--- a/plugins/vibed/vibed.cpp
+++ b/plugins/vibed/vibed.cpp
@@ -361,14 +361,14 @@ vibedView::vibedView( Instrument * _instrument,
m_volumeKnob = new Knob( knobBright_26, this );
m_volumeKnob->setVolumeKnob( true );
m_volumeKnob->move( 103, 142 );
- m_volumeKnob->setHintText( tr( "Volume:" ) + " ", "" );
+ m_volumeKnob->setHintText( tr( "Volume:" ), "" );
m_volumeKnob->setWhatsThis( tr( "The 'V' knob sets the volume "
"of the selected string." ) );
m_stiffnessKnob = new Knob( knobBright_26, this );
m_stiffnessKnob->move( 129, 142 );
- m_stiffnessKnob->setHintText( tr( "String stiffness:" ) +
- " ", "" );
+ m_stiffnessKnob->setHintText( tr( "String stiffness:" )
+ , "" );
m_stiffnessKnob->setWhatsThis( tr(
"The 'S' knob sets the stiffness of the selected string. The stiffness "
"of the string affects how long the string will ring out. The lower "
@@ -377,15 +377,15 @@ vibedView::vibedView( Instrument * _instrument,
m_pickKnob = new Knob( knobBright_26, this );
m_pickKnob->move( 153, 142 );
- m_pickKnob->setHintText( tr( "Pick position:" ) + " ", "" );
+ m_pickKnob->setHintText( tr( "Pick position:" ), "" );
m_pickKnob->setWhatsThis( tr(
"The 'P' knob sets the position where the selected string will be 'picked'. "
"The lower the setting the closer the pick is to the bridge." ) );
m_pickupKnob = new Knob( knobBright_26, this );
m_pickupKnob->move( 177, 142 );
- m_pickupKnob->setHintText( tr( "Pickup position:" ) +
- " ", "" );
+ m_pickupKnob->setHintText( tr( "Pickup position:" )
+ , "" );
m_pickupKnob->setWhatsThis( tr(
"The 'PU' knob sets the position where the vibrations will be monitored "
"for the selected string. The lower the setting, the closer the "
@@ -393,14 +393,14 @@ vibedView::vibedView( Instrument * _instrument,
m_panKnob = new Knob( knobBright_26, this );
m_panKnob->move( 105, 187 );
- m_panKnob->setHintText( tr( "Pan:" ) + " ", "" );
+ m_panKnob->setHintText( tr( "Pan:" ), "" );
m_panKnob->setWhatsThis( tr(
"The Pan knob determines the location of the selected string in the stereo "
"field." ) );
m_detuneKnob = new Knob( knobBright_26, this );
m_detuneKnob->move( 150, 187 );
- m_detuneKnob->setHintText( tr( "Detune:" ) + " ", "" );
+ m_detuneKnob->setHintText( tr( "Detune:" ), "" );
m_detuneKnob->setWhatsThis( tr(
"The Detune knob modifies the pitch of the selected string. Settings less "
"than zero will cause the string to sound flat. Settings greater than zero "
@@ -408,8 +408,8 @@ vibedView::vibedView( Instrument * _instrument,
m_randomKnob = new Knob( knobBright_26, this );
m_randomKnob->move( 194, 187 );
- m_randomKnob->setHintText( tr( "Fuzziness:" ) +
- " ", "" );
+ m_randomKnob->setHintText( tr( "Fuzziness:" )
+ , "" );
m_randomKnob->setWhatsThis( tr(
"The Slap knob adds a bit of fuzz to the selected string which is most "
"apparent during the attack, though it can also be used to make the string "
@@ -417,8 +417,8 @@ vibedView::vibedView( Instrument * _instrument,
m_lengthKnob = new Knob( knobBright_26, this );
m_lengthKnob->move( 23, 193 );
- m_lengthKnob->setHintText( tr( "Length:" ) +
- " ", "" );
+ m_lengthKnob->setHintText( tr( "Length:" )
+ , "" );
m_lengthKnob->setWhatsThis( tr(
"The Length knob sets the length of the selected string. Longer strings "
"will both ring longer and sound brighter, however, they will also eat up "
@@ -427,7 +427,7 @@ vibedView::vibedView( Instrument * _instrument,
m_impulse = new LedCheckBox( "", this );
m_impulse->move( 23, 94 );
ToolTip::add( m_impulse,
- tr( "Impulse or initial state" ) );
+ tr( "Impulse or initial state" ) );
m_impulse->setWhatsThis( tr(
"The 'Imp' selector determines whether the waveform in the graph is to be "
"treated as an impulse imparted to the string by the pick or the initial "
diff --git a/plugins/watsyn/Watsyn.h b/plugins/watsyn/Watsyn.h
index b8413f7f8..31e3625db 100644
--- a/plugins/watsyn/Watsyn.h
+++ b/plugins/watsyn/Watsyn.h
@@ -41,14 +41,14 @@
#define makeknob( name, x, y, hint, unit, oname ) \
name = new Knob( knobStyled, this ); \
name ->move( x, y ); \
- name ->setHintText( tr( hint ) + " ", unit ); \
+ name ->setHintText( tr( hint ), unit ); \
name ->setObjectName( oname ); \
name ->setFixedSize( 19, 19 );
#define maketsknob( name, x, y, hint, unit, oname ) \
name = new TempoSyncKnob( knobStyled, this ); \
name ->move( x, y ); \
- name ->setHintText( tr( hint ) + " ", unit ); \
+ name ->setHintText( tr( hint ), unit ); \
name ->setObjectName( oname ); \
name ->setFixedSize( 19, 19 );
diff --git a/plugins/waveshaper/waveshaper_control_dialog.cpp b/plugins/waveshaper/waveshaper_control_dialog.cpp
index 236fc70d4..90e1c964f 100644
--- a/plugins/waveshaper/waveshaper_control_dialog.cpp
+++ b/plugins/waveshaper/waveshaper_control_dialog.cpp
@@ -63,7 +63,7 @@ waveShaperControlDialog::waveShaperControlDialog(
inputKnob -> move( 14, 251 );
inputKnob->setModel( &_controls->m_inputModel );
inputKnob->setLabel( tr( "INPUT" ) );
- inputKnob->setHintText( tr( "Input gain:" ) + " ", "" );
+ inputKnob->setHintText( tr( "Input gain:" ) , "" );
Knob * outputKnob = new Knob( knobBright_26, this );
outputKnob -> setVolumeKnob( true );
@@ -71,7 +71,7 @@ waveShaperControlDialog::waveShaperControlDialog(
outputKnob -> move( 54, 251 );
outputKnob->setModel( &_controls->m_outputModel );
outputKnob->setLabel( tr( "OUTPUT" ) );
- outputKnob->setHintText( tr( "Output gain:" ) + " ", "" );
+ outputKnob->setHintText( tr( "Output gain:" ), "" );
PixmapButton * resetButton = new PixmapButton( this, tr("Reset waveform") );
resetButton -> move( 164, 251 );
diff --git a/plugins/zynaddsubfx/ZynAddSubFx.cpp b/plugins/zynaddsubfx/ZynAddSubFx.cpp
index b4ba7f15a..bdb0c6e1f 100644
--- a/plugins/zynaddsubfx/ZynAddSubFx.cpp
+++ b/plugins/zynaddsubfx/ZynAddSubFx.cpp
@@ -498,31 +498,31 @@ ZynAddSubFxView::ZynAddSubFxView( Instrument * _instrument, QWidget * _parent )
l->setHorizontalSpacing( 10 );
m_portamento = new Knob( knobBright_26, this );
- m_portamento->setHintText( tr( "Portamento:" ) + "", "" );
+ m_portamento->setHintText( tr( "Portamento:" ), "" );
m_portamento->setLabel( tr( "PORT" ) );
m_filterFreq = new Knob( knobBright_26, this );
- m_filterFreq->setHintText( tr( "Filter Frequency:" ) + "", "" );
+ m_filterFreq->setHintText( tr( "Filter Frequency:" ), "" );
m_filterFreq->setLabel( tr( "FREQ" ) );
m_filterQ = new Knob( knobBright_26, this );
- m_filterQ->setHintText( tr( "Filter Resonance:" ) + "", "" );
+ m_filterQ->setHintText( tr( "Filter Resonance:" ), "" );
m_filterQ->setLabel( tr( "RES" ) );
m_bandwidth = new Knob( knobBright_26, this );
- m_bandwidth->setHintText( tr( "Bandwidth:" ) + "", "" );
+ m_bandwidth->setHintText( tr( "Bandwidth:" ), "" );
m_bandwidth->setLabel( tr( "BW" ) );
m_fmGain = new Knob( knobBright_26, this );
- m_fmGain->setHintText( tr( "FM Gain:" ) + "", "" );
+ m_fmGain->setHintText( tr( "FM Gain:" ), "" );
m_fmGain->setLabel( tr( "FM GAIN" ) );
m_resCenterFreq = new Knob( knobBright_26, this );
- m_resCenterFreq->setHintText( tr( "Resonance center frequency:" ) + "", "" );
+ m_resCenterFreq->setHintText( tr( "Resonance center frequency:" ), "" );
m_resCenterFreq->setLabel( tr( "RES CF" ) );
m_resBandwidth = new Knob( knobBright_26, this );
- m_resBandwidth->setHintText( tr( "Resonance bandwidth:" ) + "", "" );
+ m_resBandwidth->setHintText( tr( "Resonance bandwidth:" ), "" );
m_resBandwidth->setLabel( tr( "RES BW" ) );
m_forwardMidiCC = new LedCheckBox( tr( "Forward MIDI Control Changes" ), this );
diff --git a/src/core/ConfigManager.cpp b/src/core/ConfigManager.cpp
index 9c1634f42..c556870c3 100644
--- a/src/core/ConfigManager.cpp
+++ b/src/core/ConfigManager.cpp
@@ -290,7 +290,13 @@ void ConfigManager::loadConfigFile()
node = node.nextSibling();
}
- if( value( "paths", "artwork" ) != "" )
+ // don't use dated theme folders as they break the UI (i.e. 0.4 != 1.0, etc)
+ bool use_artwork_path =
+ root.attribute( "version" ).startsWith(
+ QString::number( LMMS_VERSION_MAJOR ) + "." +
+ QString::number( LMMS_VERSION_MINOR ) );
+
+ if( use_artwork_path && value( "paths", "artwork" ) != "" )
{
m_artworkDir = value( "paths", "artwork" );
if( !QDir( m_artworkDir ).exists() )
diff --git a/src/core/Engine.cpp b/src/core/Engine.cpp
index 67a6a669f..d744af1c7 100644
--- a/src/core/Engine.cpp
+++ b/src/core/Engine.cpp
@@ -115,6 +115,7 @@ void Engine::init( const bool _has_gui )
void Engine::destroy()
{
+ s_projectJournal->stopAllJournalling();
s_mixer->stopProcessing();
deleteHelper( &s_projectNotes );
diff --git a/src/core/FxMixer.cpp b/src/core/FxMixer.cpp
index b1494e00d..358e31171 100644
--- a/src/core/FxMixer.cpp
+++ b/src/core/FxMixer.cpp
@@ -100,11 +100,10 @@ inline void FxChannel::processed()
void FxChannel::incrementDeps()
{
m_dependenciesMet.ref();
- if( m_dependenciesMet >= m_receives.size() )
+ if( m_dependenciesMet >= m_receives.size() && ! m_queued )
{
m_queued = true;
MixerWorkerThread::addJob( this );
- m_dependenciesMet = 0;
}
}
@@ -174,7 +173,7 @@ void FxChannel::doProcessing()
// only start fxchain when we have input...
m_fxChain.startRunning();
}
-
+
m_stillRunning = m_fxChain.processAudioBuffer( m_buffer, fpp, m_hasInput );
m_peakLeft = qMax( m_peakLeft, Engine::mixer()->peakValueLeft( m_buffer, fpp ) * v );
@@ -184,8 +183,8 @@ void FxChannel::doProcessing()
{
m_peakLeft = m_peakRight = 0.0f;
}
-
- // increment dependency counter of all receivers
+
+ // increment dependency counter of all receivers
processed();
}
@@ -430,7 +429,7 @@ FxRoute * FxMixer::createRoute( FxChannel * from, FxChannel * to, float amount )
// add us to fxmixer's list
Engine::fxMixer()->m_fxRoutes.append( route );
m_sendsMutex.unlock();
-
+
return route;
}
@@ -601,9 +600,6 @@ void FxMixer::masterMix( sampleFrame * _buf )
: m_fxChannels[0]->m_volumeModel.value();
MixHelpers::addSanitizedMultiplied( _buf, m_fxChannels[0]->m_buffer, v, fpp );
- m_fxChannels[0]->m_peakLeft *= Engine::mixer()->masterGain();
- m_fxChannels[0]->m_peakRight *= Engine::mixer()->masterGain();
-
// clear all channel buffers and
// reset channel process state
for( int i = 0; i < numChannels(); ++i)
@@ -613,6 +609,7 @@ void FxMixer::masterMix( sampleFrame * _buf )
m_fxChannels[i]->m_queued = false;
// also reset hasInput
m_fxChannels[i]->m_hasInput = false;
+ m_fxChannels[i]->m_dependenciesMet = 0;
}
}
@@ -688,7 +685,7 @@ void FxMixer::saveSettings( QDomDocument & _doc, QDomElement & _this )
ch->m_sends[si]->amount()->saveSettings( _doc, sendsDom, "amount" );
}
}
-}
+}
// make sure we have at least num channels
void FxMixer::allocateChannelsTo(int num)
diff --git a/src/core/JournallingObject.cpp b/src/core/JournallingObject.cpp
index b2eea2d6d..804483580 100644
--- a/src/core/JournallingObject.cpp
+++ b/src/core/JournallingObject.cpp
@@ -70,14 +70,19 @@ void JournallingObject::addJournalCheckPoint()
QDomElement JournallingObject::saveState( QDomDocument & _doc,
QDomElement & _parent )
{
- QDomElement _this = SerializingObject::saveState( _doc, _parent );
+ if( isJournalling() )
+ {
+ QDomElement _this = SerializingObject::saveState( _doc, _parent );
- QDomElement journalNode = _doc.createElement( "journallingObject" );
- journalNode.setAttribute( "id", id() );
- journalNode.setAttribute( "metadata", true );
- _this.appendChild( journalNode );
+ QDomElement journalNode = _doc.createElement( "journallingObject" );
+ journalNode.setAttribute( "id", id() );
+ journalNode.setAttribute( "metadata", true );
+ _this.appendChild( journalNode );
- return _this;
+ return _this;
+ } else {
+ return QDomElement();
+ }
}
diff --git a/src/core/ProjectJournal.cpp b/src/core/ProjectJournal.cpp
index 8a8d8c466..77c5c461f 100644
--- a/src/core/ProjectJournal.cpp
+++ b/src/core/ProjectJournal.cpp
@@ -168,5 +168,17 @@ void ProjectJournal::clearJournal()
}
}
+void ProjectJournal::stopAllJournalling()
+{
+ for( JoIdMap::Iterator it = m_joIDs.begin(); it != m_joIDs.end(); ++it)
+ {
+ if( it.value() != NULL )
+ {
+ it.value()->setJournalling(false);
+ }
+ }
+ setJournalling(false);
+}
+
diff --git a/src/core/SampleBuffer.cpp b/src/core/SampleBuffer.cpp
index 9b7b5fa00..01778653f 100644
--- a/src/core/SampleBuffer.cpp
+++ b/src/core/SampleBuffer.cpp
@@ -957,6 +957,7 @@ void SampleBuffer::visualize( QPainter & _p, const QRect & _dr,
_p.drawPolyline( l, nb_frames / fpp );
_p.drawPolyline( r, nb_frames / fpp );
delete[] l;
+ delete[] r;
}
diff --git a/src/core/Song.cpp b/src/core/Song.cpp
index ce686e79f..c9ac56452 100644
--- a/src/core/Song.cpp
+++ b/src/core/Song.cpp
@@ -473,7 +473,7 @@ void Song::playBB()
-void Song::playPattern( Pattern* patternToPlay, bool _loop )
+void Song::playPattern( const Pattern* patternToPlay, bool _loop )
{
if( isStopped() == false )
{
diff --git a/src/core/Track.cpp b/src/core/Track.cpp
index 85e2a3d48..5acbb6477 100644
--- a/src/core/Track.cpp
+++ b/src/core/Track.cpp
@@ -2141,7 +2141,7 @@ TrackContentObject * Track::getTCO( int _tco_num )
* \param _tco The TrackContentObject to search for.
* \return its number in our array.
*/
-int Track::getTCONum( TrackContentObject * _tco )
+int Track::getTCONum( const TrackContentObject * _tco )
{
// for( int i = 0; i < getTrackContentWidget()->numOfTCOs(); ++i )
tcoVector::iterator it = qFind( m_trackContentObjects.begin(),
diff --git a/src/gui/AutomationEditor.cpp b/src/gui/AutomationEditor.cpp
index 4aeae1035..cb90253b4 100644
--- a/src/gui/AutomationEditor.cpp
+++ b/src/gui/AutomationEditor.cpp
@@ -1934,7 +1934,7 @@ void AutomationEditor::play()
if( Engine::getSong()->playMode() != Song::Mode_PlayPattern )
{
Engine::getSong()->stop();
- Engine::getSong()->playPattern( (Pattern *) Engine::pianoRoll()->currentPattern() );
+ Engine::getSong()->playPattern( Engine::pianoRoll()->currentPattern() );
}
else if( Engine::getSong()->isStopped() == false )
{
@@ -1942,7 +1942,7 @@ void AutomationEditor::play()
}
else
{
- Engine::getSong()->playPattern( (Pattern *) Engine::pianoRoll()->currentPattern() );
+ Engine::getSong()->playPattern( Engine::pianoRoll()->currentPattern() );
}
}
else if( inBBEditor() )
diff --git a/src/gui/FxMixerView.cpp b/src/gui/FxMixerView.cpp
index 407c0bd59..aefdcf274 100644
--- a/src/gui/FxMixerView.cpp
+++ b/src/gui/FxMixerView.cpp
@@ -194,12 +194,13 @@ void FxMixerView::refreshDisplay()
for( int i = 1; iremoveWidget(m_fxChannelViews[i]->m_fxLine);
+ m_racksLayout->removeWidget( m_fxChannelViews[i]->m_rackView );
delete m_fxChannelViews[i]->m_fader;
delete m_fxChannelViews[i]->m_muteBtn;
delete m_fxChannelViews[i]->m_soloBtn;
delete m_fxChannelViews[i]->m_fxLine;
+ delete m_fxChannelViews[i]->m_rackView;
delete m_fxChannelViews[i];
- m_racksLayout->removeWidget( m_fxChannelViews[i]->m_rackView );
}
m_channelAreaWidget->adjustSize();
@@ -363,16 +364,15 @@ void FxMixerView::deleteChannel(int index)
// delete the view
chLayout->removeWidget(m_fxChannelViews[index]->m_fxLine);
+ m_racksLayout->removeWidget( m_fxChannelViews[index]->m_rackView );
delete m_fxChannelViews[index]->m_fader;
delete m_fxChannelViews[index]->m_muteBtn;
delete m_fxChannelViews[index]->m_soloBtn;
delete m_fxChannelViews[index]->m_fxLine;
+ delete m_fxChannelViews[index]->m_rackView;
delete m_fxChannelViews[index];
m_channelAreaWidget->adjustSize();
- // delete the fx rack
- m_racksLayout->removeWidget( m_fxChannelViews[index]->m_rackView );
-
// make sure every channel knows what index it is
for(int i=0; im_fxChannels[0]->m_peakLeft *= Engine::mixer()->masterGain();
+ m->m_fxChannels[0]->m_peakRight *= Engine::mixer()->masterGain();
+
for( int i = 0; i < m_fxChannelViews.size(); ++i )
{
const float opl = m_fxChannelViews[i]->m_fader->getPeak_L();
diff --git a/src/gui/LfoControllerDialog.cpp b/src/gui/LfoControllerDialog.cpp
index 0c1ef5a20..b7c3eced7 100644
--- a/src/gui/LfoControllerDialog.cpp
+++ b/src/gui/LfoControllerDialog.cpp
@@ -75,14 +75,14 @@ LfoControllerDialog::LfoControllerDialog( Controller * _model, QWidget * _parent
m_baseKnob = new Knob( knobBright_26, this );
m_baseKnob->setLabel( tr( "BASE" ) );
m_baseKnob->move( CD_LFO_BASE_CD_KNOB_X, CD_LFO_CD_KNOB_Y );
- m_baseKnob->setHintText( tr( "Base amount:" ) + " ", "" );
+ m_baseKnob->setHintText( tr( "Base amount:" ), "" );
m_baseKnob->setWhatsThis( tr("todo") );
m_speedKnob = new TempoSyncKnob( knobBright_26, this );
m_speedKnob->setLabel( tr( "SPD" ) );
m_speedKnob->move( CD_LFO_SPEED_CD_KNOB_X, CD_LFO_CD_KNOB_Y );
- m_speedKnob->setHintText( tr( "LFO-speed:" ) + " ", "" );
+ m_speedKnob->setHintText( tr( "LFO-speed:" ), "" );
m_speedKnob->setWhatsThis(
tr( "Use this knob for setting speed of the LFO. The "
"bigger this value the faster the LFO oscillates and "
@@ -92,7 +92,7 @@ LfoControllerDialog::LfoControllerDialog( Controller * _model, QWidget * _parent
m_amountKnob = new Knob( knobBright_26, this );
m_amountKnob->setLabel( tr( "AMT" ) );
m_amountKnob->move( CD_LFO_AMOUNT_CD_KNOB_X, CD_LFO_CD_KNOB_Y );
- m_amountKnob->setHintText( tr( "Modulation amount:" ) + " ", "" );
+ m_amountKnob->setHintText( tr( "Modulation amount:" ), "" );
m_amountKnob->setWhatsThis(
tr( "Use this knob for setting modulation amount of the "
"LFO. The bigger this value, the more the connected "
@@ -102,7 +102,7 @@ LfoControllerDialog::LfoControllerDialog( Controller * _model, QWidget * _parent
m_phaseKnob = new Knob( knobBright_26, this );
m_phaseKnob->setLabel( tr( "PHS" ) );
m_phaseKnob->move( CD_LFO_PHASE_CD_KNOB_X, CD_LFO_CD_KNOB_Y );
- m_phaseKnob->setHintText( tr( "Phase offset:" ) + " ", "" + tr( "degrees" ) );
+ m_phaseKnob->setHintText( tr( "Phase offset:" ) , "" + tr( "degrees" ) );
m_phaseKnob->setWhatsThis(
tr( "With this knob you can set the phase offset of "
"the LFO. That means you can move the "
diff --git a/src/gui/PianoRoll.cpp b/src/gui/PianoRoll.cpp
index 56bc5b6a0..4e37b752a 100644
--- a/src/gui/PianoRoll.cpp
+++ b/src/gui/PianoRoll.cpp
@@ -70,6 +70,11 @@
#include "TextFloat.h"
+#if QT_VERSION < 0x040800
+#define MiddleButton MidButton
+#endif
+
+
typedef AutomationPattern::timeMap timeMap;
diff --git a/src/gui/PluginBrowser.cpp b/src/gui/PluginBrowser.cpp
index e42164c60..e87eac326 100644
--- a/src/gui/PluginBrowser.cpp
+++ b/src/gui/PluginBrowser.cpp
@@ -29,6 +29,8 @@
#include
#include "PluginBrowser.h"
+#include // for std::sort
+
#include "embed.h"
#include "debug.h"
#include "templates.h"
diff --git a/src/gui/widgets/AutomatableSlider.cpp b/src/gui/widgets/AutomatableSlider.cpp
index 6a3d10640..c6a36c939 100644
--- a/src/gui/widgets/AutomatableSlider.cpp
+++ b/src/gui/widgets/AutomatableSlider.cpp
@@ -1,5 +1,5 @@
/*
- * AutomatableSlider.cpp - implementation of class automatableSlider
+ * AutomatableSlider.cpp - implementation of class AutomatableSlider
*
* Copyright (c) 2006-2007 Javier Serrano Polo
* Copyright (c) 2007-2009 Tobias Doerffel
diff --git a/src/gui/widgets/EffectView.cpp b/src/gui/widgets/EffectView.cpp
index 466b2b0fa..6214747d5 100644
--- a/src/gui/widgets/EffectView.cpp
+++ b/src/gui/widgets/EffectView.cpp
@@ -67,7 +67,7 @@ EffectView::EffectView( Effect * _model, QWidget * _parent ) :
m_wetDry->setLabel( tr( "W/D" ) );
m_wetDry->move( 27, 5 );
m_wetDry->setEnabled( isEnabled );
- m_wetDry->setHintText( tr( "Wet Level:" ) + " ", "" );
+ m_wetDry->setHintText( tr( "Wet Level:" ), "" );
m_wetDry->setWhatsThis( tr( "The Wet/Dry knob sets the ratio between "
"the input signal and the effect signal that "
"forms the output." ) );
@@ -77,7 +77,7 @@ EffectView::EffectView( Effect * _model, QWidget * _parent ) :
m_autoQuit->setLabel( tr( "DECAY" ) );
m_autoQuit->move( 60, 5 );
m_autoQuit->setEnabled( isEnabled );
- m_autoQuit->setHintText( tr( "Time:" ) + " ", "ms" );
+ m_autoQuit->setHintText( tr( "Time:" ), "ms" );
m_autoQuit->setWhatsThis( tr(
"The Decay knob controls how many buffers of silence must pass before the "
"plugin stops processing. Smaller values will reduce the CPU overhead but "
@@ -88,7 +88,7 @@ EffectView::EffectView( Effect * _model, QWidget * _parent ) :
m_gate->setLabel( tr( "GATE" ) );
m_gate->move( 93, 5 );
m_gate->setEnabled( isEnabled );
- m_gate->setHintText( tr( "Gate:" ) + " ", "" );
+ m_gate->setHintText( tr( "Gate:" ), "" );
m_gate->setWhatsThis( tr(
"The Gate knob controls the signal level that is considered to be 'silence' "
"while deciding when to stop processing signals." ) );
diff --git a/src/gui/widgets/EnvelopeAndLfoView.cpp b/src/gui/widgets/EnvelopeAndLfoView.cpp
index 5143a42e2..5c364c19b 100644
--- a/src/gui/widgets/EnvelopeAndLfoView.cpp
+++ b/src/gui/widgets/EnvelopeAndLfoView.cpp
@@ -97,7 +97,7 @@ EnvelopeAndLfoView::EnvelopeAndLfoView( QWidget * _parent ) :
m_predelayKnob = new Knob( knobBright_26, this );
m_predelayKnob->setLabel( tr( "DEL" ) );
m_predelayKnob->move( PREDELAY_KNOB_X, ENV_KNOBS_Y );
- m_predelayKnob->setHintText( tr( "Predelay:" ) + " ", "" );
+ m_predelayKnob->setHintText( tr( "Predelay:" ), "" );
m_predelayKnob->setWhatsThis(
tr( "Use this knob for setting predelay of the current "
"envelope. The bigger this value the longer the time "
@@ -107,7 +107,7 @@ EnvelopeAndLfoView::EnvelopeAndLfoView( QWidget * _parent ) :
m_attackKnob = new Knob( knobBright_26, this );
m_attackKnob->setLabel( tr( "ATT" ) );
m_attackKnob->move( ATTACK_KNOB_X, ENV_KNOBS_Y );
- m_attackKnob->setHintText( tr( "Attack:" )+" ", "" );
+ m_attackKnob->setHintText( tr( "Attack:" ), "" );
m_attackKnob->setWhatsThis(
tr( "Use this knob for setting attack-time of the current "
"envelope. The bigger this value the longer the "
@@ -118,7 +118,7 @@ EnvelopeAndLfoView::EnvelopeAndLfoView( QWidget * _parent ) :
m_holdKnob = new Knob( knobBright_26, this );
m_holdKnob->setLabel( tr( "HOLD" ) );
m_holdKnob->move( HOLD_KNOB_X, ENV_KNOBS_Y );
- m_holdKnob->setHintText( tr( "Hold:" ) + " ", "" );
+ m_holdKnob->setHintText( tr( "Hold:" ), "" );
m_holdKnob->setWhatsThis(
tr( "Use this knob for setting hold-time of the current "
"envelope. The bigger this value the longer the "
@@ -128,7 +128,7 @@ EnvelopeAndLfoView::EnvelopeAndLfoView( QWidget * _parent ) :
m_decayKnob = new Knob( knobBright_26, this );
m_decayKnob->setLabel( tr( "DEC" ) );
m_decayKnob->move( DECAY_KNOB_X, ENV_KNOBS_Y );
- m_decayKnob->setHintText( tr( "Decay:" ) + " ", "" );
+ m_decayKnob->setHintText( tr( "Decay:" ), "" );
m_decayKnob->setWhatsThis(
tr( "Use this knob for setting decay-time of the current "
"envelope. The bigger this value the longer the "
@@ -140,7 +140,7 @@ EnvelopeAndLfoView::EnvelopeAndLfoView( QWidget * _parent ) :
m_sustainKnob = new Knob( knobBright_26, this );
m_sustainKnob->setLabel( tr( "SUST" ) );
m_sustainKnob->move( SUSTAIN_KNOB_X, ENV_KNOBS_Y );
- m_sustainKnob->setHintText( tr( "Sustain:" ) + " ", "" );
+ m_sustainKnob->setHintText( tr( "Sustain:" ), "" );
m_sustainKnob->setWhatsThis(
tr( "Use this knob for setting sustain-level of the current "
"envelope. The bigger this value the higher the level "
@@ -151,7 +151,7 @@ EnvelopeAndLfoView::EnvelopeAndLfoView( QWidget * _parent ) :
m_releaseKnob = new Knob( knobBright_26, this );
m_releaseKnob->setLabel( tr( "REL" ) );
m_releaseKnob->move( RELEASE_KNOB_X, ENV_KNOBS_Y );
- m_releaseKnob->setHintText( tr( "Release:" ) + " ", "" );
+ m_releaseKnob->setHintText( tr( "Release:" ), "" );
m_releaseKnob->setWhatsThis(
tr( "Use this knob for setting release-time of the current "
"envelope. The bigger this value the longer the "
@@ -163,7 +163,7 @@ EnvelopeAndLfoView::EnvelopeAndLfoView( QWidget * _parent ) :
m_amountKnob = new Knob( knobBright_26, this );
m_amountKnob->setLabel( tr( "AMT" ) );
m_amountKnob->move( AMOUNT_KNOB_X, ENV_GRAPH_Y );
- m_amountKnob->setHintText( tr( "Modulation amount:" ) + " ", "" );
+ m_amountKnob->setHintText( tr( "Modulation amount:" ), "" );
m_amountKnob->setWhatsThis(
tr( "Use this knob for setting modulation amount of the "
"current envelope. The bigger this value the more the "
@@ -176,7 +176,7 @@ EnvelopeAndLfoView::EnvelopeAndLfoView( QWidget * _parent ) :
m_lfoPredelayKnob = new Knob( knobBright_26, this );
m_lfoPredelayKnob->setLabel( tr( "DEL" ) );
m_lfoPredelayKnob->move( LFO_PREDELAY_KNOB_X, LFO_KNOB_Y );
- m_lfoPredelayKnob->setHintText( tr( "LFO predelay:" ) + " ", "" );
+ m_lfoPredelayKnob->setHintText( tr( "LFO predelay:" ), "" );
m_lfoPredelayKnob->setWhatsThis(
tr( "Use this knob for setting predelay-time of the current "
"LFO. The bigger this value the the time until the "
@@ -186,7 +186,7 @@ EnvelopeAndLfoView::EnvelopeAndLfoView( QWidget * _parent ) :
m_lfoAttackKnob = new Knob( knobBright_26, this );
m_lfoAttackKnob->setLabel( tr( "ATT" ) );
m_lfoAttackKnob->move( LFO_ATTACK_KNOB_X, LFO_KNOB_Y );
- m_lfoAttackKnob->setHintText( tr( "LFO- attack:" ) + " ", "" );
+ m_lfoAttackKnob->setHintText( tr( "LFO- attack:" ), "" );
m_lfoAttackKnob->setWhatsThis(
tr( "Use this knob for setting attack-time of the current LFO. "
"The bigger this value the longer the LFO needs to "
@@ -196,7 +196,7 @@ EnvelopeAndLfoView::EnvelopeAndLfoView( QWidget * _parent ) :
m_lfoSpeedKnob = new TempoSyncKnob( knobBright_26, this );
m_lfoSpeedKnob->setLabel( tr( "SPD" ) );
m_lfoSpeedKnob->move( LFO_SPEED_KNOB_X, LFO_KNOB_Y );
- m_lfoSpeedKnob->setHintText( tr( "LFO speed:" ) + " ", "" );
+ m_lfoSpeedKnob->setHintText( tr( "LFO speed:" ), "" );
m_lfoSpeedKnob->setWhatsThis(
tr( "Use this knob for setting speed of the current LFO. The "
"bigger this value the faster the LFO oscillates and "
@@ -206,7 +206,7 @@ EnvelopeAndLfoView::EnvelopeAndLfoView( QWidget * _parent ) :
m_lfoAmountKnob = new Knob( knobBright_26, this );
m_lfoAmountKnob->setLabel( tr( "AMT" ) );
m_lfoAmountKnob->move( LFO_AMOUNT_KNOB_X, LFO_KNOB_Y );
- m_lfoAmountKnob->setHintText( tr( "Modulation amount:" ) + " ", "" );
+ m_lfoAmountKnob->setHintText( tr( "Modulation amount:" ), "" );
m_lfoAmountKnob->setWhatsThis(
tr( "Use this knob for setting modulation amount of the "
"current LFO. The bigger this value the more the "
diff --git a/src/gui/widgets/Fader.cpp b/src/gui/widgets/Fader.cpp
index 3015d976f..0f0bef69d 100644
--- a/src/gui/widgets/Fader.cpp
+++ b/src/gui/widgets/Fader.cpp
@@ -74,6 +74,7 @@ Fader::Fader( FloatModel * _model, const QString & _name, QWidget * _parent ) :
m_persistentPeak_R( 0.0 ),
m_fMinPeak( 0.01f ),
m_fMaxPeak( 1.1 ),
+ m_displayConversion( true ),
m_moveStartPoint( -1 ),
m_startValue( 0 ),
m_peakGreen( 0, 0, 0 ),
@@ -95,16 +96,55 @@ Fader::Fader( FloatModel * _model, const QString & _name, QWidget * _parent ) :
{
s_knob = new QPixmap( embed::getIconPixmap( "fader_knob" ) );
}
-
+
+ m_back = s_back;
+ m_leds = s_leds;
+ m_knob = s_knob;
+
setWindowTitle( _name );
setAttribute( Qt::WA_OpaquePaintEvent, false );
setMinimumSize( 23, 116 );
setMaximumSize( 23, 116);
resize( 23, 116 );
setModel( _model );
+ setHintText( "Volume:","%");
}
+Fader::Fader( FloatModel * model, const QString & name, QWidget * parent, QPixmap * back, QPixmap * leds, QPixmap * knob ) :
+ QWidget( parent ),
+ FloatModelView( model, this ),
+ m_model( model ),
+ m_fPeakValue_L( 0.0 ),
+ m_fPeakValue_R( 0.0 ),
+ m_persistentPeak_L( 0.0 ),
+ m_persistentPeak_R( 0.0 ),
+ m_fMinPeak( 0.01f ),
+ m_fMaxPeak( 1.1 ),
+ m_displayConversion( false ),
+ m_moveStartPoint( -1 ),
+ m_startValue( 0 ),
+ m_peakGreen( 0, 0, 0 ),
+ m_peakRed( 0, 0, 0 )
+{
+ if( s_textFloat == NULL )
+ {
+ s_textFloat = new TextFloat;
+ }
+
+ m_back = back;
+ m_leds = leds;
+ m_knob = knob;
+
+ setWindowTitle( name );
+ setAttribute( Qt::WA_OpaquePaintEvent, false );
+ setMinimumSize( m_back->width(), m_back->height() );
+ setMaximumSize( m_back->width(), m_back->height() );
+ resize( m_back->width(), m_back->height() );
+ setModel( model );
+ setHintText( "Volume:","%");
+}
+
Fader::~Fader()
{
@@ -130,7 +170,7 @@ void Fader::mouseMoveEvent( QMouseEvent *mouseEvent )
{
int dy = m_moveStartPoint - mouseEvent->globalY();
- float delta = dy * ( m_model->maxValue() - m_model->minValue() ) / (float) ( height() - ( *s_knob ).height() );
+ float delta = dy * ( m_model->maxValue() - m_model->minValue() ) / (float) ( height() - ( *m_knob ).height() );
model()->setValue( m_startValue + delta );
@@ -146,7 +186,7 @@ void Fader::mousePressEvent( QMouseEvent* mouseEvent )
if( mouseEvent->button() == Qt::LeftButton &&
! ( mouseEvent->modifiers() & Qt::ControlModifier ) )
{
- if( mouseEvent->y() >= knobPosY() - ( *s_knob ).height() && mouseEvent->y() < knobPosY() )
+ if( mouseEvent->y() >= knobPosY() - ( *m_knob ).height() && mouseEvent->y() < knobPosY() )
{
updateTextFloat();
s_textFloat->show();
@@ -172,19 +212,33 @@ void Fader::mousePressEvent( QMouseEvent* mouseEvent )
void Fader::mouseDoubleClickEvent( QMouseEvent* mouseEvent )
{
bool ok;
+ float newValue;
// TODO: dbV handling
- int newValue = QInputDialog::getInt( this, windowTitle(),
- tr( "Please enter a new value between %1 and %2:" ).
- arg( model()->minValue()*100 ).
- arg( model()->maxValue()*100 ),
- model()->value()*100,
- model()->minValue()*100,
- model()->maxValue()*100, 1, &ok );
+ if( m_displayConversion )
+ {
+ newValue = QInputDialog::getDouble( this, windowTitle(),
+ tr( "Please enter a new value between %1 and %2:" ).
+ arg( model()->minValue() * 100 ).
+ arg( model()->maxValue() * 100 ),
+ model()->value() * 100,
+ model()->minValue() * 100,
+ model()->maxValue() * 100, 4, &ok ) * 0.01f;
+ }
+ else
+ {
+ newValue = QInputDialog::getDouble( this, windowTitle(),
+ tr( "Please enter a new value between %1 and %2:" ).
+ arg( model()->minValue() ).
+ arg( model()->maxValue() ),
+ model()->value(),
+ model()->minValue(),
+ model()->maxValue(), 4, &ok );
+ }
if( ok )
{
- model()->setValue( newValue / 100.0f );
+ model()->setValue( newValue );
}
}
@@ -265,25 +319,24 @@ void Fader::setPeak_R( float fPeak )
// update tooltip showing value and adjust position while changing fader value
void Fader::updateTextFloat()
{
- if( ConfigManager::inst()->value( "app", "displaydbv" ).toInt() )
+ if( ConfigManager::inst()->value( "app", "displaydbv" ).toInt() && m_displayConversion )
{
s_textFloat->setText( QString("Volume: %1 dBV").
arg( 20.0 * log10( model()->value() ), 3, 'f', 2 ) );
}
else
{
- s_textFloat->setText( QString("Volume: %1 %").arg( m_model->value() * 100 ) );
+ s_textFloat->setText( m_description + " " + QString("%1 ").arg( m_displayConversion ? m_model->value() * 100 : m_model->value() ) + " " + m_unit );
}
- s_textFloat->moveGlobal( this, QPoint( width() - ( *s_knob ).width() - 5, knobPosY() - 46 ) );
+ s_textFloat->moveGlobal( this, QPoint( width() - ( *m_knob ).width() - 5, knobPosY() - 46 ) );
}
inline int Fader::calculateDisplayPeak( float fPeak )
{
- int peak = (int)( 116 - ( fPeak / ( m_fMaxPeak - m_fMinPeak ) ) * 116.0 );
+ int peak = (int)( m_back->height() - ( fPeak / ( m_fMaxPeak - m_fMinPeak ) ) * m_back->height() );
- if ( peak > 116 ) return 116;
- else return peak;
+ return qMin( peak, m_back->height() );
}
void Fader::paintEvent( QPaintEvent * ev)
@@ -291,36 +344,39 @@ void Fader::paintEvent( QPaintEvent * ev)
QPainter painter(this);
// background
- painter.drawPixmap( ev->rect(), *s_back, ev->rect() );
-
+ painter.drawPixmap( ev->rect(), *m_back, ev->rect() );
// peak leds
//float fRange = abs( m_fMaxPeak ) + abs( m_fMinPeak );
+ int height = m_back->height();
+ int width = m_back->width() / 2;
+ int center = m_back->width() - width;
+
int peak_L = calculateDisplayPeak( m_fPeakValue_L - m_fMinPeak );
int persistentPeak_L = qMax( 3, calculateDisplayPeak( m_persistentPeak_L - m_fMinPeak ) );
- painter.drawPixmap( QRect( 0, peak_L, 11, 116 - peak_L ), *s_leds, QRect( 0, peak_L, 11, 116 - peak_L ) );
+ painter.drawPixmap( QRect( 0, peak_L, width, height - peak_L ), *m_leds, QRect( 0, peak_L, width, height - peak_L ) );
if( m_persistentPeak_L > 0.05 )
{
painter.fillRect( QRect( 2, persistentPeak_L, 7, 1 ), ( m_persistentPeak_L < 1.0 )
- ? peakGreen()
+ ? peakGreen()
: peakRed() );
}
int peak_R = calculateDisplayPeak( m_fPeakValue_R - m_fMinPeak );
int persistentPeak_R = qMax( 3, calculateDisplayPeak( m_persistentPeak_R - m_fMinPeak ) );
- painter.drawPixmap( QRect( 11, peak_R, 11, 116 - peak_R ), *s_leds, QRect( 11, peak_R, 11, 116 - peak_R ) );
+ painter.drawPixmap( QRect( center, peak_R, width, height - peak_R ), *m_leds, QRect( center, peak_R, width, height - peak_R ) );
if( m_persistentPeak_R > 0.05 )
{
painter.fillRect( QRect( 14, persistentPeak_R, 7, 1 ), ( m_persistentPeak_R < 1.0 )
- ? peakGreen()
+ ? peakGreen()
: peakRed() );
}
// knob
- painter.drawPixmap( 0, knobPosY() - ( *s_knob ).height(), *s_knob );
+ painter.drawPixmap( 0, knobPosY() - m_knob->height(), *m_knob );
}
@@ -333,12 +389,12 @@ QColor Fader::peakRed() const
{
return m_peakRed;
}
-
+
void Fader::setPeakGreen( const QColor & c )
{
m_peakGreen = c;
}
-
+
void Fader::setPeakRed( const QColor & c )
{
m_peakRed = c;
diff --git a/src/gui/widgets/InstrumentFunctionViews.cpp b/src/gui/widgets/InstrumentFunctionViews.cpp
index d0f55f2c3..632526a25 100644
--- a/src/gui/widgets/InstrumentFunctionViews.cpp
+++ b/src/gui/widgets/InstrumentFunctionViews.cpp
@@ -60,7 +60,7 @@ InstrumentFunctionNoteStackingView::InstrumentFunctionNoteStackingView( Instrume
chordLabel->setFont( pointSize<8>( chordLabel->font() ) );
m_chordRangeKnob->setLabel( tr( "RANGE" ) );
- m_chordRangeKnob->setHintText( tr( "Chord range:" ) + " ", " " + tr( "octave(s)" ) );
+ m_chordRangeKnob->setHintText( tr( "Chord range:" ), " " + tr( "octave(s)" ) );
m_chordRangeKnob->setWhatsThis(
tr( "Use this knob for setting the chord range in octaves. "
"The selected chord will be played within specified "
@@ -130,7 +130,7 @@ InstrumentFunctionArpeggioView::InstrumentFunctionArpeggioView( InstrumentFuncti
m_arpRangeKnob->setLabel( tr( "RANGE" ) );
- m_arpRangeKnob->setHintText( tr( "Arpeggio range:" ) + " ", " " + tr( "octave(s)" ) );
+ m_arpRangeKnob->setHintText( tr( "Arpeggio range:" ), " " + tr( "octave(s)" ) );
m_arpRangeKnob->setWhatsThis(
tr( "Use this knob for setting the arpeggio range in octaves. "
"The selected arpeggio will be played within specified "
@@ -138,7 +138,7 @@ InstrumentFunctionArpeggioView::InstrumentFunctionArpeggioView( InstrumentFuncti
m_arpTimeKnob->setLabel( tr( "TIME" ) );
- m_arpTimeKnob->setHintText( tr( "Arpeggio time:" ) + " ", " " + tr( "ms" ) );
+ m_arpTimeKnob->setHintText( tr( "Arpeggio time:" ), " " + tr( "ms" ) );
m_arpTimeKnob->setWhatsThis(
tr( "Use this knob for setting the arpeggio time in "
"milliseconds. The arpeggio time specifies how long "
@@ -146,7 +146,7 @@ InstrumentFunctionArpeggioView::InstrumentFunctionArpeggioView( InstrumentFuncti
m_arpGateKnob->setLabel( tr( "GATE" ) );
- m_arpGateKnob->setHintText( tr( "Arpeggio gate:" ) + " ", tr( "%" ) );
+ m_arpGateKnob->setHintText( tr( "Arpeggio gate:" ), tr( "%" ) );
m_arpGateKnob->setWhatsThis(
tr( "Use this knob for setting the arpeggio gate. The "
"arpeggio gate specifies the percent of a whole "
diff --git a/src/gui/widgets/InstrumentSoundShapingView.cpp b/src/gui/widgets/InstrumentSoundShapingView.cpp
index b5c923e21..39637e7e7 100644
--- a/src/gui/widgets/InstrumentSoundShapingView.cpp
+++ b/src/gui/widgets/InstrumentSoundShapingView.cpp
@@ -99,7 +99,7 @@ InstrumentSoundShapingView::InstrumentSoundShapingView( QWidget * _parent ) :
m_filterCutKnob = new Knob( knobBright_26, m_filterGroupBox );
m_filterCutKnob->setLabel( tr( "FREQ" ) );
m_filterCutKnob->move( 140, 18 );
- m_filterCutKnob->setHintText( tr( "cutoff frequency:" ) + " ", " " + tr( "Hz" ) );
+ m_filterCutKnob->setHintText( tr( "cutoff frequency:" ), " " + tr( "Hz" ) );
m_filterCutKnob->setWhatsThis(
tr( "Use this knob for setting the cutoff frequency for the "
"selected filter. The cutoff frequency specifies the "
@@ -112,7 +112,7 @@ InstrumentSoundShapingView::InstrumentSoundShapingView( QWidget * _parent ) :
m_filterResKnob = new Knob( knobBright_26, m_filterGroupBox );
m_filterResKnob->setLabel( tr( "RESO" ) );
m_filterResKnob->move( 196, 18 );
- m_filterResKnob->setHintText( tr( "Resonance:" ) + " ", "" );
+ m_filterResKnob->setHintText( tr( "Resonance:" ), "" );
m_filterResKnob->setWhatsThis(
tr( "Use this knob for setting Q/Resonance for the selected "
"filter. Q/Resonance tells the filter how much it "
diff --git a/src/gui/widgets/LadspaControlView.cpp b/src/gui/widgets/LadspaControlView.cpp
index 558237ba6..75eaf64cb 100644
--- a/src/gui/widgets/LadspaControlView.cpp
+++ b/src/gui/widgets/LadspaControlView.cpp
@@ -100,7 +100,7 @@ LadspaControlView::LadspaControlView( QWidget * _parent,
knb->setModel( m_ctl->tempoSyncKnobModel() );
}
knb->setLabel( m_ctl->port()->name );
- knb->setHintText( tr( "Value:" ) + " ", "" );
+ knb->setHintText( tr( "Value:" ), "" );
knb->setWhatsThis( tr( "Sorry, no help available." ) );
layout->addWidget( knb );
if( link != NULL )
diff --git a/src/tracks/InstrumentTrack.cpp b/src/tracks/InstrumentTrack.cpp
index c1ae4d0c2..06219b942 100644
--- a/src/tracks/InstrumentTrack.cpp
+++ b/src/tracks/InstrumentTrack.cpp
@@ -87,7 +87,7 @@ const char * volume_help = QT_TRANSLATE_NOOP( "InstrumentTrack",
const int INSTRUMENT_WIDTH = 254;
const int INSTRUMENT_HEIGHT = INSTRUMENT_WIDTH;
-const int PIANO_HEIGHT = 84;
+const int PIANO_HEIGHT = 82;
const int INSTRUMENT_WINDOW_CACHE_SIZE = 8;
@@ -849,7 +849,7 @@ InstrumentTrackView::InstrumentTrackView( InstrumentTrack * _it, TrackContainerV
tr( "Volume" ) );
m_volumeKnob->setVolumeKnob( true );
m_volumeKnob->setModel( &_it->m_volumeModel );
- m_volumeKnob->setHintText( tr( "Volume:" ) + " ", "%" );
+ m_volumeKnob->setHintText( tr( "Volume:" ), "%" );
m_volumeKnob->move( widgetWidth-2*24, 2 );
m_volumeKnob->setLabel( tr( "VOL" ) );
m_volumeKnob->show();
@@ -858,7 +858,7 @@ InstrumentTrackView::InstrumentTrackView( InstrumentTrack * _it, TrackContainerV
m_panningKnob = new Knob( knobSmall_17, getTrackSettingsWidget(),
tr( "Panning" ) );
m_panningKnob->setModel( &_it->m_panningModel );
- m_panningKnob->setHintText( tr( "Panning:" ) + " ", "%" );
+ m_panningKnob->setHintText( tr( "Panning:" ), "%" );
m_panningKnob->move( widgetWidth-24, 2 );
m_panningKnob->setLabel( tr( "PAN" ) );
m_panningKnob->show();
@@ -1176,7 +1176,7 @@ InstrumentTrackWindow::InstrumentTrackWindow( InstrumentTrackView * _itv ) :
// set up volume knob
m_volumeKnob = new Knob( knobBright_26, NULL, tr( "Instrument volume" ) );
m_volumeKnob->setVolumeKnob( true );
- m_volumeKnob->setHintText( tr( "Volume:" ) + " ", "%" );
+ m_volumeKnob->setHintText( tr( "Volume:" ), "%" );
m_volumeKnob->setLabel( tr( "VOL" ) );
m_volumeKnob->setWhatsThis( tr( volume_help ) );
@@ -1185,7 +1185,7 @@ InstrumentTrackWindow::InstrumentTrackWindow( InstrumentTrackView * _itv ) :
// set up panning knob
m_panningKnob = new Knob( knobBright_26, NULL, tr( "Panning" ) );
- m_panningKnob->setHintText( tr( "Panning:" ) + " ", "" );
+ m_panningKnob->setHintText( tr( "Panning:" ), "" );
m_panningKnob->setLabel( tr( "PAN" ) );
basicControlsLayout->addWidget( m_panningKnob );
@@ -1193,7 +1193,7 @@ InstrumentTrackWindow::InstrumentTrackWindow( InstrumentTrackView * _itv ) :
// set up pitch knob
m_pitchKnob = new Knob( knobBright_26, NULL, tr( "Pitch" ) );
- m_pitchKnob->setHintText( tr( "Pitch:" ) + " ", " " + tr( "cents" ) );
+ m_pitchKnob->setHintText( tr( "Pitch:" ), " " + tr( "cents" ) );
m_pitchKnob->setLabel( tr( "PITCH" ) );
basicControlsLayout->addWidget( m_pitchKnob );
diff --git a/src/tracks/SampleTrack.cpp b/src/tracks/SampleTrack.cpp
index da5c8caf4..49d59f66c 100644
--- a/src/tracks/SampleTrack.cpp
+++ b/src/tracks/SampleTrack.cpp
@@ -537,7 +537,7 @@ SampleTrackView::SampleTrackView( SampleTrack * _t, TrackContainerView* tcv ) :
tr( "Track volume" ) );
m_volumeKnob->setVolumeKnob( true );
m_volumeKnob->setModel( &_t->m_volumeModel );
- m_volumeKnob->setHintText( tr( "Channel volume:" ) + " ", "%" );
+ m_volumeKnob->setHintText( tr( "Channel volume:" ), "%" );
if( ConfigManager::inst()->value( "ui",
"compacttrackbuttons" ).toInt() )
{