Merge branch 'stable-1.1'

Conflicts:
	include/AutomatableModel.h
	include/FxMixer.h
	src/core/FxMixer.cpp
	src/gui/widgets/caption_menu.cpp
	src/tracks/InstrumentTrack.cpp
This commit is contained in:
Vesa
2014-11-16 15:16:40 +02:00
21 changed files with 184 additions and 133 deletions

View File

@@ -47,6 +47,7 @@ AutomatableModel::AutomatableModel( DataType type,
m_step( step ),
m_range( max - min ),
m_centerValue( m_minValue ),
m_valueChanged( false ),
m_setValueDepth( 0 ),
m_hasStrictStepSize( false ),
m_hasLinkedModels( false ),
@@ -240,6 +241,7 @@ void AutomatableModel::setValue( const float value )
(*it)->setJournalling( journalling );
}
}
m_valueChanged = true;
emit dataChanged();
}
else
@@ -334,6 +336,7 @@ void AutomatableModel::setAutomatedValue( const float value )
(*it)->setAutomatedValue( value );
}
}
m_valueChanged = true;
emit dataChanged();
}
--m_setValueDepth;
@@ -478,6 +481,7 @@ void AutomatableModel::setControllerConnection( ControllerConnection* c )
{
QObject::connect( m_controllerConnection, SIGNAL( valueChanged() ), this, SIGNAL( dataChanged() ) );
QObject::connect( m_controllerConnection, SIGNAL( destroyed() ), this, SLOT( unlinkControllerConnection() ) );
m_valueChanged = true;
emit dataChanged();
}
}

View File

@@ -70,7 +70,8 @@ FxChannel::FxChannel( int idx, Model * _parent ) :
m_name(),
m_lock(),
m_channelIndex( idx ),
m_queued( false )
m_queued( false ),
m_dependenciesMet( 0 )
{
engine::mixer()->clearAudioBuffer( m_buffer,
engine::mixer()->framesPerPeriod() );
@@ -85,6 +86,27 @@ FxChannel::~FxChannel()
}
inline void FxChannel::processed()
{
foreach( FxRoute * receiverRoute, m_sends )
{
if( receiverRoute->receiver()->m_muted == false )
{
receiverRoute->receiver()->incrementDeps();
}
}
}
void FxChannel::incrementDeps()
{
m_dependenciesMet.ref();
if( m_dependenciesMet >= m_receives.size() )
{
m_queued = true;
MixerWorkerThread::addJob( this );
m_dependenciesMet = 0;
}
}
void FxChannel::unmuteForSolo()
{
@@ -107,25 +129,14 @@ void FxChannel::doProcessing( sampleFrame * _buf )
// <tobydox> this improves cache hit rate
_buf = m_buffer;
if( m_muteModel.value() == false )
if( m_muted == false )
{
// OK, we are not muted, so we go recursively through all the channels
// which send to us (our children)...
foreach( FxRoute * senderRoute, m_receives )
{
FxChannel * sender = senderRoute->sender();
FloatModel * sendModel = senderRoute->amount();
if( ! sendModel ) qFatal( "Error: no send model found from %d to %d", senderRoute->senderIndex(), m_channelIndex );
// wait for the sender job - either it's just been queued yet,
// then ThreadableJob::process() will process it now within this
// thread - otherwise it has been is is being processed by another
// thread and we just have to wait for it to finish
while( sender->state() != ThreadableJob::Done )
{
sender->process();
}
if( sender->m_hasInput || sender->m_stillRunning )
{
// figure out if we're getting sample-exact input
@@ -158,20 +169,28 @@ void FxChannel::doProcessing( sampleFrame * _buf )
m_hasInput = true;
}
}
const float v = m_volumeModel.value();
if( m_hasInput )
{
// only start fxchain when we have input...
m_fxChain.startRunning();
}
m_stillRunning = m_fxChain.processAudioBuffer( _buf, fpp, m_hasInput );
m_peakLeft = qMax( m_peakLeft, engine::mixer()->peakValueLeft( _buf, fpp ) * v );
m_peakRight = qMax( m_peakRight, engine::mixer()->peakValueRight( _buf, fpp ) * v );
}
const float v = m_volumeModel.value();
if( m_hasInput )
else
{
// only start fxchain when we have input...
m_fxChain.startRunning();
m_peakLeft = m_peakRight = 0.0f;
}
m_stillRunning = m_fxChain.processAudioBuffer( _buf, fpp, m_hasInput );
m_peakLeft = qMax( m_peakLeft, engine::mixer()->peakValueLeft( _buf, fpp ) * v );
m_peakRight = qMax( m_peakRight, engine::mixer()->peakValueRight( _buf, fpp ) * v );
// increment dependency counter of all receivers
processed();
}
@@ -456,11 +475,9 @@ void FxMixer::deleteChannelSend( FxRoute * route )
bool FxMixer::isInfiniteLoop( fx_ch_t sendFrom, fx_ch_t sendTo )
{
if( sendFrom == sendTo ) return true;
//m_sendsMutex.lock();
FxChannel * from = m_fxChannels[sendFrom];
FxChannel * to = m_fxChannels[sendTo];
bool b = checkInfiniteLoop( from, to );
//m_sendsMutex.unlock();
return b;
}
@@ -538,42 +555,38 @@ void FxMixer::prepareMasterMix()
void FxMixer::addChannelLeaf( FxChannel * ch, sampleFrame * buf )
{
// if we're muted or this channel is seen already, discount it
if( ch->m_queued )
{
return;
}
foreach( FxRoute * senderRoute, ch->m_receives )
{
addChannelLeaf( senderRoute->sender(), buf );
}
// add this channel to job list
ch->m_queued = true;
MixerWorkerThread::addJob( ch );
}
void FxMixer::masterMix( sampleFrame * _buf )
{
const int fpp = engine::mixer()->framesPerPeriod();
// recursively loop through channel dependency chain
// and add all channels to job list that have no dependencies
// when the channel completes it will check its parent to see if it needs
// to be processed.
//m_sendsMutex.lock();
MixerWorkerThread::resetJobQueue( MixerWorkerThread::JobQueue::Dynamic );
addChannelLeaf( m_fxChannels[0], _buf );
while( m_fxChannels[0]->state() != ThreadableJob::Done )
if( m_sendsMutex.tryLock() )
{
MixerWorkerThread::startAndWaitForJobs();
// add the channels that have no dependencies (no incoming senders, ie. no receives)
// to the jobqueue. The channels that have receives get added when their senders get processed, which
// is detected by dependency counting.
// also instantly add all muted channels as they don't need to care about their senders, and can just increment the deps of
// their recipients right away.
MixerWorkerThread::resetJobQueue( MixerWorkerThread::JobQueue::Dynamic );
foreach( FxChannel * ch, m_fxChannels )
{
ch->m_muted = ch->m_muteModel.value();
if( ch->m_muted ) // instantly "process" muted channels
{
ch->processed();
ch->done();
}
else if( ch->m_receives.size() == 0 )
{
ch->m_queued = true;
MixerWorkerThread::addJob( ch );
}
}
while( m_fxChannels[0]->state() != ThreadableJob::Done )
{
MixerWorkerThread::startAndWaitForJobs();
}
m_sendsMutex.unlock();
}
//m_sendsMutex.unlock();
// handle sample-exact data in master volume fader
ValueBuffer * volBuf = m_fxChannels[0]->m_volumeModel.valueBuffer();

View File

@@ -1044,7 +1044,7 @@ void trackContentWidget::updateBackground()
// draw lines
pmp.setPen( QPen( QColor( 0, 0, 0, 160 ), 1 ) );
// horizontal line
pmp.drawLine( 0, 0, w*2, 0 );
pmp.drawLine( 0, h-1, w*2, h-1 );
// vertical lines
for( float x = 0; x < w * 2; x += ppt )

View File

@@ -176,14 +176,12 @@ void ControllerView::modelChanged()
void ControllerView::contextMenuEvent( QContextMenuEvent * )
{
QPointer<captionMenu> contextMenu = new captionMenu( model()->displayName() );
QPointer<captionMenu> contextMenu = new captionMenu( model()->displayName(), this );
contextMenu->addAction( embed::getIconPixmap( "cancel" ),
tr( "&Remove this plugin" ),
this, SLOT( deleteController() ) );
contextMenu->addSeparator();
contextMenu->addAction( embed::getIconPixmap( "help" ),
tr( "&Help" ),
this, SLOT( displayHelp() ) );
contextMenu->addHelpAction();
contextMenu->exec( QCursor::pos() );
delete contextMenu;
}

View File

@@ -245,7 +245,7 @@ void EffectView::closeEffects()
void EffectView::contextMenuEvent( QContextMenuEvent * )
{
QPointer<captionMenu> contextMenu = new captionMenu( model()->displayName() );
QPointer<captionMenu> contextMenu = new captionMenu( model()->displayName(), this );
contextMenu->addAction( embed::getIconPixmap( "arp_up" ),
tr( "Move &up" ),
this, SLOT( moveUp() ) );
@@ -257,9 +257,7 @@ void EffectView::contextMenuEvent( QContextMenuEvent * )
tr( "&Remove this plugin" ),
this, SLOT( deletePlugin() ) );
contextMenu->addSeparator();
contextMenu->addAction( embed::getIconPixmap( "help" ),
tr( "&Help" ),
this, SLOT( displayHelp() ) );
contextMenu->addHelpAction();
contextMenu->exec( QCursor::pos() );
delete contextMenu;
}

View File

@@ -183,7 +183,7 @@ void FxLine::mouseDoubleClickEvent( QMouseEvent * )
void FxLine::contextMenuEvent( QContextMenuEvent * )
{
FxMixer * mix = engine::fxMixer();
QPointer<captionMenu> contextMenu = new captionMenu( mix->effectChannel( m_channelIndex )->m_name );
QPointer<captionMenu> contextMenu = new captionMenu( mix->effectChannel( m_channelIndex )->m_name, this );
if( m_channelIndex != 0 ) // no move-options in master
{
contextMenu->addAction( tr( "Move &left" ), this, SLOT( moveChannelLeft() ) );
@@ -199,9 +199,7 @@ void FxLine::contextMenuEvent( QContextMenuEvent * )
contextMenu->addSeparator();
}
contextMenu->addAction( embed::getIconPixmap( "help" ),
tr( "&Help" ),
this, SLOT( displayHelp() ) );
contextMenu->addHelpAction();
contextMenu->exec( QCursor::pos() );
delete contextMenu;
}

View File

@@ -24,6 +24,7 @@
#include "caption_menu.h"
#include "embed.h"
@@ -45,6 +46,19 @@ captionMenu::~captionMenu()
void captionMenu::addHelpAction()
{
QWidget* parent = (QWidget*) this->parent();
if (parent == NULL)
return;
if (! parent->whatsThis().isEmpty()) {
addAction( embed::getIconPixmap( "help" ), tr( "&Help" ),
parent, SLOT( displayHelp() ) );
}
else {
QAction* helpAction = addAction( embed::getIconPixmap("help"), tr("Help (not available)") );
helpAction->setDisabled(true);
}
}

View File

@@ -481,11 +481,10 @@ void knob::contextMenuEvent( QContextMenuEvent * )
// an QApplication::restoreOverrideCursor()-call...
mouseReleaseEvent( NULL );
captionMenu contextMenu( model()->displayName() );
captionMenu contextMenu( model()->displayName(), this );
addDefaultActions( &contextMenu );
contextMenu.addSeparator();
contextMenu.addAction( embed::getIconPixmap( "help" ), tr( "&Help" ),
this, SLOT( displayHelp() ) );
contextMenu.addHelpAction();
contextMenu.exec( QCursor::pos() );
}

View File

@@ -83,7 +83,7 @@ void TempoSyncKnob::contextMenuEvent( QContextMenuEvent * )
{
mouseReleaseEvent( NULL );
captionMenu contextMenu( model()->displayName() );
captionMenu contextMenu( model()->displayName(), this );
addDefaultActions( &contextMenu );
contextMenu.addSeparator();
@@ -147,9 +147,7 @@ void TempoSyncKnob::contextMenuEvent( QContextMenuEvent * )
}
contextMenu.addSeparator();
contextMenu.addAction( embed::getIconPixmap( "help" ), tr( "&Help" ),
this, SLOT( displayHelp() ) );
contextMenu.addHelpAction();
contextMenu.exec( QCursor::pos() );
delete syncMenu;

View File

@@ -806,6 +806,7 @@ void InstrumentTrack::loadTrackSpecificSettings( const QDomElement & thisElement
}
node = node.nextSibling();
}
updatePitchRange();
unlock();
}
@@ -1585,10 +1586,3 @@ void InstrumentTrackWindow::loadSettings( const QDomElement& thisElement )
m_itv->m_tlb->setChecked( true );
}
}