Merge https://github.com/LMMS/lmms into stable-0.4
This commit is contained in:
@@ -84,8 +84,6 @@ AutomationPattern::~AutomationPattern()
|
||||
|
||||
void AutomationPattern::addObject( AutomatableModel * _obj, bool _search_dup )
|
||||
{
|
||||
bool addIt = true;
|
||||
|
||||
if( _search_dup )
|
||||
{
|
||||
for( objectVector::iterator it = m_objects.begin();
|
||||
@@ -95,27 +93,26 @@ void AutomationPattern::addObject( AutomatableModel * _obj, bool _search_dup )
|
||||
{
|
||||
// Already exists
|
||||
// TODO: Maybe let the user know in some non-annoying way
|
||||
addIt = false;
|
||||
break;
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if( addIt )
|
||||
// the automation track is unconnected and there is nothing in the track
|
||||
if( m_objects.isEmpty() && hasAutomation() == false )
|
||||
{
|
||||
// been empty before and model's current value is not its init value?
|
||||
if( m_objects.isEmpty() && hasAutomation() == false && _obj->isAtInitValue() == false )
|
||||
{
|
||||
// then initialize first value
|
||||
putValue( 0, _obj->value<float>(), false );
|
||||
}
|
||||
|
||||
m_objects += _obj;
|
||||
|
||||
connect( _obj, SIGNAL( destroyed( jo_id_t ) ),
|
||||
this, SLOT( objectDestroyed( jo_id_t ) ),
|
||||
Qt::DirectConnection );
|
||||
// then initialize first value
|
||||
putValue( MidiTime(0), _obj->value<float>(), false );
|
||||
}
|
||||
|
||||
m_objects += _obj;
|
||||
|
||||
connect( _obj, SIGNAL( destroyed( jo_id_t ) ),
|
||||
this, SLOT( objectDestroyed( jo_id_t ) ),
|
||||
Qt::DirectConnection );
|
||||
|
||||
emit dataChanged();
|
||||
|
||||
}
|
||||
|
||||
|
||||
@@ -158,7 +155,7 @@ const AutomatableModel * AutomationPattern::firstObject() const
|
||||
return m;
|
||||
}
|
||||
|
||||
static FloatModel _fm( 0, 0, 1, 0.001 );
|
||||
static FloatModel _fm( 0, DEFAULT_MIN_VALUE, DEFAULT_MAX_VALUE, 0.001 );
|
||||
return &_fm;
|
||||
}
|
||||
|
||||
@@ -584,18 +581,18 @@ void AutomationPattern::resolveAllIDs()
|
||||
AutomationPattern * a = dynamic_cast<AutomationPattern *>( *j );
|
||||
if( a )
|
||||
{
|
||||
for( QVector<jo_id_t>::Iterator k = a->m_idsToResolve.begin();
|
||||
k != a->m_idsToResolve.end(); ++k )
|
||||
{
|
||||
JournallingObject * o = engine::projectJournal()->
|
||||
journallingObject( *k );
|
||||
if( o && dynamic_cast<AutomatableModel *>( o ) )
|
||||
{
|
||||
a->addObject( dynamic_cast<AutomatableModel *>( o ), false );
|
||||
}
|
||||
}
|
||||
a->m_idsToResolve.clear();
|
||||
a->dataChanged();
|
||||
for( QVector<jo_id_t>::Iterator k = a->m_idsToResolve.begin();
|
||||
k != a->m_idsToResolve.end(); ++k )
|
||||
{
|
||||
JournallingObject * o = engine::projectJournal()->
|
||||
journallingObject( *k );
|
||||
if( o && dynamic_cast<AutomatableModel *>( o ) )
|
||||
{
|
||||
a->addObject( dynamic_cast<AutomatableModel *>( o ), false );
|
||||
}
|
||||
}
|
||||
a->m_idsToResolve.clear();
|
||||
a->dataChanged();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -639,6 +636,20 @@ void AutomationPattern::objectDestroyed( jo_id_t _id )
|
||||
// case we had to remove ourselves if we're the global automation
|
||||
// pattern of the destroyed object
|
||||
m_idsToResolve += _id;
|
||||
|
||||
for( objectVector::Iterator objIt = m_objects.begin();
|
||||
objIt != m_objects.end(); objIt++ )
|
||||
{
|
||||
Q_ASSERT( !(*objIt).isNull() );
|
||||
if( (*objIt)->id() == _id )
|
||||
{
|
||||
//Assign to objIt so that this loop work even break; is removed.
|
||||
objIt = m_objects.erase( objIt );
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
emit dataChanged();
|
||||
}
|
||||
|
||||
|
||||
@@ -703,4 +714,6 @@ void AutomationPattern::generateTangents( timeMap::const_iterator it,
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
#include "moc_AutomationPattern.cxx"
|
||||
|
||||
@@ -177,12 +177,13 @@ Controller * Controller::create( ControllerTypes _ct, Model * _parent )
|
||||
QString() );
|
||||
break;
|
||||
|
||||
case Controller::LfoController:
|
||||
c = new ::LfoController( _parent );
|
||||
case Controller::LfoController:
|
||||
c = new ::LfoController( _parent );
|
||||
break;
|
||||
|
||||
case Controller::PeakController:
|
||||
c = new ::PeakController( _parent );
|
||||
//Already instantiated in EffectChain::loadSettings()
|
||||
Q_ASSERT( false );
|
||||
break;
|
||||
|
||||
case Controller::MidiController:
|
||||
@@ -200,9 +201,18 @@ Controller * Controller::create( ControllerTypes _ct, Model * _parent )
|
||||
|
||||
Controller * Controller::create( const QDomElement & _this, Model * _parent )
|
||||
{
|
||||
Controller * c = create(
|
||||
static_cast<ControllerTypes>( _this.attribute( "type" ).toInt() ),
|
||||
_parent );
|
||||
Controller * c;
|
||||
if( _this.attribute( "type" ).toInt() == Controller::PeakController )
|
||||
{
|
||||
c = PeakController::getControllerBySetting( _this );
|
||||
}
|
||||
else
|
||||
{
|
||||
c = create(
|
||||
static_cast<ControllerTypes>( _this.attribute( "type" ).toInt() ),
|
||||
_parent );
|
||||
}
|
||||
|
||||
if( c != NULL )
|
||||
{
|
||||
c->restoreState( _this );
|
||||
|
||||
@@ -198,6 +198,7 @@ void LfoController::saveSettings( QDomDocument & _doc, QDomElement & _this )
|
||||
m_phaseModel.saveSettings( _doc, _this, "phase" );
|
||||
m_waveModel.saveSettings( _doc, _this, "wave" );
|
||||
m_multiplierModel.saveSettings( _doc, _this, "multiplier" );
|
||||
_this.setAttribute( "userwavefile" , m_userDefSampleBuffer->audioFile() );
|
||||
}
|
||||
|
||||
|
||||
@@ -212,6 +213,7 @@ void LfoController::loadSettings( const QDomElement & _this )
|
||||
m_phaseModel.loadSettings( _this, "phase" );
|
||||
m_waveModel.loadSettings( _this, "wave" );
|
||||
m_multiplierModel.loadSettings( _this, "multiplier" );
|
||||
m_userDefSampleBuffer->setAudioFile( _this.attribute("userwavefile" ) );
|
||||
|
||||
updateSampleFunction();
|
||||
}
|
||||
|
||||
@@ -28,6 +28,7 @@
|
||||
#include <QtXml/QDomElement>
|
||||
#include <QtCore/QObject>
|
||||
#include <QtCore/QVector>
|
||||
#include <QMessageBox>
|
||||
|
||||
|
||||
#include "song.h"
|
||||
@@ -37,8 +38,12 @@
|
||||
#include "EffectChain.h"
|
||||
#include "ControllerDialog.h"
|
||||
#include "plugins/peak_controller_effect/peak_controller_effect.h"
|
||||
#include "PresetPreviewPlayHandle.h"
|
||||
|
||||
PeakControllerEffectVector PeakController::s_effects;
|
||||
int PeakController::m_getCount;
|
||||
int PeakController::m_loadCount;
|
||||
bool PeakController::m_buggedFile;
|
||||
|
||||
|
||||
PeakController::PeakController( Model * _parent,
|
||||
@@ -58,7 +63,11 @@ PeakController::PeakController( Model * _parent,
|
||||
|
||||
PeakController::~PeakController()
|
||||
{
|
||||
if( m_peakEffect != NULL && m_peakEffect->effectChain() != NULL )
|
||||
//EffectChain::loadSettings() appends effect to EffectChain::m_effects
|
||||
//When it's previewing, EffectChain::loadSettings(<Controller Fx XML>) is not called
|
||||
//Therefore, we shouldn't call removeEffect() as it is not even appended.
|
||||
//NB: Most XML setting are loaded on preview, except controller fx.
|
||||
if( m_peakEffect != NULL && m_peakEffect->effectChain() != NULL && PresetPreviewPlayHandle::isPreviewing() == false )
|
||||
{
|
||||
m_peakEffect->effectChain()->removeEffect( m_peakEffect );
|
||||
}
|
||||
@@ -103,7 +112,13 @@ void PeakController::saveSettings( QDomDocument & _doc, QDomElement & _this )
|
||||
|
||||
void PeakController::loadSettings( const QDomElement & _this )
|
||||
{
|
||||
Controller::loadSettings( _this );
|
||||
|
||||
int effectId = _this.attribute( "effectId" ).toInt();
|
||||
if( m_buggedFile == true )
|
||||
{
|
||||
effectId = m_loadCount++;
|
||||
}
|
||||
|
||||
PeakControllerEffectVector::Iterator i;
|
||||
for( i = s_effects.begin(); i != s_effects.end(); ++i )
|
||||
@@ -118,6 +133,76 @@ void PeakController::loadSettings( const QDomElement & _this )
|
||||
|
||||
|
||||
|
||||
|
||||
//Backward compatibility function for bug in <= 0.4.15
|
||||
void PeakController::initGetControllerBySetting()
|
||||
{
|
||||
m_loadCount = 0;
|
||||
m_getCount = 0;
|
||||
m_buggedFile = false;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
PeakController * PeakController::getControllerBySetting(const QDomElement & _this )
|
||||
{
|
||||
int effectId = _this.attribute( "effectId" ).toInt();
|
||||
|
||||
PeakControllerEffectVector::Iterator i;
|
||||
|
||||
//Backward compatibility for bug in <= 0.4.15 . For >= 1.0.0 ,
|
||||
//foundCount should always be 1 because m_effectId is initialized with rand()
|
||||
int foundCount = 0;
|
||||
if( m_buggedFile == false )
|
||||
{
|
||||
for( i = s_effects.begin(); i != s_effects.end(); ++i )
|
||||
{
|
||||
if( (*i)->m_effectId == effectId )
|
||||
{
|
||||
foundCount++;
|
||||
}
|
||||
}
|
||||
if( foundCount >= 2 )
|
||||
{
|
||||
m_buggedFile = true;
|
||||
int newEffectId = 0;
|
||||
for( i = s_effects.begin(); i != s_effects.end(); ++i )
|
||||
{
|
||||
(*i)->m_effectId = newEffectId++;
|
||||
}
|
||||
QMessageBox msgBox;
|
||||
msgBox.setIcon( QMessageBox::Information );
|
||||
msgBox.setWindowTitle( tr("Peak Controller Bug") );
|
||||
msgBox.setText( tr("Due to a bug in older version of LMMS, the peak "
|
||||
"controllers may not be connect properly. "
|
||||
"Please ensure that peak controllers are connected "
|
||||
"properly and re-save this file. "
|
||||
"Sorry for any inconvenience caused.") );
|
||||
msgBox.setStandardButtons(QMessageBox::Ok);
|
||||
msgBox.exec();
|
||||
}
|
||||
}
|
||||
|
||||
if( m_buggedFile == true )
|
||||
{
|
||||
effectId = m_getCount;
|
||||
}
|
||||
m_getCount++; //NB: m_getCount should be increased even m_buggedFile is false
|
||||
|
||||
for( i = s_effects.begin(); i != s_effects.end(); ++i )
|
||||
{
|
||||
if( (*i)->m_effectId == effectId )
|
||||
{
|
||||
return (*i)->controller();
|
||||
}
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
||||
|
||||
QString PeakController::nodeName() const
|
||||
{
|
||||
return( "Peakcontroller" );
|
||||
|
||||
@@ -88,8 +88,8 @@ public:
|
||||
|
||||
bool isPreviewing()
|
||||
{
|
||||
bool ret = m_dataMutex.tryLock();
|
||||
if( ret == true )
|
||||
bool ret = !m_dataMutex.tryLock();
|
||||
if( ret == false )
|
||||
{
|
||||
m_dataMutex.unlock();
|
||||
}
|
||||
|
||||
@@ -908,6 +908,27 @@ QString SampleBuffer::openAndSetAudioFile()
|
||||
}
|
||||
|
||||
|
||||
QString SampleBuffer::openAndSetWaveformFile()
|
||||
{
|
||||
if( m_audioFile.isEmpty() )
|
||||
{
|
||||
m_audioFile = configManager::inst()->factorySamplesDir() + "waveforms/10saw.flac";
|
||||
}
|
||||
|
||||
QString fileName = this->openAudioFile();
|
||||
|
||||
if(!fileName.isEmpty())
|
||||
{
|
||||
this->setAudioFile( fileName );
|
||||
}
|
||||
else
|
||||
{
|
||||
m_audioFile = "";
|
||||
}
|
||||
|
||||
return fileName;
|
||||
}
|
||||
|
||||
|
||||
|
||||
#undef LMMS_HAVE_FLAC_STREAM_ENCODER_H /* not yet... */
|
||||
|
||||
@@ -61,6 +61,7 @@
|
||||
#include "templates.h"
|
||||
#include "text_float.h"
|
||||
#include "timeline.h"
|
||||
#include "PeakController.h"
|
||||
|
||||
#ifdef LMMS_BUILD_WIN32
|
||||
#ifndef USE_QT_SHMEM
|
||||
@@ -1141,6 +1142,10 @@ void song::loadProject( const QString & _file_name )
|
||||
m_globalAutomationTrack->restoreState( mmp.content().
|
||||
firstChildElement( "track" ) );
|
||||
}
|
||||
|
||||
//Backward compatibility for LMMS <= 0.4.15
|
||||
PeakController::initGetControllerBySetting();
|
||||
|
||||
QDomNode node = mmp.content().firstChild();
|
||||
while( !node.isNull() )
|
||||
{
|
||||
@@ -1354,7 +1359,16 @@ void song::restoreControllerStates( const QDomElement & _this )
|
||||
QDomNode node = _this.firstChild();
|
||||
while( !node.isNull() )
|
||||
{
|
||||
addController( Controller::create( node.toElement(), this ) );
|
||||
Controller * c = Controller::create( node.toElement(), this );
|
||||
Q_ASSERT( c != NULL );
|
||||
|
||||
/* For PeakController, addController() was called in
|
||||
* PeakControllerEffect::PeakControllerEffect().
|
||||
* This line removes the previously added controller for PeakController
|
||||
* without affecting the order of controllers in Controller Rack
|
||||
*/
|
||||
engine::getSong()->removeController( c );
|
||||
addController( c );
|
||||
|
||||
node = node.nextSibling();
|
||||
}
|
||||
|
||||
@@ -283,14 +283,14 @@ void timeLine::mousePressEvent( QMouseEvent* event )
|
||||
m_moveXOff = s_posMarkerPixmap->width() / 2;
|
||||
}
|
||||
}
|
||||
else if( event->button() == Qt::RightButton )
|
||||
else if( event->button() == Qt::RightButton || event->button() == Qt::MiddleButton )
|
||||
{
|
||||
const MidiTime t = m_begin + static_cast<int>( event->x() * MidiTime::ticksPerTact() / m_ppt );
|
||||
if( m_loopPos[0] > m_loopPos[1] )
|
||||
{
|
||||
qSwap( m_loopPos[0], m_loopPos[1] );
|
||||
}
|
||||
if( event->modifiers() & Qt::ShiftModifier )
|
||||
if( ( event->modifiers() & Qt::ShiftModifier ) || event->button() == Qt::MiddleButton )
|
||||
{
|
||||
m_action = MoveLoopBegin;
|
||||
}
|
||||
|
||||
@@ -72,6 +72,10 @@ QPixmap * AutomationEditor::s_toolSelect = NULL;
|
||||
QPixmap * AutomationEditor::s_toolMove = NULL;
|
||||
|
||||
|
||||
const QColor DRAGGABLE_PIN_COLOR = QColor( 0xFF, 0x00, 0x00 );
|
||||
const QColor DRAGGABLE_PIN_BORDER_COLOR = QColor( 0xFF, 0xFF, 0xFF );
|
||||
|
||||
|
||||
AutomationEditor::AutomationEditor() :
|
||||
QWidget(),
|
||||
m_zoomingXModel(),
|
||||
@@ -1348,6 +1352,22 @@ inline void AutomationEditor::drawCross( QPainter & _p )
|
||||
|
||||
|
||||
|
||||
inline void AutomationEditor::drawAutomationPoint( QPainter & p, timeMap::iterator it )
|
||||
{
|
||||
int x = xCoordOfTick( it.key() );
|
||||
int y = yCoordOfLevel( it.value() );
|
||||
int outerRadius = qMin( 8, m_ppt/quantization() );
|
||||
int innerRadius = qMax( 0, outerRadius-2 );
|
||||
p.setBrush( QBrush( DRAGGABLE_PIN_BORDER_COLOR ) );
|
||||
p.drawEllipse( x-outerRadius/2, y-outerRadius/2, outerRadius, outerRadius );
|
||||
p.setBrush( QBrush( DRAGGABLE_PIN_COLOR ) );
|
||||
p.drawEllipse( x-innerRadius/2, y-innerRadius/2, innerRadius, innerRadius );
|
||||
p.setBrush( QBrush() );
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
void AutomationEditor::paintEvent( QPaintEvent * _pe )
|
||||
{
|
||||
QMutexLocker m( &m_patternMutex );
|
||||
@@ -1526,71 +1546,75 @@ void AutomationEditor::paintEvent( QPaintEvent * _pe )
|
||||
{
|
||||
int len_ticks = 4;
|
||||
timeMap & time_map = m_pattern->getTimeMap();
|
||||
timeMap::iterator it = time_map.begin();
|
||||
p.setPen( QColor( 0xCF, 0xD9, 0xFF ) );
|
||||
|
||||
while( it+1 != time_map.end() )
|
||||
//Don't bother doing/rendering anything if there is no automation points
|
||||
if( time_map.size() > 0 )
|
||||
{
|
||||
// skip this section if it occurs completely before the
|
||||
// visible area
|
||||
int next_x = xCoordOfTick( (it+1).key() );
|
||||
if( next_x < 0 )
|
||||
timeMap::iterator it = time_map.begin();
|
||||
p.setPen( QColor( 0xCF, 0xD9, 0xFF ) );
|
||||
while( it+1 != time_map.end() )
|
||||
{
|
||||
++it;
|
||||
continue;
|
||||
}
|
||||
// skip this section if it occurs completely before the
|
||||
// visible area
|
||||
int next_x = xCoordOfTick( (it+1).key() );
|
||||
if( next_x < 0 )
|
||||
{
|
||||
++it;
|
||||
continue;
|
||||
}
|
||||
|
||||
int x = xCoordOfTick( it.key() );
|
||||
if( x > width() )
|
||||
{
|
||||
break;
|
||||
}
|
||||
int x = xCoordOfTick( it.key() );
|
||||
if( x > width() )
|
||||
{
|
||||
break;
|
||||
}
|
||||
|
||||
bool is_selected = FALSE;
|
||||
// if we're in move-mode, we may only draw
|
||||
// values in selected area, that have originally
|
||||
// been selected and not values that are now in
|
||||
// selection because the user moved it...
|
||||
if( m_editMode == MOVE )
|
||||
{
|
||||
if( m_selValuesForMove.contains( it.key() ) )
|
||||
bool is_selected = FALSE;
|
||||
// if we're in move-mode, we may only draw
|
||||
// values in selected area, that have originally
|
||||
// been selected and not values that are now in
|
||||
// selection because the user moved it...
|
||||
if( m_editMode == MOVE )
|
||||
{
|
||||
if( m_selValuesForMove.contains( it.key() ) )
|
||||
{
|
||||
is_selected = TRUE;
|
||||
}
|
||||
}
|
||||
else if( it.value() >= selLevel_start &&
|
||||
it.value() <= selLevel_end &&
|
||||
it.key() >= sel_pos_start &&
|
||||
it.key() + len_ticks <= sel_pos_end )
|
||||
{
|
||||
is_selected = TRUE;
|
||||
}
|
||||
|
||||
float *values = m_pattern->valuesAfter( it.key() );
|
||||
for( int i = 0; i < (it+1).key() - it.key(); i++ )
|
||||
{
|
||||
drawLevelTick( p, it.key() + i, values[i],
|
||||
is_selected );
|
||||
}
|
||||
delete [] values;
|
||||
|
||||
// Draw circle
|
||||
drawAutomationPoint(p, it);
|
||||
|
||||
++it;
|
||||
}
|
||||
else if( it.value() >= selLevel_start &&
|
||||
it.value() <= selLevel_end &&
|
||||
it.key() >= sel_pos_start &&
|
||||
it.key() + len_ticks <= sel_pos_end )
|
||||
|
||||
Q_ASSERT( it == time_map.end()-1 );
|
||||
|
||||
for( int i = it.key(), x = xCoordOfTick( i ); x <= width();
|
||||
i++, x = xCoordOfTick( i ) )
|
||||
{
|
||||
is_selected = TRUE;
|
||||
// TODO: Find out if the section after the last control
|
||||
// point is able to be selected and if so set this
|
||||
// boolean correctly
|
||||
drawLevelTick( p, i, it.value(), false );
|
||||
}
|
||||
|
||||
float *values = m_pattern->valuesAfter( it.key() );
|
||||
for( int i = 0; i < (it+1).key() - it.key(); i++ )
|
||||
{
|
||||
drawLevelTick( p, it.key() + i, values[i],
|
||||
is_selected );
|
||||
}
|
||||
delete [] values;
|
||||
|
||||
// Draw cross
|
||||
int y = yCoordOfLevel( it.value() );
|
||||
p.drawLine( x - 1, y, x + 1, y );
|
||||
p.drawLine( x, y - 1, x, y + 1 );
|
||||
// _p.setPen( QColor( 0xFF, 0x9F, 0x00 ) );
|
||||
// _p.setPen( QColor( 0xFF, 0xFF, 0x40 ) );
|
||||
|
||||
++it;
|
||||
}
|
||||
|
||||
for( int i = it.key(), x = xCoordOfTick( i ); x <= width();
|
||||
i++, x = xCoordOfTick( i ) )
|
||||
{
|
||||
// TODO: Find out if the section after the last control
|
||||
// point is able to be selected and if so set this
|
||||
// boolean correctly
|
||||
drawLevelTick( p, i, it.value(), false );
|
||||
// Draw circle(the last one)
|
||||
drawAutomationPoint(p, it);
|
||||
}
|
||||
}
|
||||
else
|
||||
|
||||
@@ -107,10 +107,26 @@ void AutomationPatternView::disconnectObject( QAction * _a )
|
||||
journallingObject( _a->data().toInt() );
|
||||
if( j && dynamic_cast<AutomatableModel *>( j ) )
|
||||
{
|
||||
float oldMin = m_pat->getMin();
|
||||
float oldMax = m_pat->getMax();
|
||||
|
||||
m_pat->m_objects.erase( qFind( m_pat->m_objects.begin(),
|
||||
m_pat->m_objects.end(),
|
||||
dynamic_cast<AutomatableModel *>( j ) ) );
|
||||
update();
|
||||
|
||||
//If automation editor is opened, update its display after disconnection
|
||||
if( engine::automationEditor() )
|
||||
{
|
||||
engine::automationEditor()->updateAfterPatternChange();
|
||||
}
|
||||
|
||||
//if there is no more connection connected to the AutomationPattern
|
||||
if( m_pat->m_objects.size() == 0 )
|
||||
{
|
||||
//scale the points to fit the new min. and max. value
|
||||
this->scaleTimemapToFit( oldMin, oldMax );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -333,6 +349,14 @@ void AutomationPatternView::dropEvent( QDropEvent * _de )
|
||||
{
|
||||
engine::automationEditor()->setCurrentPattern( m_pat );
|
||||
}
|
||||
|
||||
//This is the only model that's just added to AutomationPattern.
|
||||
if( m_pat->m_objects.size() == 1 )
|
||||
{
|
||||
//scale the points to fit the new min. and max. value
|
||||
this->scaleTimemapToFit( AutomationPattern::DEFAULT_MIN_VALUE,
|
||||
AutomationPattern::DEFAULT_MAX_VALUE );
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -343,5 +367,37 @@ void AutomationPatternView::dropEvent( QDropEvent * _de )
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* @brief Preserves the auto points over different scale
|
||||
*/
|
||||
void AutomationPatternView::scaleTimemapToFit( float oldMin, float oldMax )
|
||||
{
|
||||
float newMin = m_pat->getMin();
|
||||
float newMax = m_pat->getMax();
|
||||
|
||||
if( oldMin == newMin && oldMax == newMax )
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
for( AutomationPattern::timeMap::iterator it = m_pat->m_timeMap.begin();
|
||||
it != m_pat->m_timeMap.end(); ++it )
|
||||
{
|
||||
if( *it < oldMin )
|
||||
{
|
||||
*it = oldMin;
|
||||
}
|
||||
else if( *it > oldMax )
|
||||
{
|
||||
*it = oldMax;
|
||||
}
|
||||
*it = (*it-oldMin)*(newMax-newMin)/(oldMax-oldMin)+newMin;
|
||||
}
|
||||
|
||||
m_pat->generateTangents();
|
||||
}
|
||||
|
||||
|
||||
|
||||
#include "moc_AutomationPatternView.cxx"
|
||||
|
||||
|
||||
@@ -252,7 +252,7 @@ void LfoControllerDialog::askUserDefWave()
|
||||
{
|
||||
SampleBuffer * sampleBuffer = dynamic_cast<LfoController*>(this->model())->
|
||||
m_userDefSampleBuffer;
|
||||
QString fileName = sampleBuffer->openAndSetAudioFile();
|
||||
QString fileName = sampleBuffer->openAndSetWaveformFile();
|
||||
if( fileName.isEmpty() == false )
|
||||
{
|
||||
// TODO:
|
||||
|
||||
@@ -68,12 +68,12 @@ bbEditor::bbEditor( bbTrackContainer* tc ) :
|
||||
"compacttrackbuttons" ).toInt() )
|
||||
{
|
||||
setMinimumWidth( TRACK_OP_WIDTH_COMPACT + DEFAULT_SETTINGS_WIDGET_WIDTH_COMPACT
|
||||
+ 2 * TCO_BORDER_WIDTH + 192 );
|
||||
+ 2 * TCO_BORDER_WIDTH + 264 );
|
||||
}
|
||||
else
|
||||
{
|
||||
setMinimumWidth( TRACK_OP_WIDTH + DEFAULT_SETTINGS_WIDGET_WIDTH
|
||||
+ 2 * TCO_BORDER_WIDTH + 192 );
|
||||
+ 2 * TCO_BORDER_WIDTH + 264 );
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -485,7 +485,7 @@ void graphModel::setWaveToNoise()
|
||||
QString graphModel::setWaveToUser()
|
||||
{
|
||||
SampleBuffer * sampleBuffer = new SampleBuffer;
|
||||
QString fileName = sampleBuffer->openAndSetAudioFile();
|
||||
QString fileName = sampleBuffer->openAndSetWaveformFile();
|
||||
if( fileName.isEmpty() == false )
|
||||
{
|
||||
for( int i = 0; i < length(); i++ )
|
||||
|
||||
@@ -1332,6 +1332,7 @@ void InstrumentTrackWindow::modelChanged()
|
||||
{
|
||||
m_pitchKnob->hide();
|
||||
m_pitchKnob->setModel( NULL );
|
||||
m_pitchRangeSpinBox->hide();
|
||||
}
|
||||
|
||||
m_ssView->setModel( &m_track->m_soundShaping );
|
||||
|
||||
Reference in New Issue
Block a user