Render the mixer levels in a dB FS scale (#2672)

* Render the mixer levels in a dB FS scale

Adds the option to render the mixer levels in dB FS. By default this
option is disabled so that classes which inherit from Fader are not
affected by this change. However, in the code of the FxMixerView this
feature is enabled so that the mixer shows the levels in dB FS.

The ability to render in dB FS is exported as a property so that it can
also be set in a style sheet (not used as of now). The new property is
called "levelsDisplayedInDBFS".

There are now setters and getters for the min and max level.

Showing the levels in dB FS (which is a logarithmic scale) gives a less
"fidgety" impression when the levels are moving.

* Introduction of an init method in Fader

An init method was added to unify the initialization of the two Fader
constructors.
This commit is contained in:
Michael Gregorius
2016-07-10 15:08:54 +02:00
committed by Umcaruje
parent 04ee0910af
commit 52ec3874b1
3 changed files with 117 additions and 26 deletions

View File

@@ -50,6 +50,7 @@
#include "InstrumentTrack.h"
#include "Song.h"
#include "BBTrackContainer.h"
#include "lmms_math.h"
FxMixerView::FxMixerView() :
QWidget(),
@@ -280,6 +281,11 @@ FxMixerView::FxChannelView::FxChannelView(QWidget * _parent, FxMixerView * _mv,
m_fader = new Fader( &fxChannel->m_volumeModel,
tr( "FX Fader %1" ).arg( channelIndex ), m_fxLine );
m_fader->setLevelsDisplayedInDBFS();
// TODO dbvToAmp is really dBFSToAmp. Rename in later commit.
m_fader->setMinPeak(dbvToAmp(-40));
m_fader->setMaxPeak(dbvToAmp(12));
m_fader->move( 16-m_fader->width()/2,
m_fxLine->height()-
m_fader->height()-5 );

View File

@@ -57,6 +57,7 @@
#include "ConfigManager.h"
#include "TextFloat.h"
#include "MainWindow.h"
#include "lmms_math.h"
TextFloat * Fader::s_textFloat = NULL;
@@ -74,6 +75,7 @@ Fader::Fader( FloatModel * _model, const QString & _name, QWidget * _parent ) :
m_fMinPeak( 0.01f ),
m_fMaxPeak( 1.1 ),
m_displayConversion( true ),
m_levelsDisplayedInDBFS(false),
m_moveStartPoint( -1 ),
m_startValue( 0 ),
m_peakGreen( 0, 0, 0 ),
@@ -100,13 +102,7 @@ Fader::Fader( FloatModel * _model, const QString & _name, QWidget * _parent ) :
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:","%");
init(_model, _name);
}
@@ -120,6 +116,7 @@ Fader::Fader( FloatModel * model, const QString & name, QWidget * parent, QPixma
m_fMinPeak( 0.01f ),
m_fMaxPeak( 1.1 ),
m_displayConversion( false ),
m_levelsDisplayedInDBFS(false),
m_moveStartPoint( -1 ),
m_startValue( 0 ),
m_peakGreen( 0, 0, 0 ),
@@ -134,13 +131,7 @@ Fader::Fader( FloatModel * model, const QString & name, QWidget * parent, QPixma
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:","%");
init(model, name);
}
@@ -149,6 +140,18 @@ Fader::~Fader()
}
void Fader::init(FloatModel * model, QString const & name)
{
setWindowTitle( name );
setAttribute( Qt::WA_OpaquePaintEvent, false );
QSize backgroundSize = m_back->size();
setMinimumSize( backgroundSize );
setMaximumSize( backgroundSize );
resize( backgroundSize );
setModel( model );
setHintText( "Volume:","%");
}
void Fader::contextMenuEvent( QContextMenuEvent * _ev )
@@ -337,20 +340,81 @@ inline int Fader::calculateDisplayPeak( float fPeak )
return qMin( peak, m_back->height() );
}
void Fader::paintEvent( QPaintEvent * ev)
{
QPainter painter(this);
// background
// Draw the background
painter.drawPixmap( ev->rect(), *m_back, ev->rect() );
// Draw the levels with peaks
if (getLevelsDisplayedInDBFS())
{
paintDBFSLevels(ev, painter);
}
else
{
paintLinearLevels(ev, painter);
}
// Draw the knob
painter.drawPixmap( 0, knobPosY() - m_knob->height(), *m_knob );
}
void Fader::paintDBFSLevels(QPaintEvent * ev, QPainter & painter)
{
int height = m_back->height();
int width = m_back->width() / 2;
int center = m_back->width() - width;
float const maxDB(ampToDbv(m_fMaxPeak));
float const minDB(ampToDbv(m_fMinPeak));
// We will need to divide by the span between min and max several times. It's more
// efficient to calculate the reciprocal once and then to multiply.
float const fullSpanReciprocal = 1 / (maxDB - minDB);
// Draw left levels
float const leftSpan = ampToDbv(m_fPeakValue_L) - minDB;
int peak_L = height * leftSpan * fullSpanReciprocal;
QRect drawRectL( 0, height - peak_L, width, peak_L ); // Source and target are identical
painter.drawPixmap( drawRectL, *m_leds, drawRectL );
float const persistentLeftPeakDBFS = ampToDbv(m_persistentPeak_L);
int persistentPeak_L = height * (1 - (persistentLeftPeakDBFS - minDB) * fullSpanReciprocal);
if( persistentLeftPeakDBFS > minDB )
{
QColor const & peakColor = clips(m_persistentPeak_L) ? peakRed() : peakGreen();
painter.fillRect( QRect( 2, persistentPeak_L, 7, 1 ), peakColor );
}
// Draw right levels
float const rightSpan = ampToDbv(m_fPeakValue_R) - minDB;
int peak_R = height * rightSpan * fullSpanReciprocal;
QRect const drawRectR( center, height - peak_R, width, peak_R ); // Source and target are identical
painter.drawPixmap( drawRectR, *m_leds, drawRectR );
float const persistentRightPeakDBFS = ampToDbv(m_persistentPeak_R);
int persistentPeak_R = height * (1 - (persistentRightPeakDBFS - minDB) * fullSpanReciprocal);
if( persistentRightPeakDBFS > minDB )
{
QColor const & peakColor = clips(m_persistentPeak_R) ? peakRed() : peakGreen();
painter.fillRect( QRect( 14, persistentPeak_R, 7, 1 ), peakColor );
}
}
void Fader::paintLinearLevels(QPaintEvent * ev, QPainter & painter)
{
// 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<int>( 3, calculateDisplayPeak( m_persistentPeak_L - m_fMinPeak ) );
painter.drawPixmap( QRect( 0, peak_L, width, height - peak_L ), *m_leds, QRect( 0, peak_L, width, height - peak_L ) );
@@ -372,18 +436,15 @@ void Fader::paintEvent( QPaintEvent * ev)
? peakGreen()
: peakRed() );
}
// knob
painter.drawPixmap( 0, knobPosY() - m_knob->height(), *m_knob );
}
QColor Fader::peakGreen() const
QColor const & Fader::peakGreen() const
{
return m_peakGreen;
}
QColor Fader::peakRed() const
QColor const & Fader::peakRed() const
{
return m_peakRed;
}