Ability to save mixer sends to disk with the mmp

LMMS can load projects with the old mixer and new projects with
the new mixer. By "new mixer", I simply mean not hardcoded to 64
channels.
This commit is contained in:
Andrew Kelley
2009-10-01 02:45:32 -07:00
parent dd28a654b5
commit 333df687e6
8 changed files with 152 additions and 42 deletions

View File

@@ -442,13 +442,16 @@ void FxMixer::masterMix( sampleFrame * _buf )
void FxMixer::clear()
{
for( int i = 0; i < m_fxChannels.size(); ++i )
while( m_fxChannels.size() > 1 )
{
clearChannel(i);
deleteChannel(1);
}
clearChannel(0);
}
void FxMixer::clearChannel(fx_ch_t index)
{
FxChannel * ch = m_fxChannels[index];
@@ -483,38 +486,94 @@ void FxMixer::saveSettings( QDomDocument & _doc, QDomElement & _this )
{
for( int i = 0; i < m_fxChannels.size(); ++i )
{
FxChannel * ch = m_fxChannels[i];
QDomElement fxch = _doc.createElement( QString( "fxchannel" ) );
_this.appendChild( fxch );
m_fxChannels[i]->m_fxChain.saveState( _doc, fxch );
m_fxChannels[i]->m_volumeModel.saveSettings( _doc, fxch,
"volume" );
m_fxChannels[i]->m_muteModel.saveSettings( _doc, fxch,
"muted" );
ch->m_fxChain.saveState( _doc, fxch );
ch->m_volumeModel.saveSettings( _doc, fxch, "volume" );
ch->m_muteModel.saveSettings( _doc, fxch, "muted" );
fxch.setAttribute( "num", i );
fxch.setAttribute( "name", m_fxChannels[i]->m_name );
fxch.setAttribute( "name", ch->m_name );
// add the channel sends
for( int si = 0; si < ch->m_sends.size(); ++si )
{
QDomElement sendsDom = _doc.createElement( QString( "send" ) );
fxch.appendChild( sendsDom );
sendsDom.setAttribute( "channel", ch->m_sends[si] );
ch->m_sendAmount[si]->saveSettings( _doc, sendsDom, "amount");
}
}
}
void FxMixer::allocateChannelsTo(int num)
{
while( num > m_fxChannels.size() - 1 )
{
createChannel();
// delete the default send to master
deleteChannelSend(m_fxChannels.size()-1, 0);
}
}
void FxMixer::loadSettings( const QDomElement & _this )
{
clear();
QDomNode node = _this.firstChild();
for( int i = 0; i <= 64; ++i ) // TODO make this work
bool thereIsASend = false;
while( ! node.isNull() )
{
QDomElement fxch = node.toElement();
// index of the channel we are about to load
int num = fxch.attribute( "num" ).toInt();
m_fxChannels[num]->m_fxChain.restoreState(
fxch.firstChildElement(
m_fxChannels[num]->m_fxChain.nodeName() ) );
// allocate enough channels
allocateChannelsTo( num );
m_fxChannels[num]->m_volumeModel.loadSettings( fxch, "volume" );
m_fxChannels[num]->m_muteModel.loadSettings( fxch, "muted" );
m_fxChannels[num]->m_name = fxch.attribute( "name" );
m_fxChannels[num]->m_fxChain.restoreState( fxch.firstChildElement(
m_fxChannels[num]->m_fxChain.nodeName() ) );
// mixer sends
QDomNodeList chData = fxch.childNodes();
for( unsigned int i=0; i<chData.length(); ++i )
{
QDomElement chDataItem = chData.at(i).toElement();
if( chDataItem.nodeName() == QString( "send" ) )
{
thereIsASend = true;
int sendTo = chDataItem.attribute( "channel" ).toInt();
allocateChannelsTo( sendTo) ;
float amount = chDataItem.attribute( "amount" ).toFloat();
createChannelSend( num, sendTo, amount );
}
}
node = node.nextSibling();
}
// check for old format. 65 fx channels and no explicit sends.
if( ! thereIsASend && m_fxChannels.size() == 65 ) {
// create a send from every channel into master
for( int i=1; i<m_fxChannels.size(); ++i )
{
createChannelSend(i, 0);
}
}
emit dataChanged();
}

View File

@@ -904,6 +904,23 @@ void song::loadProject( const QString & _file_name )
firstChildElement( "track" ) );
}
QDomNode node = mmp.content().firstChild();
// walk through and fix up the mixer
while( !node.isNull() )
{
if( node.nodeName() == engine::fxMixer()->nodeName() )
{
engine::fxMixer()->restoreState( node.toElement() );
// refresh FxMixerView
engine::fxMixerView()->refreshDisplay();
}
node = node.nextSibling();
}
node = mmp.content().firstChild();
while( !node.isNull() )
{
if( node.isElement() )
@@ -917,10 +934,6 @@ void song::loadProject( const QString & _file_name )
{
restoreControllerStates( node.toElement() );
}
else if( node.nodeName() == engine::fxMixer()->nodeName() )
{
engine::fxMixer()->restoreState( node.toElement() );
}
else if( engine::hasGUI() )
{
if( node.nodeName() ==
@@ -973,7 +986,6 @@ void song::loadProject( const QString & _file_name )
// resolve all IDs so that autoModels are automated
automationPattern::resolveAllIDs();
engine::getMixer()->unlock();
configManager::inst()->addRecentlyOpenedProject( _file_name );

View File

@@ -9,7 +9,6 @@
#include "FxMixerView.h"
#include "embed.h"
#include "engine.h"
#include "lcd_spinbox.h"
#include "SendButtonIndicator.h"
FxLine::FxLine( QWidget * _parent, FxMixerView * _mv, int _channelIndex) :
@@ -32,11 +31,27 @@ FxLine::FxLine( QWidget * _parent, FxMixerView * _mv, int _channelIndex) :
m_sendBtn->move(4,4);
// channel number
lcdSpinBox * l = new lcdSpinBox( 2, this );
l->model()->setRange( m_channelIndex, m_channelIndex );
l->model()->setValue( m_channelIndex );
l->move( 2, 58 );
l->setMarginWidth( 1 );
m_lcd = new lcdSpinBox( 2, this );
m_lcd->model()->setRange( m_channelIndex, m_channelIndex );
m_lcd->model()->setValue( m_channelIndex );
m_lcd->move( 2, 58 );
m_lcd->setMarginWidth( 1 );
}
FxLine::~FxLine()
{
delete m_sendKnob;
delete m_sendBtn;
delete m_lcd;
}
void FxLine::setChannelIndex(int index) {
m_channelIndex = index;
m_lcd->model()->setRange( m_channelIndex, m_channelIndex );
m_lcd->model()->setValue( m_channelIndex );
m_lcd->update();
}

View File

@@ -91,8 +91,8 @@ FxMixerView::FxMixerView() :
m_fxChannelViews[i] = new FxChannelView(m_channelAreaWidget, this, i);
chLayout->addWidget(m_fxChannelViews[i]->m_fxLine);
}
// add the scrolling section to the main layout
// add the scrolling section to the main layout
// class solely for scroll area to pass key presses down
class ChannelArea : public QScrollArea
{
@@ -175,6 +175,32 @@ void FxMixerView::addNewChannel()
}
void FxMixerView::refreshDisplay()
{
// delete all views and re-add them
for( int i = 1; i<m_fxChannelViews.size(); ++i )
{
chLayout->removeWidget(m_fxChannelViews[i]->m_fxLine);
delete m_fxChannelViews[i]->m_fader;
delete m_fxChannelViews[i]->m_muteBtn;
delete m_fxChannelViews[i]->m_fxLine;
delete m_fxChannelViews[i];
}
m_channelAreaWidget->adjustSize();
// re-add the views
m_fxChannelViews.resize(engine::fxMixer()->numChannels());
for( int i = 1; i < m_fxChannelViews.size(); ++i )
{
m_fxChannelViews[i] = new FxChannelView(m_channelAreaWidget, this, i);
chLayout->addWidget(m_fxChannelViews[i]->m_fxLine);
}
// fix master
//TODO
}
void FxMixerView::updateMaxChannelSelector()
{
// update the and max. channel number for every instrument
@@ -190,8 +216,8 @@ void FxMixerView::updateMaxChannelSelector()
if( trackList[i]->type() == track::InstrumentTrack )
{
InstrumentTrack * inst = (InstrumentTrack *) trackList[i];
inst->effectChannelModel()->setMaxValue(
m_fxChannelViews.size()-1);
inst->effectChannelModel()->setRange(0,
m_fxChannelViews.size()-1,1);
}
}
}