Used FloatModels as the backend for mixer sends
Can add new channels in the mixer, and sends are implemented. Instruments are hardcoded at 10. FL Import is hardcoded at 64.
This commit is contained in:
BIN
data/themes/default/send_bg_arrow.png
Normal file
BIN
data/themes/default/send_bg_arrow.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 267 B |
@@ -31,7 +31,6 @@
|
||||
#include "JournallingObject.h"
|
||||
|
||||
|
||||
const int NumFxChannels = 64;
|
||||
|
||||
|
||||
struct FxChannel
|
||||
@@ -54,6 +53,7 @@ struct FxChannel
|
||||
|
||||
// pointers to other channels that this one sends to
|
||||
QVector<fx_ch_t> m_sends;
|
||||
QVector<FloatModel *> m_sendAmount;
|
||||
|
||||
// pointers to other channels that send to this one
|
||||
QVector<fx_ch_t> m_receives;
|
||||
@@ -86,26 +86,36 @@ public:
|
||||
|
||||
FxChannel * effectChannel( int _ch )
|
||||
{
|
||||
if( _ch >= 0 && _ch <= NumFxChannels )
|
||||
{
|
||||
return m_fxChannels[_ch];
|
||||
}
|
||||
return NULL;
|
||||
return m_fxChannels[_ch];
|
||||
}
|
||||
|
||||
// make the output of channel fromChannel go to the input of channel toChannel
|
||||
void createChannelSend(fx_ch_t fromChannel, fx_ch_t toChannel);
|
||||
// it is safe to call even if the send already exists
|
||||
void createChannelSend(fx_ch_t fromChannel, fx_ch_t toChannel,
|
||||
float amount = 1.0f);
|
||||
|
||||
// delete the connection made by createChannelSend
|
||||
void deleteChannelSend(fx_ch_t fromChannel, fx_ch_t toChannel);
|
||||
|
||||
// does fromChannel send its output to the input of toChannel?
|
||||
bool channelSendsTo(fx_ch_t fromChannel, fx_ch_t toChannel);
|
||||
// return the FloatModel of fromChannel sending its output to the input of
|
||||
// toChannel. NULL if there is no send.
|
||||
FloatModel * channelSendModel(fx_ch_t fromChannel, fx_ch_t toChannel);
|
||||
|
||||
// add a new channel to the Fx Mixer.
|
||||
// returns the index of the channel that was just added
|
||||
int createChannel();
|
||||
|
||||
// reset a channel's name, fx, sends, etc
|
||||
void clearChannel(fx_ch_t channelIndex);
|
||||
|
||||
inline fx_ch_t numChannels() const
|
||||
{
|
||||
return m_fxChannels.size();
|
||||
}
|
||||
|
||||
private:
|
||||
FxChannel * m_fxChannels[NumFxChannels+1]; // +1 = master
|
||||
// the fx channels in the mixer. index 0 is always master.
|
||||
QVector<FxChannel *> m_fxChannels;
|
||||
|
||||
friend class mixerWorkerThread;
|
||||
friend class FxMixerView;
|
||||
|
||||
@@ -26,6 +26,8 @@
|
||||
#define _FX_MIXER_VIEW_H
|
||||
|
||||
#include <QtGui/QWidget>
|
||||
#include <QtGui/QHBoxLayout>
|
||||
#include <QtGui/QScrollArea>
|
||||
|
||||
#include "FxMixer.h"
|
||||
#include "ModelView.h"
|
||||
@@ -61,7 +63,7 @@ public:
|
||||
|
||||
private slots:
|
||||
void updateFaders();
|
||||
|
||||
void addNewChannel();
|
||||
|
||||
private:
|
||||
struct FxChannelView
|
||||
@@ -72,13 +74,15 @@ private:
|
||||
fader * m_fader;
|
||||
} ;
|
||||
|
||||
FxChannelView m_fxChannelViews[NumFxChannels+1];
|
||||
QVector<FxChannelView> m_fxChannelViews;
|
||||
|
||||
QStackedLayout * m_fxRacksLayout;
|
||||
QStackedLayout * m_fxLineBanks;
|
||||
QButtonGroup * m_bankButtons;
|
||||
FxLine * m_currentFxLine;
|
||||
|
||||
QScrollArea * channelArea;
|
||||
QHBoxLayout * chLayout;
|
||||
|
||||
void addFxLine(int i, QWidget * parent, QLayout * layout);
|
||||
} ;
|
||||
|
||||
#endif
|
||||
|
||||
@@ -59,7 +59,7 @@ public:
|
||||
// LMMS Stuff
|
||||
|
||||
virtual void drawFxLine(QPainter * _painter, const QWidget *_fxLine,
|
||||
const QString & _name, bool _active);
|
||||
const QString & _name, bool _active, bool _sendToThis);
|
||||
|
||||
virtual void drawTrackContentBackground(QPainter * _painter,
|
||||
const QSize & _size, const int _pixelsPerTact);
|
||||
|
||||
@@ -66,7 +66,7 @@ public:
|
||||
virtual void unpolish( QWidget * widget );
|
||||
|
||||
virtual void drawFxLine( QPainter * _painter, const QWidget *_fxLine,
|
||||
const QString & _name, bool _active );
|
||||
const QString & _name, bool _active, bool _sendToThis );
|
||||
|
||||
virtual void drawTrackContentBackground( QPainter * _painter,
|
||||
const QSize & _size, const int _pixelsPerTact );
|
||||
|
||||
@@ -91,7 +91,7 @@ public:
|
||||
|
||||
|
||||
virtual void drawFxLine(QPainter * _painter, const QWidget *_fxLine,
|
||||
const QString & _name, bool _active) = 0;
|
||||
const QString & _name, bool _active, bool _sendToThis) = 0;
|
||||
|
||||
virtual void drawTrackContentBackground(QPainter * _painter,
|
||||
const QSize & _size, const int _pixelsPerTact) = 0;
|
||||
|
||||
@@ -104,7 +104,7 @@ extern QString outstring;
|
||||
|
||||
}
|
||||
|
||||
|
||||
const int NumFLFxChannels = 64;
|
||||
|
||||
static void dump_mem( const void * buffer, uint n_bytes )
|
||||
{
|
||||
@@ -542,7 +542,7 @@ struct FL_Project
|
||||
int currentPattern;
|
||||
int activeEditPattern;
|
||||
|
||||
FL_EffectChannel effectChannels[NumFxChannels+1];
|
||||
FL_EffectChannel effectChannels[NumFLFxChannels+1];
|
||||
int currentEffectChannel;
|
||||
|
||||
QString projectNotes;
|
||||
@@ -1022,7 +1022,7 @@ bool FlpImport::tryFLPImport( trackContainer * _tc )
|
||||
break;
|
||||
|
||||
case FLP_EffectChannelMuted:
|
||||
if( p.currentEffectChannel <= NumFxChannels )
|
||||
if( p.currentEffectChannel <= NumFLFxChannels )
|
||||
{
|
||||
p.effectChannels[p.currentEffectChannel].isMuted =
|
||||
( data & 0x08 ) > 0 ? false : true;
|
||||
@@ -1274,7 +1274,7 @@ if( p.currentEffectChannel <= NumFxChannels )
|
||||
|
||||
case FLP_Text_EffectChanName:
|
||||
++p.currentEffectChannel;
|
||||
if( p.currentEffectChannel <= NumFxChannels )
|
||||
if( p.currentEffectChannel <= NumFLFxChannels )
|
||||
{
|
||||
p.effectChannels[p.currentEffectChannel].name = text;
|
||||
}
|
||||
@@ -1497,7 +1497,7 @@ if( p.currentEffectChannel <= NumFxChannels )
|
||||
const int param = pi[i*3+1] & 0xffff;
|
||||
const int ch = ( pi[i*3+1] >> 22 )
|
||||
& 0x7f;
|
||||
if( ch < 0 || ch > NumFxChannels )
|
||||
if( ch < 0 || ch > NumFLFxChannels )
|
||||
{
|
||||
continue;
|
||||
}
|
||||
@@ -1797,7 +1797,7 @@ p->putValue( jt->pos, value, false );
|
||||
}
|
||||
}
|
||||
|
||||
for( int fx_ch = 0; fx_ch <= NumFxChannels ; ++fx_ch )
|
||||
for( int fx_ch = 0; fx_ch <= NumFLFxChannels ; ++fx_ch )
|
||||
{
|
||||
FxChannel * ch = engine::fxMixer()->effectChannel( fx_ch );
|
||||
if( !ch )
|
||||
@@ -1857,7 +1857,7 @@ p->putValue( jt->pos, value, false );
|
||||
break;
|
||||
}
|
||||
if( effName.isEmpty() || it->fxChannel < 0 ||
|
||||
it->fxChannel > NumFxChannels )
|
||||
it->fxChannel > NumFLFxChannels )
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
@@ -61,49 +61,64 @@ FxChannel::~FxChannel()
|
||||
|
||||
FxMixer::FxMixer() :
|
||||
JournallingObject(),
|
||||
Model( NULL )
|
||||
Model( NULL ),
|
||||
m_fxChannels()
|
||||
{
|
||||
// create master channel
|
||||
m_fxChannels[0] = new FxChannel(this);
|
||||
|
||||
// create the rest of the channels
|
||||
for( int i = 1; i < NumFxChannels+1; ++i )
|
||||
{
|
||||
// create new channel
|
||||
m_fxChannels[i] = new FxChannel( this );
|
||||
|
||||
// send the channel into master
|
||||
createChannelSend(i, 0);
|
||||
}
|
||||
|
||||
// reset name etc.
|
||||
clear();
|
||||
createChannel();
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
FxMixer::~FxMixer()
|
||||
{
|
||||
for( int i = 0; i < NumFxChannels+1; ++i )
|
||||
for( int i = 0; i < m_fxChannels.size(); ++i )
|
||||
{
|
||||
delete m_fxChannels[i]->m_sendAmount[i];
|
||||
delete m_fxChannels[i];
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
void FxMixer::createChannelSend(fx_ch_t fromChannel, fx_ch_t toChannel)
|
||||
int FxMixer::createChannel()
|
||||
{
|
||||
// first make sure the send doesn't already exist
|
||||
if( ! channelSendsTo(fromChannel, toChannel) )
|
||||
{
|
||||
// add to from's sends
|
||||
m_fxChannels[fromChannel]->m_sends.push_back(toChannel);
|
||||
// create new channel
|
||||
m_fxChannels.push_back(new FxChannel( this ));
|
||||
|
||||
// add to to's receives
|
||||
m_fxChannels[toChannel]->m_receives.push_back(fromChannel);
|
||||
// reset channel state
|
||||
int index = m_fxChannels.size() - 1;
|
||||
clearChannel(index);
|
||||
|
||||
return index;
|
||||
}
|
||||
|
||||
|
||||
|
||||
void FxMixer::createChannelSend(fx_ch_t fromChannel, fx_ch_t toChannel,
|
||||
float amount)
|
||||
{
|
||||
// find the existing connection
|
||||
FxChannel * from = m_fxChannels[fromChannel];
|
||||
for(int i=0; i<from->m_sends.size(); ++i){
|
||||
if( from->m_sends[i] == toChannel )
|
||||
{
|
||||
// simply adjust the amount
|
||||
from->m_sendAmount[i]->setValue(amount);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
// connection does not exist. create a new one
|
||||
|
||||
// add to from's sends
|
||||
from->m_sends.push_back(toChannel);
|
||||
from->m_sendAmount.push_back(new FloatModel(amount, 0, 1, 0.001, NULL,
|
||||
tr("Amount to send")));
|
||||
|
||||
// add to to's receives
|
||||
m_fxChannels[toChannel]->m_receives.push_back(fromChannel);
|
||||
|
||||
}
|
||||
|
||||
|
||||
@@ -120,6 +135,8 @@ void FxMixer::deleteChannelSend(fx_ch_t fromChannel, fx_ch_t toChannel)
|
||||
if( from->m_sends[i] == toChannel )
|
||||
{
|
||||
// delete this index
|
||||
delete from->m_sendAmount[i];
|
||||
from->m_sendAmount.remove(i);
|
||||
from->m_sends.remove(i);
|
||||
break;
|
||||
}
|
||||
@@ -139,15 +156,15 @@ void FxMixer::deleteChannelSend(fx_ch_t fromChannel, fx_ch_t toChannel)
|
||||
|
||||
|
||||
|
||||
// does fromChannel send its output to the input of toChannel?
|
||||
bool FxMixer::channelSendsTo(fx_ch_t fromChannel, fx_ch_t toChannel)
|
||||
// how much does fromChannel send its output to the input of toChannel?
|
||||
FloatModel * FxMixer::channelSendModel(fx_ch_t fromChannel, fx_ch_t toChannel)
|
||||
{
|
||||
FxChannel * from = m_fxChannels[fromChannel];
|
||||
for(int i=0; i<from->m_sends.size(); ++i){
|
||||
if( from->m_sends[i] == toChannel )
|
||||
return true;
|
||||
return from->m_sendAmount[i];
|
||||
}
|
||||
return false;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
||||
@@ -182,12 +199,13 @@ void FxMixer::processChannel( fx_ch_t _ch, sampleFrame * _buf )
|
||||
processChannel( senderIndex );
|
||||
|
||||
// mix it with this one
|
||||
float amt = channelSendModel(senderIndex, _ch)->value();
|
||||
sampleFrame * ch_buf = sender->m_buffer;
|
||||
const float v = sender->m_volumeModel.value();
|
||||
for( f_cnt_t f = 0; f < fpp; ++f )
|
||||
{
|
||||
_buf[f][0] += ch_buf[f][0] * v;
|
||||
_buf[f][1] += ch_buf[f][1] * v;
|
||||
_buf[f][0] += ch_buf[f][0] * v * amt;
|
||||
_buf[f][1] += ch_buf[f][1] * v * amt;
|
||||
}
|
||||
engine::getMixer()->clearAudioBuffer( ch_buf,
|
||||
engine::getMixer()->framesPerPeriod() );
|
||||
@@ -233,13 +251,6 @@ void FxMixer::masterMix( sampleFrame * _buf )
|
||||
|
||||
processChannel( 0, _buf );
|
||||
|
||||
/*if( m_fxChannels[0]->m_muteModel.value() )
|
||||
{
|
||||
engine::getMixer()->clearAudioBuffer( _buf,
|
||||
engine::getMixer()->framesPerPeriod() );
|
||||
return;
|
||||
}*/
|
||||
|
||||
const float v = m_fxChannels[0]->m_volumeModel.value();
|
||||
for( f_cnt_t f = 0; f < engine::getMixer()->framesPerPeriod(); ++f )
|
||||
{
|
||||
@@ -256,25 +267,46 @@ void FxMixer::masterMix( sampleFrame * _buf )
|
||||
|
||||
void FxMixer::clear()
|
||||
{
|
||||
for( int i = 0; i <= NumFxChannels; ++i )
|
||||
for( int i = 0; i < m_fxChannels.size(); ++i )
|
||||
{
|
||||
m_fxChannels[i]->m_fxChain.clear();
|
||||
m_fxChannels[i]->m_volumeModel.setValue( 1.0f );
|
||||
m_fxChannels[i]->m_muteModel.setValue( false );
|
||||
m_fxChannels[i]->m_name = ( i == 0 ) ?
|
||||
tr( "Master" ) : tr( "FX %1" ).arg( i );
|
||||
m_fxChannels[i]->m_volumeModel.setDisplayName(
|
||||
m_fxChannels[i]->m_name );
|
||||
|
||||
clearChannel(i);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void FxMixer::clearChannel(fx_ch_t index)
|
||||
{
|
||||
FxChannel * ch = m_fxChannels[index];
|
||||
ch->m_fxChain.clear();
|
||||
ch->m_volumeModel.setValue( 1.0f );
|
||||
ch->m_muteModel.setValue( false );
|
||||
ch->m_name = ( index == 0 ) ? tr( "Master" ) : tr( "FX %1" ).arg( index );
|
||||
ch->m_volumeModel.setDisplayName(ch->m_name );
|
||||
|
||||
// send only to master
|
||||
if( index > 0)
|
||||
{
|
||||
// delete existing sends
|
||||
for( int i=0; i<ch->m_sends.size(); ++i)
|
||||
{
|
||||
deleteChannelSend(index, ch->m_sends[i]);
|
||||
}
|
||||
|
||||
// add send to master
|
||||
createChannelSend(index, 0);
|
||||
}
|
||||
|
||||
// delete receives
|
||||
for( int i=0; i<ch->m_receives.size(); ++i)
|
||||
{
|
||||
deleteChannelSend(ch->m_receives[i], index);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
void FxMixer::saveSettings( QDomDocument & _doc, QDomElement & _this )
|
||||
{
|
||||
for( int i = 0; i <= NumFxChannels; ++i )
|
||||
for( int i = 0; i < m_fxChannels.size(); ++i )
|
||||
{
|
||||
QDomElement fxch = _doc.createElement( QString( "fxchannel" ) );
|
||||
_this.appendChild( fxch );
|
||||
@@ -295,7 +327,7 @@ void FxMixer::loadSettings( const QDomElement & _this )
|
||||
{
|
||||
clear();
|
||||
QDomNode node = _this.firstChild();
|
||||
for( int i = 0; i <= NumFxChannels; ++i )
|
||||
for( int i = 0; i <= 64; ++i ) // TODO make this work
|
||||
{
|
||||
QDomElement fxch = node.toElement();
|
||||
int num = fxch.attribute( "num" ).toInt();
|
||||
|
||||
@@ -61,10 +61,6 @@
|
||||
#endif
|
||||
|
||||
|
||||
static QVector<fx_ch_t> __fx_channel_jobs( NumFxChannels );
|
||||
|
||||
|
||||
|
||||
class MixerWorkerThread : public QThread
|
||||
{
|
||||
public:
|
||||
@@ -284,11 +280,6 @@ mixer::mixer() :
|
||||
clearAudioBuffer( m_inputBuffer[i], m_inputBufferSize[i] );
|
||||
}
|
||||
|
||||
for( int i = 1; i < NumFxChannels+1; ++i )
|
||||
{
|
||||
__fx_channel_jobs[i-1] = (fx_ch_t) i;
|
||||
}
|
||||
|
||||
// just rendering?
|
||||
if( !engine::hasGUI() )
|
||||
{
|
||||
|
||||
@@ -22,6 +22,8 @@
|
||||
*
|
||||
*/
|
||||
|
||||
#include <QtGlobal>
|
||||
|
||||
#include <QtGui/QButtonGroup>
|
||||
#include <QtGui/QInputDialog>
|
||||
#include <QtGui/QLayout>
|
||||
@@ -31,9 +33,12 @@
|
||||
#include <QtGui/QPushButton>
|
||||
#include <QtGui/QToolButton>
|
||||
#include <QtGui/QStackedLayout>
|
||||
#include <QtGui/QScrollArea>
|
||||
|
||||
|
||||
#include "FxMixerView.h"
|
||||
#include "fader.h"
|
||||
#include "knob.h"
|
||||
#include "EffectRackView.h"
|
||||
#include "engine.h"
|
||||
#include "embed.h"
|
||||
@@ -44,26 +49,40 @@
|
||||
#include "pixmap_button.h"
|
||||
|
||||
|
||||
class SendIndicator : public QWidget
|
||||
{
|
||||
public:
|
||||
SendIndicator( QWidget * _parent ) :
|
||||
QWidget( _parent )
|
||||
{
|
||||
setFixedSize(23, 16);
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
class FxLine : public QWidget
|
||||
{
|
||||
public:
|
||||
FxLine( QWidget * _parent, FxMixerView * _mv, QString & _name ) :
|
||||
FxLine( QWidget * _parent, FxMixerView * _mv, QString & _name,
|
||||
int _channelIndex) :
|
||||
QWidget( _parent ),
|
||||
m_channelIndex( _channelIndex ),
|
||||
m_mv( _mv ),
|
||||
m_name( _name )
|
||||
{
|
||||
setFixedSize( 32, 232 );
|
||||
setFixedSize( 32, 287 );
|
||||
setAttribute( Qt::WA_OpaquePaintEvent, true );
|
||||
setCursor( QCursor( embed::getIconPixmap( "hand" ), 0, 0 ) );
|
||||
}
|
||||
|
||||
virtual void paintEvent( QPaintEvent * )
|
||||
{
|
||||
bool sendToThis = engine::fxMixer()->channelSendModel(
|
||||
m_mv->currentFxLine()->m_channelIndex, m_channelIndex) != NULL;
|
||||
QPainter painter;
|
||||
painter.begin( this );
|
||||
engine::getLmmsStyle()->drawFxLine( &painter,
|
||||
this, m_name, m_mv->currentFxLine() == this );
|
||||
engine::getLmmsStyle()->drawFxLine( &painter, this, m_name,
|
||||
m_mv->currentFxLine() == this, sendToThis );
|
||||
painter.end();
|
||||
}
|
||||
|
||||
@@ -87,7 +106,8 @@ public:
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
knob * m_sendKnob;
|
||||
int m_channelIndex;
|
||||
private:
|
||||
FxMixerView * m_mv;
|
||||
QString & m_name;
|
||||
@@ -114,10 +134,6 @@ FxMixerView::FxMixerView() :
|
||||
setWindowTitle( tr( "FX-Mixer" ) );
|
||||
setWindowIcon( embed::getIconPixmap( "fx_mixer" ) );
|
||||
|
||||
m_fxLineBanks = new QStackedLayout;
|
||||
m_fxLineBanks->setSpacing( 0 );
|
||||
m_fxLineBanks->setMargin( 1 );
|
||||
|
||||
m_fxRacksLayout = new QStackedLayout;
|
||||
m_fxRacksLayout->setSpacing( 0 );
|
||||
m_fxRacksLayout->setMargin( 0 );
|
||||
@@ -128,93 +144,40 @@ FxMixerView::FxMixerView() :
|
||||
ml->setSpacing( 0 );
|
||||
ml->addSpacing( 6 );
|
||||
|
||||
m_fxChannelViews.resize(m->numChannels());
|
||||
channelArea = new QScrollArea(this);
|
||||
chLayout = new QHBoxLayout(channelArea);
|
||||
|
||||
QHBoxLayout * banks[NumFxChannels/16];
|
||||
for( int i = 0; i < NumFxChannels/16; ++i )
|
||||
// add master channel
|
||||
FxChannelView * masterView = &m_fxChannelViews[0];
|
||||
addFxLine(0, this, ml);
|
||||
ml->addSpacing(5);
|
||||
QSize fxLineSize = masterView->m_fxLine->size();
|
||||
|
||||
chLayout->setSizeConstraint(QLayout::SetMinimumSize);
|
||||
channelArea->setWidgetResizable(true);
|
||||
|
||||
// add mixer channels
|
||||
for( int i = 1; i < m_fxChannelViews.size(); ++i )
|
||||
{
|
||||
QWidget * w = new QWidget( this );
|
||||
banks[i] = new QHBoxLayout( w );
|
||||
banks[i]->setMargin( 5 );
|
||||
banks[i]->setSpacing( 1 );
|
||||
m_fxLineBanks->addWidget( w );
|
||||
addFxLine(i, channelArea, chLayout);
|
||||
}
|
||||
// add the scrolling section to the main layout
|
||||
ml->addLayout(chLayout);
|
||||
|
||||
for( int i = 0; i < NumFxChannels+1; ++i )
|
||||
{
|
||||
FxChannelView * cv = &m_fxChannelViews[i];
|
||||
if( i == 0 )
|
||||
{
|
||||
cv->m_fxLine = new FxLine( NULL, this,
|
||||
m->m_fxChannels[i]->m_name );
|
||||
ml->addWidget( cv->m_fxLine );
|
||||
ml->addSpacing( 10 );
|
||||
}
|
||||
else
|
||||
{
|
||||
const int bank = (i-1) / 16;
|
||||
cv->m_fxLine = new FxLine( NULL, this,
|
||||
m->m_fxChannels[i]->m_name );
|
||||
banks[bank]->addWidget( cv->m_fxLine );
|
||||
}
|
||||
lcdSpinBox * l = new lcdSpinBox( 2, cv->m_fxLine );
|
||||
l->model()->setRange( i, i );
|
||||
l->model()->setValue( i );
|
||||
l->move( 2, 4 );
|
||||
l->setMarginWidth( 1 );
|
||||
// show the add new effect channel button
|
||||
QPushButton * newChannelBtn = new QPushButton("new", this );
|
||||
newChannelBtn->setFont(QFont("sans-serif", 10, 1, false));
|
||||
newChannelBtn->setFixedSize(fxLineSize);
|
||||
connect( newChannelBtn, SIGNAL(clicked()), this, SLOT(addNewChannel()));
|
||||
ml->addWidget( newChannelBtn );
|
||||
|
||||
|
||||
cv->m_fader = new fader( &m->m_fxChannels[i]->m_volumeModel,
|
||||
tr( "FX Fader %1" ).arg( i ),
|
||||
cv->m_fxLine );
|
||||
cv->m_fader->move( 15-cv->m_fader->width()/2,
|
||||
cv->m_fxLine->height()-
|
||||
cv->m_fader->height()-5 );
|
||||
|
||||
cv->m_muteBtn = new pixmapButton( cv->m_fxLine, tr( "Mute" ) );
|
||||
cv->m_muteBtn->setModel( &m->m_fxChannels[i]->m_muteModel );
|
||||
cv->m_muteBtn->setActiveGraphic(
|
||||
embed::getIconPixmap( "led_off" ) );
|
||||
cv->m_muteBtn->setInactiveGraphic(
|
||||
embed::getIconPixmap( "led_green" ) );
|
||||
cv->m_muteBtn->setCheckable( true );
|
||||
cv->m_muteBtn->move( 9, cv->m_fader->y()-16);
|
||||
toolTip::add( cv->m_muteBtn, tr( "Mute this FX channel" ) );
|
||||
|
||||
cv->m_rackView = new EffectRackView(
|
||||
&m->m_fxChannels[i]->m_fxChain, this );
|
||||
m_fxRacksLayout->addWidget( cv->m_rackView );
|
||||
if( i == 0 )
|
||||
{
|
||||
QVBoxLayout * l = new QVBoxLayout;
|
||||
l->addSpacing( 10 );
|
||||
QButtonGroup * g = new QButtonGroup( this );
|
||||
m_bankButtons = g;
|
||||
g->setExclusive( true );
|
||||
for( int j = 0; j < 4; ++j )
|
||||
{
|
||||
QToolButton * btn = new QToolButton;
|
||||
btn->setText( QString( 'A'+j ) );
|
||||
btn->setCheckable( true );
|
||||
btn->setSizePolicy( QSizePolicy::Preferred,
|
||||
QSizePolicy::Expanding );
|
||||
l->addWidget( btn );
|
||||
g->addButton( btn, j );
|
||||
btn->setChecked( j == 0);
|
||||
}
|
||||
l->addSpacing( 10 );
|
||||
ml->addLayout( l );
|
||||
connect( g, SIGNAL( buttonClicked( int ) ),
|
||||
m_fxLineBanks, SLOT( setCurrentIndex( int ) ) );
|
||||
}
|
||||
}
|
||||
|
||||
ml->addLayout( m_fxLineBanks );
|
||||
ml->addLayout( m_fxRacksLayout );
|
||||
|
||||
|
||||
setLayout( ml );
|
||||
updateGeometry();
|
||||
|
||||
m_fxLineBanks->setCurrentIndex( 0 );
|
||||
setCurrentFxLine( m_fxChannelViews[0].m_fxLine );
|
||||
|
||||
// timer for updating faders
|
||||
@@ -226,10 +189,9 @@ FxMixerView::FxMixerView() :
|
||||
QMdiSubWindow * subWin =
|
||||
engine::mainWindow()->workspace()->addSubWindow( this );
|
||||
Qt::WindowFlags flags = subWin->windowFlags();
|
||||
flags |= Qt::MSWindowsFixedSizeDialogHint;
|
||||
flags &= ~Qt::WindowMaximizeButtonHint;
|
||||
subWin->setWindowFlags( flags );
|
||||
subWin->layout()->setSizeConstraint(QLayout::SetFixedSize);
|
||||
subWin->layout()->setSizeConstraint(QLayout::SetMinimumSize);
|
||||
|
||||
parentWidget()->setAttribute( Qt::WA_DeleteOnClose, false );
|
||||
parentWidget()->move( 5, 310 );
|
||||
@@ -239,6 +201,54 @@ FxMixerView::FxMixerView() :
|
||||
}
|
||||
|
||||
|
||||
void FxMixerView::addFxLine(int i, QWidget * parent, QLayout * layout)
|
||||
{
|
||||
FxMixer * m = engine::fxMixer();
|
||||
|
||||
FxChannelView * cv = &m_fxChannelViews[i];
|
||||
|
||||
cv->m_fxLine = new FxLine( parent, this,
|
||||
m->m_fxChannels[i]->m_name, i );
|
||||
layout->addWidget(cv->m_fxLine);
|
||||
|
||||
// mixer sends knob
|
||||
cv->m_fxLine->m_sendKnob = new knob(0, cv->m_fxLine,
|
||||
tr("Channel send amount"));
|
||||
cv->m_fxLine->m_sendKnob->move(0, 22);
|
||||
cv->m_fxLine->m_sendKnob->setVisible(false);
|
||||
|
||||
// send light indicator
|
||||
|
||||
|
||||
// channel number
|
||||
lcdSpinBox * l = new lcdSpinBox( 2, cv->m_fxLine );
|
||||
l->model()->setRange( i, i );
|
||||
l->model()->setValue( i );
|
||||
l->move( 2, 58 );
|
||||
l->setMarginWidth( 1 );
|
||||
|
||||
|
||||
cv->m_fader = new fader( &m->m_fxChannels[i]->m_volumeModel,
|
||||
tr( "FX Fader %1" ).arg( i ),
|
||||
cv->m_fxLine );
|
||||
cv->m_fader->move( 15-cv->m_fader->width()/2,
|
||||
cv->m_fxLine->height()-
|
||||
cv->m_fader->height()-5 );
|
||||
|
||||
cv->m_muteBtn = new pixmapButton( cv->m_fxLine, tr( "Mute" ) );
|
||||
cv->m_muteBtn->setModel( &m->m_fxChannels[i]->m_muteModel );
|
||||
cv->m_muteBtn->setActiveGraphic(
|
||||
embed::getIconPixmap( "led_off" ) );
|
||||
cv->m_muteBtn->setInactiveGraphic(
|
||||
embed::getIconPixmap( "led_green" ) );
|
||||
cv->m_muteBtn->setCheckable( true );
|
||||
cv->m_muteBtn->move( 9, cv->m_fader->y()-16);
|
||||
toolTip::add( cv->m_muteBtn, tr( "Mute this FX channel" ) );
|
||||
|
||||
cv->m_rackView = new EffectRackView(
|
||||
&m->m_fxChannels[i]->m_fxChain, this );
|
||||
m_fxRacksLayout->addWidget( cv->m_rackView );
|
||||
}
|
||||
|
||||
|
||||
FxMixerView::~FxMixerView()
|
||||
@@ -247,6 +257,18 @@ FxMixerView::~FxMixerView()
|
||||
|
||||
|
||||
|
||||
void FxMixerView::addNewChannel()
|
||||
{
|
||||
// add new fx mixer channel and redraw the form.
|
||||
FxMixer * mix = engine::fxMixer();
|
||||
|
||||
int newChannelIndex = mix->createChannel();
|
||||
m_fxChannelViews.push_back(FxChannelView());
|
||||
|
||||
addFxLine(newChannelIndex, channelArea, chLayout);
|
||||
}
|
||||
|
||||
|
||||
|
||||
void FxMixerView::saveSettings( QDomDocument & _doc, QDomElement & _this )
|
||||
{
|
||||
@@ -266,13 +288,29 @@ void FxMixerView::loadSettings( const QDomElement & _this )
|
||||
|
||||
void FxMixerView::setCurrentFxLine( FxLine * _line )
|
||||
{
|
||||
FxMixer * mix = engine::fxMixer();
|
||||
|
||||
// select
|
||||
m_currentFxLine = _line;
|
||||
for( int i = 0; i < NumFxChannels+1; ++i )
|
||||
m_fxRacksLayout->setCurrentIndex( _line->m_channelIndex );
|
||||
|
||||
// set up send knob
|
||||
for(int i = 0; i < m_fxChannelViews.size(); ++i)
|
||||
{
|
||||
if( m_fxChannelViews[i].m_fxLine == _line )
|
||||
// does current channel send to this channel?
|
||||
FloatModel * sendModel = mix->channelSendModel(_line->m_channelIndex, i);
|
||||
if( sendModel == NULL )
|
||||
{
|
||||
m_fxRacksLayout->setCurrentIndex( i );
|
||||
// does not send, hide send knob
|
||||
m_fxChannelViews[i].m_fxLine->m_sendKnob->setVisible(false);
|
||||
}
|
||||
else
|
||||
{
|
||||
// it does send, show knob and connect
|
||||
m_fxChannelViews[i].m_fxLine->m_sendKnob->setVisible(true);
|
||||
m_fxChannelViews[i].m_fxLine->m_sendKnob->setModel(sendModel);
|
||||
}
|
||||
|
||||
m_fxChannelViews[i].m_fxLine->update();
|
||||
}
|
||||
}
|
||||
@@ -281,12 +319,7 @@ void FxMixerView::setCurrentFxLine( FxLine * _line )
|
||||
|
||||
void FxMixerView::setCurrentFxLine( int _line )
|
||||
{
|
||||
if ( _line >= 0 && _line < NumFxChannels+1 )
|
||||
{
|
||||
setCurrentFxLine( m_fxChannelViews[_line].m_fxLine );
|
||||
|
||||
m_bankButtons->button( (_line-1) / 16 )->click();
|
||||
}
|
||||
setCurrentFxLine( m_fxChannelViews[_line].m_fxLine );
|
||||
}
|
||||
|
||||
|
||||
@@ -294,7 +327,7 @@ void FxMixerView::setCurrentFxLine( int _line )
|
||||
|
||||
void FxMixerView::clear()
|
||||
{
|
||||
for( int i = 0; i <= NumFxChannels; ++i )
|
||||
for( int i = 0; i < m_fxChannelViews.size(); ++i )
|
||||
{
|
||||
m_fxChannelViews[i].m_rackView->clearViews();
|
||||
}
|
||||
@@ -306,7 +339,7 @@ void FxMixerView::clear()
|
||||
void FxMixerView::updateFaders()
|
||||
{
|
||||
FxMixer * m = engine::fxMixer();
|
||||
for( int i = 0; i < NumFxChannels+1; ++i )
|
||||
for( int i = 0; i < m_fxChannelViews.size(); ++i )
|
||||
{
|
||||
const float opl = m_fxChannelViews[i].m_fader->getPeak_L();
|
||||
const float opr = m_fxChannelViews[i].m_fader->getPeak_R();
|
||||
|
||||
@@ -279,7 +279,7 @@ int ClassicStyle::pixelMetric( PixelMetric _metric,
|
||||
|
||||
|
||||
void ClassicStyle::drawFxLine( QPainter * _painter, const QWidget *_fxLine,
|
||||
const QString & _name, bool _active )
|
||||
const QString & _name, bool _active, bool _sendToThis )
|
||||
{
|
||||
int width = _fxLine->rect().width();
|
||||
int height = _fxLine->rect().height();
|
||||
@@ -293,10 +293,18 @@ void ClassicStyle::drawFxLine( QPainter * _painter, const QWidget *_fxLine,
|
||||
p->setPen( QColor( 20, 24, 32 ) );
|
||||
p->drawRect( 0, 0, width-1, height-1 );
|
||||
|
||||
// draw the mixer send background
|
||||
if( _sendToThis )
|
||||
{
|
||||
p->drawPixmap(2, 0, 28, 56,
|
||||
embed::getIconPixmap("send_bg_arrow", 28, 56));
|
||||
}
|
||||
|
||||
// draw the channel name
|
||||
p->rotate( -90 );
|
||||
p->setPen( _active ? QColor( 0, 255, 0 ) : Qt::white );
|
||||
p->setFont( pointSizeF( _fxLine->font(), 7.5f ) );
|
||||
p->drawText( -90, 20, _name );
|
||||
p->drawText( -145, 20, _name );
|
||||
}
|
||||
|
||||
void ClassicStyle::drawTrackContentBackground(QPainter * _painter,
|
||||
|
||||
@@ -881,7 +881,7 @@ int CusisStyle::pixelMetric( PixelMetric _metric, const QStyleOption * _option,
|
||||
|
||||
|
||||
void CusisStyle::drawFxLine( QPainter * _painter, const QWidget *_fxLine,
|
||||
const QString & _name, bool _active )
|
||||
const QString & _name, bool _active, bool _sendToThis )
|
||||
{
|
||||
int width = _fxLine->rect().width();
|
||||
int height = _fxLine->rect().height();
|
||||
|
||||
@@ -103,7 +103,7 @@ InstrumentTrack::InstrumentTrack( trackContainer * _tc ) :
|
||||
this, tr( "Panning" ) ),
|
||||
m_pitchModel( 0, -100, 100, 1, this, tr( "Pitch" ) ),
|
||||
m_pitchRangeModel( 1, 1, 24, this, tr( "Pitch range" ) ),
|
||||
m_effectChannelModel( 0, 0, NumFxChannels, this, tr( "FX channel" ) ),
|
||||
m_effectChannelModel( 0, 0, 10, this, tr( "FX channel" ) ), // change this so it's a combo box, all the channels and then new.
|
||||
m_instrument( NULL ),
|
||||
m_soundShaping( this ),
|
||||
m_arpeggiator( this ),
|
||||
|
||||
Reference in New Issue
Block a user