Merge branch 'master'
This commit is contained in:
@@ -30,7 +30,7 @@
|
||||
|
||||
#include "AudioEngineWorkerThread.h"
|
||||
#include "AudioPort.h"
|
||||
#include "FxMixer.h"
|
||||
#include "Mixer.h"
|
||||
#include "Song.h"
|
||||
#include "EnvelopeAndLfoParameters.h"
|
||||
#include "NotePlayHandle.h"
|
||||
@@ -109,15 +109,14 @@ AudioEngine::AudioEngine( bool renderOnly ) :
|
||||
if( renderOnly == false )
|
||||
{
|
||||
m_framesPerPeriod =
|
||||
( fpp_t ) ConfigManager::inst()->
|
||||
value( "mixer", "framesperaudiobuffer" ).toInt();
|
||||
( fpp_t ) ConfigManager::inst()->value( "audioengine", "framesperaudiobuffer" ).toInt();
|
||||
|
||||
// if the value read from user configuration is not set or
|
||||
// lower than the minimum allowed, use the default value and
|
||||
// save it to the configuration
|
||||
if( m_framesPerPeriod < MINIMUM_BUFFER_SIZE )
|
||||
{
|
||||
ConfigManager::inst()->setValue( "mixer",
|
||||
ConfigManager::inst()->setValue( "audioengine",
|
||||
"framesperaudiobuffer",
|
||||
QString::number( DEFAULT_BUFFER_SIZE ) );
|
||||
|
||||
@@ -256,8 +255,7 @@ void AudioEngine::stopProcessing()
|
||||
|
||||
sample_rate_t AudioEngine::baseSampleRate() const
|
||||
{
|
||||
sample_rate_t sr =
|
||||
ConfigManager::inst()->value( "mixer", "samplerate" ).toInt();
|
||||
sample_rate_t sr = ConfigManager::inst()->value( "audioengine", "samplerate" ).toInt();
|
||||
if( sr < 44100 )
|
||||
{
|
||||
sr = 44100;
|
||||
@@ -369,8 +367,8 @@ const surroundSampleFrame * AudioEngine::renderNextBuffer()
|
||||
swapBuffers();
|
||||
|
||||
// prepare master mix (clear internal buffers etc.)
|
||||
FxMixer * fxMixer = Engine::fxMixer();
|
||||
fxMixer->prepareMasterMix();
|
||||
Mixer * mixer = Engine::mixer();
|
||||
mixer->prepareMasterMix();
|
||||
|
||||
handleMetronome();
|
||||
|
||||
@@ -421,8 +419,8 @@ const surroundSampleFrame * AudioEngine::renderNextBuffer()
|
||||
AudioEngineWorkerThread::startAndWaitForJobs();
|
||||
|
||||
|
||||
// STAGE 3: do master mix in FX mixer
|
||||
fxMixer->masterMix(m_outputBufferWrite);
|
||||
// STAGE 3: do master mix in mixer
|
||||
mixer->masterMix(m_outputBufferWrite);
|
||||
|
||||
|
||||
emit nextAudioBuffer(m_outputBufferRead);
|
||||
@@ -465,7 +463,7 @@ void AudioEngine::handleMetronome()
|
||||
Song::PlayModes currentPlayMode = song->playMode();
|
||||
|
||||
bool metronomeSupported =
|
||||
currentPlayMode == Song::Mode_PlayPattern
|
||||
currentPlayMode == Song::Mode_PlayMidiClip
|
||||
|| currentPlayMode == Song::Mode_PlaySong
|
||||
|| currentPlayMode == Song::Mode_PlayBB;
|
||||
|
||||
@@ -956,7 +954,7 @@ AudioDevice * AudioEngine::tryAudioDevices()
|
||||
{
|
||||
bool success_ful = false;
|
||||
AudioDevice * dev = nullptr;
|
||||
QString dev_name = ConfigManager::inst()->value( "mixer", "audiodev" );
|
||||
QString dev_name = ConfigManager::inst()->value( "audioengine", "audiodev" );
|
||||
if( !isAudioDevNameValid( dev_name ) )
|
||||
{
|
||||
dev_name = "";
|
||||
@@ -1102,8 +1100,7 @@ AudioDevice * AudioEngine::tryAudioDevices()
|
||||
|
||||
MidiClient * AudioEngine::tryMidiClients()
|
||||
{
|
||||
QString client_name = ConfigManager::inst()->value( "mixer",
|
||||
"mididev" );
|
||||
QString client_name = ConfigManager::inst()->value( "audioengine", "mididev" );
|
||||
if( !isMidiDevNameValid( client_name ) )
|
||||
{
|
||||
client_name = "";
|
||||
|
||||
@@ -27,7 +27,7 @@
|
||||
#include "lmms_math.h"
|
||||
|
||||
#include "AudioEngine.h"
|
||||
#include "AutomationPattern.h"
|
||||
#include "AutomationClip.h"
|
||||
#include "ControllerConnection.h"
|
||||
#include "LocaleHelper.h"
|
||||
#include "ProjectJournal.h"
|
||||
@@ -87,7 +87,7 @@ AutomatableModel::~AutomatableModel()
|
||||
|
||||
bool AutomatableModel::isAutomated() const
|
||||
{
|
||||
return AutomationPattern::isAutomated( this );
|
||||
return AutomationClip::isAutomated( this );
|
||||
}
|
||||
|
||||
|
||||
@@ -176,13 +176,13 @@ void AutomatableModel::saveSettings( QDomDocument& doc, QDomElement& element, co
|
||||
void AutomatableModel::loadSettings( const QDomElement& element, const QString& name )
|
||||
{
|
||||
// compat code
|
||||
QDomNode node = element.namedItem( AutomationPattern::classNodeName() );
|
||||
QDomNode node = element.namedItem( AutomationClip::classNodeName() );
|
||||
if( node.isElement() )
|
||||
{
|
||||
node = node.namedItem( name );
|
||||
if( node.isElement() )
|
||||
{
|
||||
AutomationPattern * p = AutomationPattern::globalAutomationPattern( this );
|
||||
AutomationClip * p = AutomationClip::globalAutomationClip( this );
|
||||
p->loadSettings( node.toElement() );
|
||||
setValue( p->valueAt( 0 ) );
|
||||
// in older projects we sometimes have odd automations
|
||||
@@ -718,57 +718,57 @@ void AutomatableModel::reset()
|
||||
|
||||
float AutomatableModel::globalAutomationValueAt( const TimePos& time )
|
||||
{
|
||||
// get patterns that connect to this model
|
||||
QVector<AutomationPattern *> patterns = AutomationPattern::patternsForModel( this );
|
||||
if( patterns.isEmpty() )
|
||||
// get clips that connect to this model
|
||||
QVector<AutomationClip *> clips = AutomationClip::clipsForModel( this );
|
||||
if( clips.isEmpty() )
|
||||
{
|
||||
// if no such patterns exist, return current value
|
||||
// if no such clips exist, return current value
|
||||
return m_value;
|
||||
}
|
||||
else
|
||||
{
|
||||
// of those patterns:
|
||||
// find the patterns which overlap with the time position
|
||||
QVector<AutomationPattern *> patternsInRange;
|
||||
for( QVector<AutomationPattern *>::ConstIterator it = patterns.begin(); it != patterns.end(); it++ )
|
||||
// of those clips:
|
||||
// find the clips which overlap with the time position
|
||||
QVector<AutomationClip *> clipsInRange;
|
||||
for( QVector<AutomationClip *>::ConstIterator it = clips.begin(); it != clips.end(); it++ )
|
||||
{
|
||||
int s = ( *it )->startPosition();
|
||||
int e = ( *it )->endPosition();
|
||||
if( s <= time && e >= time ) { patternsInRange += ( *it ); }
|
||||
if( s <= time && e >= time ) { clipsInRange += ( *it ); }
|
||||
}
|
||||
|
||||
AutomationPattern * latestPattern = nullptr;
|
||||
AutomationClip * latestClip = nullptr;
|
||||
|
||||
if( ! patternsInRange.isEmpty() )
|
||||
if( ! clipsInRange.isEmpty() )
|
||||
{
|
||||
// if there are more than one overlapping patterns, just use the first one because
|
||||
// multiple pattern behaviour is undefined anyway
|
||||
latestPattern = patternsInRange[0];
|
||||
// if there are more than one overlapping clips, just use the first one because
|
||||
// multiple clip behaviour is undefined anyway
|
||||
latestClip = clipsInRange[0];
|
||||
}
|
||||
else
|
||||
// if we find no patterns at the exact time, we need to search for the last pattern before time and use that
|
||||
// if we find no clips at the exact time, we need to search for the last clip before time and use that
|
||||
{
|
||||
int latestPosition = 0;
|
||||
|
||||
for( QVector<AutomationPattern *>::ConstIterator it = patterns.begin(); it != patterns.end(); it++ )
|
||||
for( QVector<AutomationClip *>::ConstIterator it = clips.begin(); it != clips.end(); it++ )
|
||||
{
|
||||
int e = ( *it )->endPosition();
|
||||
if( e <= time && e > latestPosition )
|
||||
{
|
||||
latestPosition = e;
|
||||
latestPattern = ( *it );
|
||||
latestClip = ( *it );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if( latestPattern )
|
||||
if( latestClip )
|
||||
{
|
||||
// scale/fit the value appropriately and return it
|
||||
const float value = latestPattern->valueAt( time - latestPattern->startPosition() );
|
||||
const float value = latestClip->valueAt( time - latestClip->startPosition() );
|
||||
const float scaled_value = scaledValue( value );
|
||||
return fittedValue( scaled_value );
|
||||
}
|
||||
// if we still find no pattern, the value at that time is undefined so
|
||||
// if we still find no clip, the value at that time is undefined so
|
||||
// just return current value as the best we can do
|
||||
else return m_value;
|
||||
}
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* AutomationPattern.cpp - implementation of class AutomationPattern which
|
||||
* AutomationClip.cpp - implementation of class AutomationClip which
|
||||
* holds dynamic values
|
||||
*
|
||||
* Copyright (c) 2008-2014 Tobias Doerffel <tobydox/at/users.sourceforge.net>
|
||||
@@ -24,10 +24,10 @@
|
||||
*
|
||||
*/
|
||||
|
||||
#include "AutomationPattern.h"
|
||||
#include "AutomationClip.h"
|
||||
|
||||
#include "AutomationNode.h"
|
||||
#include "AutomationPatternView.h"
|
||||
#include "AutomationClipView.h"
|
||||
#include "AutomationTrack.h"
|
||||
#include "BBTrackContainer.h"
|
||||
#include "LocaleHelper.h"
|
||||
@@ -36,14 +36,14 @@
|
||||
|
||||
#include <cmath>
|
||||
|
||||
int AutomationPattern::s_quantization = 1;
|
||||
const float AutomationPattern::DEFAULT_MIN_VALUE = 0;
|
||||
const float AutomationPattern::DEFAULT_MAX_VALUE = 1;
|
||||
int AutomationClip::s_quantization = 1;
|
||||
const float AutomationClip::DEFAULT_MIN_VALUE = 0;
|
||||
const float AutomationClip::DEFAULT_MAX_VALUE = 1;
|
||||
|
||||
|
||||
AutomationPattern::AutomationPattern( AutomationTrack * _auto_track ) :
|
||||
TrackContentObject( _auto_track ),
|
||||
m_patternMutex(QMutex::Recursive),
|
||||
AutomationClip::AutomationClip( AutomationTrack * _auto_track ) :
|
||||
Clip( _auto_track ),
|
||||
m_clipMutex(QMutex::Recursive),
|
||||
m_autoTrack( _auto_track ),
|
||||
m_objects(),
|
||||
m_tension( 1.0 ),
|
||||
@@ -73,25 +73,25 @@ AutomationPattern::AutomationPattern( AutomationTrack * _auto_track ) :
|
||||
|
||||
|
||||
|
||||
AutomationPattern::AutomationPattern( const AutomationPattern & _pat_to_copy ) :
|
||||
TrackContentObject( _pat_to_copy.m_autoTrack ),
|
||||
m_patternMutex(QMutex::Recursive),
|
||||
m_autoTrack( _pat_to_copy.m_autoTrack ),
|
||||
m_objects( _pat_to_copy.m_objects ),
|
||||
m_tension( _pat_to_copy.m_tension ),
|
||||
m_progressionType( _pat_to_copy.m_progressionType )
|
||||
AutomationClip::AutomationClip( const AutomationClip & _clip_to_copy ) :
|
||||
Clip( _clip_to_copy.m_autoTrack ),
|
||||
m_clipMutex(QMutex::Recursive),
|
||||
m_autoTrack( _clip_to_copy.m_autoTrack ),
|
||||
m_objects( _clip_to_copy.m_objects ),
|
||||
m_tension( _clip_to_copy.m_tension ),
|
||||
m_progressionType( _clip_to_copy.m_progressionType )
|
||||
{
|
||||
// Locks the mutex of the copied AutomationPattern to make sure it
|
||||
// Locks the mutex of the copied AutomationClip to make sure it
|
||||
// doesn't change while it's being copied
|
||||
QMutexLocker m(&_pat_to_copy.m_patternMutex);
|
||||
QMutexLocker m(&_clip_to_copy.m_clipMutex);
|
||||
|
||||
for( timeMap::const_iterator it = _pat_to_copy.m_timeMap.begin();
|
||||
it != _pat_to_copy.m_timeMap.end(); ++it )
|
||||
for( timeMap::const_iterator it = _clip_to_copy.m_timeMap.begin();
|
||||
it != _clip_to_copy.m_timeMap.end(); ++it )
|
||||
{
|
||||
// Copies the automation node (in/out values and in/out tangents)
|
||||
m_timeMap[POS(it)] = it.value();
|
||||
// Sets the node's pattern to this one
|
||||
m_timeMap[POS(it)].setPattern(this);
|
||||
// Sets the node's clip to this one
|
||||
m_timeMap[POS(it)].setClip(this);
|
||||
}
|
||||
if (!getTrack()){ return; }
|
||||
switch( getTrack()->trackContainer()->type() )
|
||||
@@ -108,9 +108,9 @@ AutomationPattern::AutomationPattern( const AutomationPattern & _pat_to_copy ) :
|
||||
}
|
||||
}
|
||||
|
||||
bool AutomationPattern::addObject( AutomatableModel * _obj, bool _search_dup )
|
||||
bool AutomationClip::addObject( AutomatableModel * _obj, bool _search_dup )
|
||||
{
|
||||
QMutexLocker m(&m_patternMutex);
|
||||
QMutexLocker m(&m_clipMutex);
|
||||
|
||||
if( _search_dup && m_objects.contains(_obj) )
|
||||
{
|
||||
@@ -138,10 +138,10 @@ bool AutomationPattern::addObject( AutomatableModel * _obj, bool _search_dup )
|
||||
|
||||
|
||||
|
||||
void AutomationPattern::setProgressionType(
|
||||
void AutomationClip::setProgressionType(
|
||||
ProgressionTypes _new_progression_type )
|
||||
{
|
||||
QMutexLocker m(&m_patternMutex);
|
||||
QMutexLocker m(&m_clipMutex);
|
||||
|
||||
if ( _new_progression_type == DiscreteProgression ||
|
||||
_new_progression_type == LinearProgression ||
|
||||
@@ -155,9 +155,9 @@ void AutomationPattern::setProgressionType(
|
||||
|
||||
|
||||
|
||||
void AutomationPattern::setTension( QString _new_tension )
|
||||
void AutomationClip::setTension( QString _new_tension )
|
||||
{
|
||||
QMutexLocker m(&m_patternMutex);
|
||||
QMutexLocker m(&m_clipMutex);
|
||||
|
||||
bool ok;
|
||||
float nt = LocaleHelper::toFloat(_new_tension, & ok);
|
||||
@@ -171,9 +171,9 @@ void AutomationPattern::setTension( QString _new_tension )
|
||||
|
||||
|
||||
|
||||
const AutomatableModel * AutomationPattern::firstObject() const
|
||||
const AutomatableModel * AutomationClip::firstObject() const
|
||||
{
|
||||
QMutexLocker m(&m_patternMutex);
|
||||
QMutexLocker m(&m_clipMutex);
|
||||
|
||||
AutomatableModel* model;
|
||||
if (!m_objects.isEmpty() && (model = m_objects.first()) != nullptr)
|
||||
@@ -185,9 +185,9 @@ const AutomatableModel * AutomationPattern::firstObject() const
|
||||
return &fm;
|
||||
}
|
||||
|
||||
const AutomationPattern::objectVector& AutomationPattern::objects() const
|
||||
const AutomationClip::objectVector& AutomationClip::objects() const
|
||||
{
|
||||
QMutexLocker m(&m_patternMutex);
|
||||
QMutexLocker m(&m_clipMutex);
|
||||
|
||||
return m_objects;
|
||||
}
|
||||
@@ -195,9 +195,9 @@ const AutomationPattern::objectVector& AutomationPattern::objects() const
|
||||
|
||||
|
||||
|
||||
TimePos AutomationPattern::timeMapLength() const
|
||||
TimePos AutomationClip::timeMapLength() const
|
||||
{
|
||||
QMutexLocker m(&m_patternMutex);
|
||||
QMutexLocker m(&m_clipMutex);
|
||||
|
||||
TimePos one_bar = TimePos(1, 0);
|
||||
if (m_timeMap.isEmpty()) { return one_bar; }
|
||||
@@ -205,7 +205,7 @@ TimePos AutomationPattern::timeMapLength() const
|
||||
timeMap::const_iterator it = m_timeMap.end();
|
||||
tick_t last_tick = static_cast<tick_t>(POS(it - 1));
|
||||
// if last_tick is 0 (single item at tick 0)
|
||||
// return length as a whole bar to prevent disappearing TCO
|
||||
// return length as a whole bar to prevent disappearing Clip
|
||||
if (last_tick == 0) { return one_bar; }
|
||||
|
||||
return TimePos(last_tick);
|
||||
@@ -214,7 +214,7 @@ TimePos AutomationPattern::timeMapLength() const
|
||||
|
||||
|
||||
|
||||
void AutomationPattern::updateLength()
|
||||
void AutomationClip::updateLength()
|
||||
{
|
||||
// Do not resize down in case user manually extended up
|
||||
changeLength(qMax(length(), timeMapLength()));
|
||||
@@ -232,14 +232,14 @@ void AutomationPattern::updateLength()
|
||||
* @param Boolean True to ignore unquantized surrounding nodes (defaults to true)
|
||||
* @return TimePos of the recently added automation node
|
||||
*/
|
||||
TimePos AutomationPattern::putValue(
|
||||
TimePos AutomationClip::putValue(
|
||||
const TimePos & time,
|
||||
const float value,
|
||||
const bool quantPos,
|
||||
const bool ignoreSurroundingPoints
|
||||
)
|
||||
{
|
||||
QMutexLocker m(&m_patternMutex);
|
||||
QMutexLocker m(&m_clipMutex);
|
||||
|
||||
cleanObjects();
|
||||
|
||||
@@ -286,7 +286,7 @@ TimePos AutomationPattern::putValue(
|
||||
* @param Boolean True to ignore unquantized surrounding nodes (defaults to true)
|
||||
* @return TimePos of the recently added automation node
|
||||
*/
|
||||
TimePos AutomationPattern::putValues(
|
||||
TimePos AutomationClip::putValues(
|
||||
const TimePos & time,
|
||||
const float inValue,
|
||||
const float outValue,
|
||||
@@ -294,7 +294,7 @@ TimePos AutomationPattern::putValues(
|
||||
const bool ignoreSurroundingPoints
|
||||
)
|
||||
{
|
||||
QMutexLocker m(&m_patternMutex);
|
||||
QMutexLocker m(&m_clipMutex);
|
||||
|
||||
cleanObjects();
|
||||
|
||||
@@ -331,9 +331,9 @@ TimePos AutomationPattern::putValues(
|
||||
|
||||
|
||||
|
||||
void AutomationPattern::removeNode(const TimePos & time)
|
||||
void AutomationClip::removeNode(const TimePos & time)
|
||||
{
|
||||
QMutexLocker m(&m_patternMutex);
|
||||
QMutexLocker m(&m_clipMutex);
|
||||
|
||||
cleanObjects();
|
||||
|
||||
@@ -358,7 +358,7 @@ void AutomationPattern::removeNode(const TimePos & time)
|
||||
* @param Int first tick of the range
|
||||
* @param Int second tick of the range
|
||||
*/
|
||||
void AutomationPattern::removeNodes(const int tick0, const int tick1)
|
||||
void AutomationClip::removeNodes(const int tick0, const int tick1)
|
||||
{
|
||||
if (tick0 == tick1)
|
||||
{
|
||||
@@ -393,7 +393,7 @@ void AutomationPattern::removeNodes(const int tick0, const int tick1)
|
||||
* @param Int first tick of the range
|
||||
* @param Int second tick of the range
|
||||
*/
|
||||
void AutomationPattern::resetNodes(const int tick0, const int tick1)
|
||||
void AutomationClip::resetNodes(const int tick0, const int tick1)
|
||||
{
|
||||
if (tick0 == tick1)
|
||||
{
|
||||
@@ -414,9 +414,9 @@ void AutomationPattern::resetNodes(const int tick0, const int tick1)
|
||||
|
||||
|
||||
|
||||
void AutomationPattern::recordValue(TimePos time, float value)
|
||||
void AutomationClip::recordValue(TimePos time, float value)
|
||||
{
|
||||
QMutexLocker m(&m_patternMutex);
|
||||
QMutexLocker m(&m_clipMutex);
|
||||
|
||||
if( value != m_lastRecordedValue )
|
||||
{
|
||||
@@ -442,14 +442,14 @@ void AutomationPattern::recordValue(TimePos time, float value)
|
||||
* @param Boolean. True to ignore unquantized surrounding nodes
|
||||
* @return TimePos with current time of the dragged value
|
||||
*/
|
||||
TimePos AutomationPattern::setDragValue(
|
||||
TimePos AutomationClip::setDragValue(
|
||||
const TimePos & time,
|
||||
const float value,
|
||||
const bool quantPos,
|
||||
const bool controlKey
|
||||
)
|
||||
{
|
||||
QMutexLocker m(&m_patternMutex);
|
||||
QMutexLocker m(&m_clipMutex);
|
||||
|
||||
if (m_dragging == false)
|
||||
{
|
||||
@@ -495,9 +495,9 @@ TimePos AutomationPattern::setDragValue(
|
||||
/**
|
||||
* @brief After the point is dragged, this function is called to apply the change.
|
||||
*/
|
||||
void AutomationPattern::applyDragValue()
|
||||
void AutomationClip::applyDragValue()
|
||||
{
|
||||
QMutexLocker m(&m_patternMutex);
|
||||
QMutexLocker m(&m_clipMutex);
|
||||
|
||||
m_dragging = false;
|
||||
}
|
||||
@@ -505,9 +505,9 @@ void AutomationPattern::applyDragValue()
|
||||
|
||||
|
||||
|
||||
float AutomationPattern::valueAt( const TimePos & _time ) const
|
||||
float AutomationClip::valueAt( const TimePos & _time ) const
|
||||
{
|
||||
QMutexLocker m(&m_patternMutex);
|
||||
QMutexLocker m(&m_clipMutex);
|
||||
|
||||
if( m_timeMap.isEmpty() )
|
||||
{
|
||||
@@ -544,9 +544,9 @@ float AutomationPattern::valueAt( const TimePos & _time ) const
|
||||
|
||||
// This method will get the value at an offset from a node, so we use the outValue of
|
||||
// that node and the inValue of the next node for the calculations.
|
||||
float AutomationPattern::valueAt( timeMap::const_iterator v, int offset ) const
|
||||
float AutomationClip::valueAt( timeMap::const_iterator v, int offset ) const
|
||||
{
|
||||
QMutexLocker m(&m_patternMutex);
|
||||
QMutexLocker m(&m_clipMutex);
|
||||
|
||||
// We never use it with offset 0, but doesn't hurt to return a correct
|
||||
// value if we do
|
||||
@@ -591,9 +591,9 @@ float AutomationPattern::valueAt( timeMap::const_iterator v, int offset ) const
|
||||
|
||||
|
||||
|
||||
float *AutomationPattern::valuesAfter( const TimePos & _time ) const
|
||||
float *AutomationClip::valuesAfter( const TimePos & _time ) const
|
||||
{
|
||||
QMutexLocker m(&m_patternMutex);
|
||||
QMutexLocker m(&m_clipMutex);
|
||||
|
||||
timeMap::const_iterator v = m_timeMap.lowerBound(_time);
|
||||
if( v == m_timeMap.end() || (v+1) == m_timeMap.end() )
|
||||
@@ -615,9 +615,9 @@ float *AutomationPattern::valuesAfter( const TimePos & _time ) const
|
||||
|
||||
|
||||
|
||||
void AutomationPattern::flipY(int min, int max)
|
||||
void AutomationClip::flipY(int min, int max)
|
||||
{
|
||||
QMutexLocker m(&m_patternMutex);
|
||||
QMutexLocker m(&m_clipMutex);
|
||||
|
||||
bool changedTimeMap = false;
|
||||
|
||||
@@ -645,7 +645,7 @@ void AutomationPattern::flipY(int min, int max)
|
||||
|
||||
|
||||
|
||||
void AutomationPattern::flipY()
|
||||
void AutomationClip::flipY()
|
||||
{
|
||||
flipY(getMin(), getMax());
|
||||
}
|
||||
@@ -653,16 +653,16 @@ void AutomationPattern::flipY()
|
||||
|
||||
|
||||
|
||||
void AutomationPattern::flipX(int length)
|
||||
void AutomationClip::flipX(int length)
|
||||
{
|
||||
QMutexLocker m(&m_patternMutex);
|
||||
QMutexLocker m(&m_clipMutex);
|
||||
|
||||
timeMap::const_iterator it = m_timeMap.lowerBound(0);
|
||||
|
||||
if (it == m_timeMap.end()) { return; }
|
||||
|
||||
// Temporary map where we will store the flipped version
|
||||
// of our pattern
|
||||
// of our clip
|
||||
timeMap tempMap;
|
||||
|
||||
float tempValue = 0;
|
||||
@@ -672,7 +672,7 @@ void AutomationPattern::flipX(int length)
|
||||
float realLength = m_timeMap.lastKey();
|
||||
|
||||
// If we have a positive length, we want to flip the area covered by that
|
||||
// length, even if it goes beyond the pattern. A negative length means that
|
||||
// length, even if it goes beyond the clip. A negative length means that
|
||||
// we just want to flip the nodes we have
|
||||
if (length >= 0 && length != realLength)
|
||||
{
|
||||
@@ -752,9 +752,9 @@ void AutomationPattern::flipX(int length)
|
||||
|
||||
|
||||
|
||||
void AutomationPattern::saveSettings( QDomDocument & _doc, QDomElement & _this )
|
||||
void AutomationClip::saveSettings( QDomDocument & _doc, QDomElement & _this )
|
||||
{
|
||||
QMutexLocker m(&m_patternMutex);
|
||||
QMutexLocker m(&m_clipMutex);
|
||||
|
||||
_this.setAttribute( "pos", startPosition() );
|
||||
_this.setAttribute( "len", length() );
|
||||
@@ -794,9 +794,9 @@ void AutomationPattern::saveSettings( QDomDocument & _doc, QDomElement & _this )
|
||||
|
||||
|
||||
|
||||
void AutomationPattern::loadSettings( const QDomElement & _this )
|
||||
void AutomationClip::loadSettings( const QDomElement & _this )
|
||||
{
|
||||
QMutexLocker m(&m_patternMutex);
|
||||
QMutexLocker m(&m_clipMutex);
|
||||
|
||||
clear();
|
||||
|
||||
@@ -851,13 +851,13 @@ void AutomationPattern::loadSettings( const QDomElement & _this )
|
||||
|
||||
|
||||
|
||||
const QString AutomationPattern::name() const
|
||||
const QString AutomationClip::name() const
|
||||
{
|
||||
QMutexLocker m(&m_patternMutex);
|
||||
QMutexLocker m(&m_clipMutex);
|
||||
|
||||
if( !TrackContentObject::name().isEmpty() )
|
||||
if( !Clip::name().isEmpty() )
|
||||
{
|
||||
return TrackContentObject::name();
|
||||
return Clip::name();
|
||||
}
|
||||
if( !m_objects.isEmpty() && m_objects.first() != nullptr )
|
||||
{
|
||||
@@ -869,18 +869,18 @@ const QString AutomationPattern::name() const
|
||||
|
||||
|
||||
|
||||
TrackContentObjectView * AutomationPattern::createView( TrackView * _tv )
|
||||
ClipView * AutomationClip::createView( TrackView * _tv )
|
||||
{
|
||||
QMutexLocker m(&m_patternMutex);
|
||||
QMutexLocker m(&m_clipMutex);
|
||||
|
||||
return new AutomationPatternView( this, _tv );
|
||||
return new AutomationClipView( this, _tv );
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
bool AutomationPattern::isAutomated( const AutomatableModel * _m )
|
||||
bool AutomationClip::isAutomated( const AutomatableModel * _m )
|
||||
{
|
||||
TrackContainer::TrackList l;
|
||||
l += Engine::getSong()->tracks();
|
||||
@@ -892,10 +892,10 @@ bool AutomationPattern::isAutomated( const AutomatableModel * _m )
|
||||
if( ( *it )->type() == Track::AutomationTrack ||
|
||||
( *it )->type() == Track::HiddenAutomationTrack )
|
||||
{
|
||||
const Track::tcoVector & v = ( *it )->getTCOs();
|
||||
for( Track::tcoVector::ConstIterator j = v.begin(); j != v.end(); ++j )
|
||||
const Track::clipVector & v = ( *it )->getClips();
|
||||
for( Track::clipVector::ConstIterator j = v.begin(); j != v.end(); ++j )
|
||||
{
|
||||
const AutomationPattern * a = dynamic_cast<const AutomationPattern *>( *j );
|
||||
const AutomationClip * a = dynamic_cast<const AutomationClip *>( *j );
|
||||
if( a && a->hasAutomation() )
|
||||
{
|
||||
for( objectVector::const_iterator k = a->m_objects.begin(); k != a->m_objects.end(); ++k )
|
||||
@@ -914,12 +914,12 @@ bool AutomationPattern::isAutomated( const AutomatableModel * _m )
|
||||
|
||||
|
||||
/**
|
||||
* @brief returns a list of all the automation patterns that are connected to a specific model
|
||||
* @brief returns a list of all the automation clips that are connected to a specific model
|
||||
* @param _m the model we want to look for
|
||||
*/
|
||||
QVector<AutomationPattern *> AutomationPattern::patternsForModel( const AutomatableModel * _m )
|
||||
QVector<AutomationClip *> AutomationClip::clipsForModel( const AutomatableModel * _m )
|
||||
{
|
||||
QVector<AutomationPattern *> patterns;
|
||||
QVector<AutomationClip *> clips;
|
||||
TrackContainer::TrackList l;
|
||||
l += Engine::getSong()->tracks();
|
||||
l += Engine::getBBTrackContainer()->tracks();
|
||||
@@ -932,17 +932,17 @@ QVector<AutomationPattern *> AutomationPattern::patternsForModel( const Automata
|
||||
if( ( *it )->type() == Track::AutomationTrack ||
|
||||
( *it )->type() == Track::HiddenAutomationTrack )
|
||||
{
|
||||
// get patterns in those tracks....
|
||||
const Track::tcoVector & v = ( *it )->getTCOs();
|
||||
// go through all the patterns...
|
||||
for( Track::tcoVector::ConstIterator j = v.begin(); j != v.end(); ++j )
|
||||
// get clips in those tracks....
|
||||
const Track::clipVector & v = ( *it )->getClips();
|
||||
// go through all the clips...
|
||||
for( Track::clipVector::ConstIterator j = v.begin(); j != v.end(); ++j )
|
||||
{
|
||||
AutomationPattern * a = dynamic_cast<AutomationPattern *>( *j );
|
||||
// check that the pattern has automation
|
||||
AutomationClip * a = dynamic_cast<AutomationClip *>( *j );
|
||||
// check that the clip has automation
|
||||
if( a && a->hasAutomation() )
|
||||
{
|
||||
// now check is the pattern is connected to the model we want by going through all the connections
|
||||
// of the pattern
|
||||
// now check is the clip is connected to the model we want by going through all the connections
|
||||
// of the clip
|
||||
bool has_object = false;
|
||||
for( objectVector::const_iterator k = a->m_objects.begin(); k != a->m_objects.end(); ++k )
|
||||
{
|
||||
@@ -951,25 +951,25 @@ QVector<AutomationPattern *> AutomationPattern::patternsForModel( const Automata
|
||||
has_object = true;
|
||||
}
|
||||
}
|
||||
// if the patterns is connected to the model, add it to the list
|
||||
if( has_object ) { patterns += a; }
|
||||
// if the clips is connected to the model, add it to the list
|
||||
if( has_object ) { clips += a; }
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return patterns;
|
||||
return clips;
|
||||
}
|
||||
|
||||
|
||||
|
||||
AutomationPattern * AutomationPattern::globalAutomationPattern(
|
||||
AutomationClip * AutomationClip::globalAutomationClip(
|
||||
AutomatableModel * _m )
|
||||
{
|
||||
AutomationTrack * t = Engine::getSong()->globalAutomationTrack();
|
||||
Track::tcoVector v = t->getTCOs();
|
||||
for( Track::tcoVector::const_iterator j = v.begin(); j != v.end(); ++j )
|
||||
Track::clipVector v = t->getClips();
|
||||
for( Track::clipVector::const_iterator j = v.begin(); j != v.end(); ++j )
|
||||
{
|
||||
AutomationPattern * a = dynamic_cast<AutomationPattern *>( *j );
|
||||
AutomationClip * a = dynamic_cast<AutomationClip *>( *j );
|
||||
if( a )
|
||||
{
|
||||
for( objectVector::const_iterator k = a->m_objects.begin();
|
||||
@@ -983,7 +983,7 @@ AutomationPattern * AutomationPattern::globalAutomationPattern(
|
||||
}
|
||||
}
|
||||
|
||||
AutomationPattern * a = new AutomationPattern( t );
|
||||
AutomationClip * a = new AutomationClip( t );
|
||||
a->addObject( _m, false );
|
||||
return a;
|
||||
}
|
||||
@@ -991,7 +991,7 @@ AutomationPattern * AutomationPattern::globalAutomationPattern(
|
||||
|
||||
|
||||
|
||||
void AutomationPattern::resolveAllIDs()
|
||||
void AutomationClip::resolveAllIDs()
|
||||
{
|
||||
TrackContainer::TrackList l = Engine::getSong()->tracks() +
|
||||
Engine::getBBTrackContainer()->tracks();
|
||||
@@ -1002,11 +1002,11 @@ void AutomationPattern::resolveAllIDs()
|
||||
if( ( *it )->type() == Track::AutomationTrack ||
|
||||
( *it )->type() == Track::HiddenAutomationTrack )
|
||||
{
|
||||
Track::tcoVector v = ( *it )->getTCOs();
|
||||
for( Track::tcoVector::iterator j = v.begin();
|
||||
Track::clipVector v = ( *it )->getClips();
|
||||
for( Track::clipVector::iterator j = v.begin();
|
||||
j != v.end(); ++j )
|
||||
{
|
||||
AutomationPattern * a = dynamic_cast<AutomationPattern *>( *j );
|
||||
AutomationClip * a = dynamic_cast<AutomationClip *>( *j );
|
||||
if( a )
|
||||
{
|
||||
for( QVector<jo_id_t>::Iterator k = a->m_idsToResolve.begin();
|
||||
@@ -1050,9 +1050,9 @@ void AutomationPattern::resolveAllIDs()
|
||||
|
||||
|
||||
|
||||
void AutomationPattern::clear()
|
||||
void AutomationClip::clear()
|
||||
{
|
||||
QMutexLocker m(&m_patternMutex);
|
||||
QMutexLocker m(&m_clipMutex);
|
||||
|
||||
m_timeMap.clear();
|
||||
|
||||
@@ -1062,14 +1062,14 @@ void AutomationPattern::clear()
|
||||
|
||||
|
||||
|
||||
void AutomationPattern::objectDestroyed( jo_id_t _id )
|
||||
void AutomationClip::objectDestroyed( jo_id_t _id )
|
||||
{
|
||||
QMutexLocker m(&m_patternMutex);
|
||||
QMutexLocker m(&m_clipMutex);
|
||||
|
||||
// TODO: distict between temporary removal (e.g. LADSPA controls
|
||||
// when switching samplerate) and real deletions because in the latter
|
||||
// case we had to remove ourselves if we're the global automation
|
||||
// pattern of the destroyed object
|
||||
// clip of the destroyed object
|
||||
m_idsToResolve += _id;
|
||||
|
||||
for( objectVector::Iterator objIt = m_objects.begin();
|
||||
@@ -1090,9 +1090,9 @@ void AutomationPattern::objectDestroyed( jo_id_t _id )
|
||||
|
||||
|
||||
|
||||
void AutomationPattern::cleanObjects()
|
||||
void AutomationClip::cleanObjects()
|
||||
{
|
||||
QMutexLocker m(&m_patternMutex);
|
||||
QMutexLocker m(&m_clipMutex);
|
||||
|
||||
for( objectVector::iterator it = m_objects.begin(); it != m_objects.end(); )
|
||||
{
|
||||
@@ -1110,7 +1110,7 @@ void AutomationPattern::cleanObjects()
|
||||
|
||||
|
||||
|
||||
void AutomationPattern::generateTangents()
|
||||
void AutomationClip::generateTangents()
|
||||
{
|
||||
generateTangents(m_timeMap.begin(), m_timeMap.size());
|
||||
}
|
||||
@@ -1122,9 +1122,9 @@ void AutomationPattern::generateTangents()
|
||||
// of the node (in case we have discrete value jumps in the middle of a curve).
|
||||
// If the inValue and outValue of a node are the same, consequently the inTangent and
|
||||
// outTangent values of the node will be the same too.
|
||||
void AutomationPattern::generateTangents(timeMap::iterator it, int numToGenerate)
|
||||
void AutomationClip::generateTangents(timeMap::iterator it, int numToGenerate)
|
||||
{
|
||||
QMutexLocker m(&m_patternMutex);
|
||||
QMutexLocker m(&m_clipMutex);
|
||||
|
||||
if( m_timeMap.size() < 2 && numToGenerate > 0 )
|
||||
{
|
||||
@@ -1,6 +1,6 @@
|
||||
/*
|
||||
* AutomationPattern.cpp - Implementation of class AutomationNode which
|
||||
* holds information on a single automation pattern node
|
||||
* AutomationClip.cpp - Implementation of class AutomationNode which
|
||||
* holds information on a single automation clip node
|
||||
*
|
||||
* Copyright (c) 2020 Ian Caio <iancaio_dev/at/hotmail.com>
|
||||
*
|
||||
@@ -24,12 +24,12 @@
|
||||
*/
|
||||
|
||||
#include "AutomationNode.h"
|
||||
#include "AutomationPattern.h"
|
||||
#include "AutomationClip.h"
|
||||
|
||||
|
||||
// Dummy constructor for the QMap
|
||||
AutomationNode::AutomationNode() :
|
||||
m_pattern(nullptr),
|
||||
m_clip(nullptr),
|
||||
m_pos(0),
|
||||
m_inValue(0),
|
||||
m_outValue(0),
|
||||
@@ -38,8 +38,8 @@ AutomationNode::AutomationNode() :
|
||||
{
|
||||
}
|
||||
|
||||
AutomationNode::AutomationNode(AutomationPattern* pat, float value, int pos) :
|
||||
m_pattern(pat),
|
||||
AutomationNode::AutomationNode(AutomationClip* clip, float value, int pos) :
|
||||
m_clip(clip),
|
||||
m_pos(pos),
|
||||
m_inValue(value),
|
||||
m_outValue(value),
|
||||
@@ -48,8 +48,8 @@ AutomationNode::AutomationNode(AutomationPattern* pat, float value, int pos) :
|
||||
{
|
||||
}
|
||||
|
||||
AutomationNode::AutomationNode(AutomationPattern* pat, float inValue, float outValue, int pos) :
|
||||
m_pattern(pat),
|
||||
AutomationNode::AutomationNode(AutomationClip* clip, float inValue, float outValue, int pos) :
|
||||
m_clip(clip),
|
||||
m_pos(pos),
|
||||
m_inValue(inValue),
|
||||
m_outValue(outValue),
|
||||
@@ -67,15 +67,15 @@ void AutomationNode::setInValue(float value)
|
||||
m_inValue = value;
|
||||
|
||||
// Recalculate the tangents from neighbor nodes
|
||||
AutomationPattern::timeMap & tm = m_pattern->getTimeMap();
|
||||
AutomationClip::timeMap & tm = m_clip->getTimeMap();
|
||||
|
||||
// Get an iterator pointing to this node
|
||||
AutomationPattern::timeMap::iterator it = tm.lowerBound(m_pos);
|
||||
AutomationClip::timeMap::iterator it = tm.lowerBound(m_pos);
|
||||
// If it's not the first node, get the one immediately behind it
|
||||
if (it != tm.begin()) { --it; }
|
||||
|
||||
// Generate tangents from the previously, current and next nodes
|
||||
m_pattern->generateTangents(it, 3);
|
||||
m_clip->generateTangents(it, 3);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -87,15 +87,15 @@ void AutomationNode::setOutValue(float value)
|
||||
m_outValue = value;
|
||||
|
||||
// Recalculate the tangents from neighbor nodes
|
||||
AutomationPattern::timeMap & tm = m_pattern->getTimeMap();
|
||||
AutomationClip::timeMap & tm = m_clip->getTimeMap();
|
||||
|
||||
// Get an iterator pointing to this node
|
||||
AutomationPattern::timeMap::iterator it = tm.lowerBound(m_pos);
|
||||
AutomationClip::timeMap::iterator it = tm.lowerBound(m_pos);
|
||||
// If it's not the first node, get the one immediately behind it
|
||||
if (it != tm.begin()) { --it; }
|
||||
|
||||
// Generate tangents from the previously, current and next nodes
|
||||
m_pattern->generateTangents(it, 3);
|
||||
m_clip->generateTangents(it, 3);
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* BBTCO.cpp - implementation of class bbTCO
|
||||
* BBClip.cpp - implementation of class bbClip
|
||||
*
|
||||
* Copyright (c) 2004-2014 Tobias Doerffel <tobydox/at/users.sourceforge.net>
|
||||
*
|
||||
@@ -22,7 +22,7 @@
|
||||
*
|
||||
*/
|
||||
|
||||
#include "BBTCO.h"
|
||||
#include "BBClip.h"
|
||||
|
||||
#include <QDomElement>
|
||||
|
||||
@@ -31,8 +31,8 @@
|
||||
#include "Engine.h"
|
||||
|
||||
|
||||
BBTCO::BBTCO( Track * _track ) :
|
||||
TrackContentObject( _track )
|
||||
BBClip::BBClip( Track * _track ) :
|
||||
Clip( _track )
|
||||
{
|
||||
bar_t t = Engine::getBBTrackContainer()->lengthOfBB( bbTrackIndex() );
|
||||
if( t > 0 )
|
||||
@@ -44,7 +44,7 @@ BBTCO::BBTCO( Track * _track ) :
|
||||
setAutoResize( false );
|
||||
}
|
||||
|
||||
void BBTCO::saveSettings( QDomDocument & doc, QDomElement & element )
|
||||
void BBClip::saveSettings( QDomDocument & doc, QDomElement & element )
|
||||
{
|
||||
element.setAttribute( "name", name() );
|
||||
if( element.parentNode().nodeName() == "clipboard" )
|
||||
@@ -66,7 +66,7 @@ void BBTCO::saveSettings( QDomDocument & doc, QDomElement & element )
|
||||
|
||||
|
||||
|
||||
void BBTCO::loadSettings( const QDomElement & element )
|
||||
void BBClip::loadSettings( const QDomElement & element )
|
||||
{
|
||||
setName( element.attribute( "name" ) );
|
||||
if( element.attribute( "pos" ).toInt() >= 0 )
|
||||
@@ -101,14 +101,14 @@ void BBTCO::loadSettings( const QDomElement & element )
|
||||
|
||||
|
||||
|
||||
int BBTCO::bbTrackIndex()
|
||||
int BBClip::bbTrackIndex()
|
||||
{
|
||||
return dynamic_cast<BBTrack *>( getTrack() )->index();
|
||||
}
|
||||
|
||||
|
||||
|
||||
TrackContentObjectView * BBTCO::createView( TrackView * _tv )
|
||||
ClipView * BBClip::createView( TrackView * _tv )
|
||||
{
|
||||
return new BBTCOView( this, _tv );
|
||||
return new BBClipView( this, _tv );
|
||||
}
|
||||
@@ -53,21 +53,21 @@ BBTrackContainer::~BBTrackContainer()
|
||||
|
||||
|
||||
|
||||
bool BBTrackContainer::play(TimePos start, fpp_t frames, f_cnt_t offset, int tcoNum)
|
||||
bool BBTrackContainer::play(TimePos start, fpp_t frames, f_cnt_t offset, int clipNum)
|
||||
{
|
||||
bool notePlayed = false;
|
||||
|
||||
if (lengthOfBB(tcoNum) <= 0)
|
||||
if (lengthOfBB(clipNum) <= 0)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
start = start % (lengthOfBB(tcoNum) * TimePos::ticksPerBar());
|
||||
start = start % (lengthOfBB(clipNum) * TimePos::ticksPerBar());
|
||||
|
||||
TrackList tl = tracks();
|
||||
for (Track * t : tl)
|
||||
{
|
||||
if (t->play(start, frames, offset, tcoNum))
|
||||
if (t->play(start, frames, offset, clipNum))
|
||||
{
|
||||
notePlayed = true;
|
||||
}
|
||||
@@ -97,10 +97,10 @@ bar_t BBTrackContainer::lengthOfBB(int bb) const
|
||||
const TrackList & tl = tracks();
|
||||
for (Track * t : tl)
|
||||
{
|
||||
// Don't create TCOs here if they don't exist
|
||||
if (bb < t->numOfTCOs())
|
||||
// Don't create Clips here if they don't exist
|
||||
if (bb < t->numOfClips())
|
||||
{
|
||||
maxLength = qMax(maxLength, t->getTCO(bb)->length());
|
||||
maxLength = qMax(maxLength, t->getClip(bb)->length());
|
||||
}
|
||||
}
|
||||
|
||||
@@ -123,7 +123,7 @@ void BBTrackContainer::removeBB(int bb)
|
||||
TrackList tl = tracks();
|
||||
for (Track * t : tl)
|
||||
{
|
||||
delete t->getTCO(bb);
|
||||
delete t->getClip(bb);
|
||||
t->removeBar(bb * DefaultTicksPerBar);
|
||||
}
|
||||
if (bb <= currentBB())
|
||||
@@ -140,7 +140,7 @@ void BBTrackContainer::swapBB(int bb1, int bb2)
|
||||
TrackList tl = tracks();
|
||||
for (Track * t : tl)
|
||||
{
|
||||
t->swapPositionOfTCOs(bb1, bb2);
|
||||
t->swapPositionOfClips(bb1, bb2);
|
||||
}
|
||||
updateComboBox();
|
||||
}
|
||||
@@ -148,9 +148,9 @@ void BBTrackContainer::swapBB(int bb1, int bb2)
|
||||
|
||||
|
||||
|
||||
void BBTrackContainer::updateBBTrack(TrackContentObject * tco)
|
||||
void BBTrackContainer::updateBBTrack(Clip * clip)
|
||||
{
|
||||
BBTrack * t = BBTrack::findBBTrack(tco->startPosition() / DefaultTicksPerBar);
|
||||
BBTrack * t = BBTrack::findBBTrack(clip->startPosition() / DefaultTicksPerBar);
|
||||
if (t != nullptr)
|
||||
{
|
||||
t->dataChanged();
|
||||
@@ -167,7 +167,7 @@ void BBTrackContainer::fixIncorrectPositions()
|
||||
{
|
||||
for (int i = 0; i < numOfBBs(); ++i)
|
||||
{
|
||||
t->getTCO(i)->movePosition(TimePos(i, 0));
|
||||
t->getClip(i)->movePosition(TimePos(i, 0));
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -231,27 +231,27 @@ void BBTrackContainer::currentBBChanged()
|
||||
|
||||
|
||||
|
||||
void BBTrackContainer::createTCOsForBB(int bb)
|
||||
void BBTrackContainer::createClipsForBB(int bb)
|
||||
{
|
||||
TrackList tl = tracks();
|
||||
for (Track * t : tl)
|
||||
{
|
||||
t->createTCOsForBB(bb);
|
||||
t->createClipsForBB(bb);
|
||||
}
|
||||
}
|
||||
|
||||
AutomatedValueMap BBTrackContainer::automatedValuesAt(TimePos time, int tcoNum) const
|
||||
AutomatedValueMap BBTrackContainer::automatedValuesAt(TimePos time, int clipNum) const
|
||||
{
|
||||
Q_ASSERT(tcoNum >= 0);
|
||||
Q_ASSERT(clipNum >= 0);
|
||||
Q_ASSERT(time.getTicks() >= 0);
|
||||
|
||||
auto lengthBars = lengthOfBB(tcoNum);
|
||||
auto lengthBars = lengthOfBB(clipNum);
|
||||
auto lengthTicks = lengthBars * TimePos::ticksPerBar();
|
||||
if (time > lengthTicks)
|
||||
{
|
||||
time = lengthTicks;
|
||||
}
|
||||
|
||||
return TrackContainer::automatedValuesAt(time + (TimePos::ticksPerBar() * tcoNum), tcoNum);
|
||||
return TrackContainer::automatedValuesAt(time + (TimePos::ticksPerBar() * clipNum), clipNum);
|
||||
}
|
||||
|
||||
|
||||
@@ -5,11 +5,11 @@ set(LMMS_SRCS
|
||||
core/AudioEngineProfiler.cpp
|
||||
core/AudioEngineWorkerThread.cpp
|
||||
core/AutomatableModel.cpp
|
||||
core/AutomationPattern.cpp
|
||||
core/AutomationClip.cpp
|
||||
core/AutomationNode.cpp
|
||||
core/BandLimitedWave.cpp
|
||||
core/base64.cpp
|
||||
core/BBTCO.cpp
|
||||
core/BBClip.cpp
|
||||
core/BBTrackContainer.cpp
|
||||
core/BufferManager.cpp
|
||||
core/Clipboard.cpp
|
||||
@@ -24,7 +24,7 @@ set(LMMS_SRCS
|
||||
core/Engine.cpp
|
||||
core/EnvelopeAndLfoParameters.cpp
|
||||
core/fft_helpers.cpp
|
||||
core/FxMixer.cpp
|
||||
core/Mixer.cpp
|
||||
core/ImportFilter.cpp
|
||||
core/InlineAutomation.cpp
|
||||
core/Instrument.cpp
|
||||
@@ -66,9 +66,9 @@ set(LMMS_SRCS
|
||||
core/RenderManager.cpp
|
||||
core/RingBuffer.cpp
|
||||
core/SampleBuffer.cpp
|
||||
core/SampleClip.cpp
|
||||
core/SamplePlayHandle.cpp
|
||||
core/SampleRecordHandle.cpp
|
||||
core/SampleTCO.cpp
|
||||
core/Scale.cpp
|
||||
core/SerializingObject.cpp
|
||||
core/Song.cpp
|
||||
@@ -77,7 +77,7 @@ set(LMMS_SRCS
|
||||
core/ToolPlugin.cpp
|
||||
core/Track.cpp
|
||||
core/TrackContainer.cpp
|
||||
core/TrackContentObject.cpp
|
||||
core/Clip.cpp
|
||||
core/ValueBuffer.cpp
|
||||
core/VstSyncController.cpp
|
||||
core/StepRecorder.cpp
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* TrackContentObject.cpp - implementation of TrackContentObject class
|
||||
* Clip.cpp - implementation of Clip class
|
||||
*
|
||||
* Copyright (c) 2004-2014 Tobias Doerffel <tobydox/at/users.sourceforge.net>
|
||||
*
|
||||
@@ -22,24 +22,24 @@
|
||||
*
|
||||
*/
|
||||
|
||||
#include "TrackContentObject.h"
|
||||
#include "Clip.h"
|
||||
|
||||
#include <QDomDocument>
|
||||
|
||||
#include "AutomationEditor.h"
|
||||
#include "AutomationPattern.h"
|
||||
#include "AutomationClip.h"
|
||||
#include "Engine.h"
|
||||
#include "GuiApplication.h"
|
||||
#include "Song.h"
|
||||
|
||||
|
||||
/*! \brief Create a new TrackContentObject
|
||||
/*! \brief Create a new Clip
|
||||
*
|
||||
* Creates a new track content object for the given track.
|
||||
* Creates a new clip for the given track.
|
||||
*
|
||||
* \param _track The track that will contain the new object
|
||||
*/
|
||||
TrackContentObject::TrackContentObject( Track * track ) :
|
||||
Clip::Clip( Track * track ) :
|
||||
Model( track ),
|
||||
m_track( track ),
|
||||
m_startPosition(),
|
||||
@@ -51,7 +51,7 @@ TrackContentObject::TrackContentObject( Track * track ) :
|
||||
{
|
||||
if( getTrack() )
|
||||
{
|
||||
getTrack()->addTCO( this );
|
||||
getTrack()->addClip( this );
|
||||
}
|
||||
setJournalling( false );
|
||||
movePosition( 0 );
|
||||
@@ -62,32 +62,32 @@ TrackContentObject::TrackContentObject( Track * track ) :
|
||||
|
||||
|
||||
|
||||
/*! \brief Destroy a TrackContentObject
|
||||
/*! \brief Destroy a Clip
|
||||
*
|
||||
* Destroys the given track content object.
|
||||
* Destroys the given clip.
|
||||
*
|
||||
*/
|
||||
TrackContentObject::~TrackContentObject()
|
||||
Clip::~Clip()
|
||||
{
|
||||
emit destroyedTCO();
|
||||
emit destroyedClip();
|
||||
|
||||
if( getTrack() )
|
||||
{
|
||||
getTrack()->removeTCO( this );
|
||||
getTrack()->removeClip( this );
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
/*! \brief Move this TrackContentObject's position in time
|
||||
/*! \brief Move this Clip's position in time
|
||||
*
|
||||
* If the track content object has moved, update its position. We
|
||||
* If the clip has moved, update its position. We
|
||||
* also add a journal entry for undo and update the display.
|
||||
*
|
||||
* \param _pos The new position of the track content object.
|
||||
* \param _pos The new position of the clip.
|
||||
*/
|
||||
void TrackContentObject::movePosition( const TimePos & pos )
|
||||
void Clip::movePosition( const TimePos & pos )
|
||||
{
|
||||
TimePos newPos = qMax(0, pos.getTicks());
|
||||
if (m_startPosition != newPos)
|
||||
@@ -103,14 +103,14 @@ void TrackContentObject::movePosition( const TimePos & pos )
|
||||
|
||||
|
||||
|
||||
/*! \brief Change the length of this TrackContentObject
|
||||
/*! \brief Change the length of this Clip
|
||||
*
|
||||
* If the track content object's length has changed, update it. We
|
||||
* If the clip's length has changed, update it. We
|
||||
* also add a journal entry for undo and update the display.
|
||||
*
|
||||
* \param _length The new length of the track content object.
|
||||
* \param _length The new length of the clip.
|
||||
*/
|
||||
void TrackContentObject::changeLength( const TimePos & length )
|
||||
void Clip::changeLength( const TimePos & length )
|
||||
{
|
||||
m_length = length;
|
||||
Engine::getSong()->updateLength();
|
||||
@@ -120,7 +120,7 @@ void TrackContentObject::changeLength( const TimePos & length )
|
||||
|
||||
|
||||
|
||||
bool TrackContentObject::comparePosition(const TrackContentObject *a, const TrackContentObject *b)
|
||||
bool Clip::comparePosition(const Clip *a, const Clip *b)
|
||||
{
|
||||
return a->startPosition() < b->startPosition();
|
||||
}
|
||||
@@ -128,11 +128,11 @@ bool TrackContentObject::comparePosition(const TrackContentObject *a, const Trac
|
||||
|
||||
|
||||
|
||||
/*! \brief Copies the state of a TrackContentObject to another TrackContentObject
|
||||
/*! \brief Copies the state of a Clip to another Clip
|
||||
*
|
||||
* This method copies the state of a TCO to another TCO
|
||||
* This method copies the state of a Clip to another Clip
|
||||
*/
|
||||
void TrackContentObject::copyStateTo( TrackContentObject *src, TrackContentObject *dst )
|
||||
void Clip::copyStateTo( Clip *src, Clip *dst )
|
||||
{
|
||||
// If the node names match we copy the state
|
||||
if( src->nodeName() == dst->nodeName() ){
|
||||
@@ -144,23 +144,23 @@ void TrackContentObject::copyStateTo( TrackContentObject *src, TrackContentObjec
|
||||
dst->restoreState( parent.firstChild().toElement() );
|
||||
dst->movePosition( pos );
|
||||
|
||||
AutomationPattern::resolveAllIDs();
|
||||
GuiApplication::instance()->automationEditor()->m_editor->updateAfterPatternChange();
|
||||
AutomationClip::resolveAllIDs();
|
||||
GuiApplication::instance()->automationEditor()->m_editor->updateAfterClipChange();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
/*! \brief Mutes this TrackContentObject
|
||||
/*! \brief Mutes this Clip
|
||||
*
|
||||
* Restore the previous state of this track content object. This will
|
||||
* restore the position or the length of the track content object
|
||||
* Restore the previous state of this clip. This will
|
||||
* restore the position or the length of the clip
|
||||
* depending on what was changed.
|
||||
*
|
||||
* \param _je The journal entry to undo
|
||||
*/
|
||||
void TrackContentObject::toggleMute()
|
||||
void Clip::toggleMute()
|
||||
{
|
||||
m_mutedModel.setValue( !m_mutedModel.value() );
|
||||
emit dataChanged();
|
||||
@@ -169,7 +169,7 @@ void TrackContentObject::toggleMute()
|
||||
|
||||
|
||||
|
||||
TimePos TrackContentObject::startTimeOffset() const
|
||||
TimePos Clip::startTimeOffset() const
|
||||
{
|
||||
return m_startTimeOffset;
|
||||
}
|
||||
@@ -177,14 +177,14 @@ TimePos TrackContentObject::startTimeOffset() const
|
||||
|
||||
|
||||
|
||||
void TrackContentObject::setStartTimeOffset( const TimePos &startTimeOffset )
|
||||
void Clip::setStartTimeOffset( const TimePos &startTimeOffset )
|
||||
{
|
||||
m_startTimeOffset = startTimeOffset;
|
||||
}
|
||||
|
||||
|
||||
|
||||
void TrackContentObject::useCustomClipColor( bool b )
|
||||
void Clip::useCustomClipColor( bool b )
|
||||
{
|
||||
if (b == m_useCustomClipColor) { return; }
|
||||
m_useCustomClipColor = b;
|
||||
@@ -192,7 +192,7 @@ void TrackContentObject::useCustomClipColor( bool b )
|
||||
}
|
||||
|
||||
|
||||
bool TrackContentObject::hasColor()
|
||||
bool Clip::hasColor()
|
||||
{
|
||||
return usesCustomClipColor() || getTrack()->useColor();
|
||||
}
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Clipboard.cpp - the clipboard for patterns, notes etc.
|
||||
* Clipboard.cpp - the clipboard for clips, notes etc.
|
||||
*
|
||||
* Copyright (c) 2004-2009 Tobias Doerffel <tobydox/at/users.sourceforge.net>
|
||||
*
|
||||
|
||||
@@ -40,7 +40,8 @@
|
||||
|
||||
// Vector with all the upgrade methods
|
||||
const std::vector<ConfigManager::UpgradeMethod> ConfigManager::UPGRADE_METHODS = {
|
||||
&ConfigManager::upgrade_1_1_90 , &ConfigManager::upgrade_1_1_91
|
||||
&ConfigManager::upgrade_1_1_90 , &ConfigManager::upgrade_1_1_91,
|
||||
&ConfigManager::upgrade_1_2_2
|
||||
};
|
||||
|
||||
static inline QString ensureTrailingSlash(const QString & s )
|
||||
@@ -119,16 +120,35 @@ void ConfigManager::upgrade_1_1_90()
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void ConfigManager::upgrade_1_1_91()
|
||||
{
|
||||
// rename displaydbv to displaydbfs
|
||||
if (!value("app", "displaydbv").isNull()) {
|
||||
if (!value("app", "displaydbv").isNull())
|
||||
{
|
||||
setValue("app", "displaydbfs", value("app", "displaydbv"));
|
||||
deleteValue("app", "displaydbv");
|
||||
}
|
||||
}
|
||||
|
||||
void ConfigManager::upgrade_1_2_2()
|
||||
{
|
||||
// Since mixer has been renamed to audioengine, we need to transfer the
|
||||
// attributes from the old element to the new one
|
||||
std::vector<QString> attrs = {
|
||||
"audiodev", "mididev", "framesperaudiobuffer", "hqaudio", "samplerate"
|
||||
};
|
||||
|
||||
for (auto attr : attrs)
|
||||
{
|
||||
if (!value("mixer", attr).isNull())
|
||||
{
|
||||
setValue("audioengine", attr, value("mixer", attr));
|
||||
deleteValue("mixer", attr);
|
||||
}
|
||||
}
|
||||
|
||||
m_settings.remove("mixer");
|
||||
}
|
||||
|
||||
void ConfigManager::upgrade()
|
||||
{
|
||||
@@ -139,7 +159,8 @@ void ConfigManager::upgrade()
|
||||
}
|
||||
|
||||
// Runs all necessary upgrade methods
|
||||
std::for_each( UPGRADE_METHODS.begin() + m_configVersion, UPGRADE_METHODS.end(),
|
||||
std::size_t max = std::min(static_cast<std::size_t>(m_configVersion), UPGRADE_METHODS.size());
|
||||
std::for_each( UPGRADE_METHODS.begin() + max, UPGRADE_METHODS.end(),
|
||||
[this](UpgradeMethod um)
|
||||
{
|
||||
(this->*um)();
|
||||
|
||||
@@ -70,7 +70,8 @@ const std::vector<DataFile::UpgradeMethod> DataFile::UPGRADE_METHODS = {
|
||||
&DataFile::upgrade_1_1_91 , &DataFile::upgrade_1_2_0_rc3,
|
||||
&DataFile::upgrade_1_3_0 , &DataFile::upgrade_noHiddenClipNames,
|
||||
&DataFile::upgrade_automationNodes , &DataFile::upgrade_extendedNoteRange,
|
||||
&DataFile::upgrade_defaultTripleOscillatorHQ
|
||||
&DataFile::upgrade_defaultTripleOscillatorHQ,
|
||||
&DataFile::upgrade_mixerRename
|
||||
};
|
||||
|
||||
// Vector of all versions that have upgrade routines.
|
||||
@@ -94,7 +95,7 @@ DataFile::typeDescStruct
|
||||
{ DataFile::ClipboardData, "clipboard-data" },
|
||||
{ DataFile::JournalData, "journaldata" },
|
||||
{ DataFile::EffectSettings, "effectsettings" },
|
||||
{ DataFile::NotePattern, "pattern" }
|
||||
{ DataFile::MidiClip, "pattern" }
|
||||
} ;
|
||||
|
||||
|
||||
@@ -199,7 +200,7 @@ bool DataFile::validate( QString extension )
|
||||
return true;
|
||||
}
|
||||
break;
|
||||
case Type::NotePattern:
|
||||
case Type::MidiClip:
|
||||
if (extension == "xpt" || extension == "xptz")
|
||||
{
|
||||
return true;
|
||||
@@ -1769,10 +1770,41 @@ void DataFile::upgrade_defaultTripleOscillatorHQ()
|
||||
}
|
||||
|
||||
|
||||
// Remove FX prefix from mixer and related nodes
|
||||
void DataFile::upgrade_mixerRename()
|
||||
{
|
||||
// Change nodename <fxmixer> to <mixer>
|
||||
QDomNodeList fxmixer = elementsByTagName("fxmixer");
|
||||
for (int i = 0; !fxmixer.item(i).isNull(); ++i)
|
||||
{
|
||||
fxmixer.item(i).toElement().setTagName("mixer");
|
||||
}
|
||||
|
||||
// Change nodename <fxchannel> to <mixerchannel>
|
||||
QDomNodeList fxchannel = elementsByTagName("fxchannel");
|
||||
for (int i = 0; !fxchannel.item(i).isNull(); ++i)
|
||||
{
|
||||
fxchannel.item(i).toElement().setTagName("mixerchannel");
|
||||
}
|
||||
|
||||
// Change the attribute fxch of element <instrumenttrack> to mixch
|
||||
QDomNodeList fxch = elementsByTagName("instrumenttrack");
|
||||
for(int i = 0; !fxch.item(i).isNull(); ++i)
|
||||
{
|
||||
if(fxch.item(i).toElement().hasAttribute("fxch"))
|
||||
{
|
||||
fxch.item(i).toElement().setAttribute("mixch", fxch.item(i).toElement().attribute("fxch"));
|
||||
fxch.item(i).toElement().removeAttribute("fxch");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void DataFile::upgrade()
|
||||
{
|
||||
// Runs all necessary upgrade methods
|
||||
std::for_each( UPGRADE_METHODS.begin() + m_fileVersion, UPGRADE_METHODS.end(),
|
||||
std::size_t max = std::min(static_cast<std::size_t>(m_fileVersion), UPGRADE_METHODS.size());
|
||||
std::for_each( UPGRADE_METHODS.begin() + max, UPGRADE_METHODS.end(),
|
||||
[this](UpgradeMethod um)
|
||||
{
|
||||
(this->*um)();
|
||||
|
||||
@@ -27,7 +27,7 @@
|
||||
#include "AudioEngine.h"
|
||||
#include "BBTrackContainer.h"
|
||||
#include "ConfigManager.h"
|
||||
#include "FxMixer.h"
|
||||
#include "Mixer.h"
|
||||
#include "Ladspa2LMMS.h"
|
||||
#include "Lv2Manager.h"
|
||||
#include "Plugin.h"
|
||||
@@ -39,7 +39,7 @@
|
||||
|
||||
float LmmsCore::s_framesPerTick;
|
||||
AudioEngine* LmmsCore::s_audioEngine = nullptr;
|
||||
FxMixer * LmmsCore::s_fxMixer = nullptr;
|
||||
Mixer * LmmsCore::s_mixer = nullptr;
|
||||
BBTrackContainer * LmmsCore::s_bbTrackContainer = nullptr;
|
||||
Song * LmmsCore::s_song = nullptr;
|
||||
ProjectJournal * LmmsCore::s_projectJournal = nullptr;
|
||||
@@ -66,7 +66,7 @@ void LmmsCore::init( bool renderOnly )
|
||||
s_projectJournal = new ProjectJournal;
|
||||
s_audioEngine = new AudioEngine( renderOnly );
|
||||
s_song = new Song;
|
||||
s_fxMixer = new FxMixer;
|
||||
s_mixer = new Mixer;
|
||||
s_bbTrackContainer = new BBTrackContainer;
|
||||
|
||||
#ifdef LMMS_HAVE_LV2
|
||||
@@ -100,7 +100,7 @@ void LmmsCore::destroy()
|
||||
|
||||
deleteHelper( &s_bbTrackContainer );
|
||||
|
||||
deleteHelper( &s_fxMixer );
|
||||
deleteHelper( &s_mixer );
|
||||
deleteHelper( &s_audioEngine );
|
||||
|
||||
#ifdef LMMS_HAVE_LV2
|
||||
|
||||
@@ -33,9 +33,9 @@ void InlineAutomation::saveSettings( QDomDocument & _doc,
|
||||
if( hasAutomation() )
|
||||
{
|
||||
QDomElement ap = _doc.createElement(
|
||||
AutomationPattern::classNodeName() );
|
||||
AutomationClip::classNodeName() );
|
||||
QDomElement v = _doc.createElement( nodeName() );
|
||||
automationPattern()->saveSettings( _doc, v );
|
||||
automationClip()->saveSettings( _doc, v );
|
||||
ap.appendChild( v );
|
||||
_parent.appendChild( ap );
|
||||
}
|
||||
@@ -46,13 +46,13 @@ void InlineAutomation::saveSettings( QDomDocument & _doc,
|
||||
|
||||
void InlineAutomation::loadSettings( const QDomElement & _this )
|
||||
{
|
||||
QDomNode node = _this.namedItem( AutomationPattern::classNodeName() );
|
||||
QDomNode node = _this.namedItem( AutomationClip::classNodeName() );
|
||||
if( node.isElement() )
|
||||
{
|
||||
node = node.namedItem( nodeName() );
|
||||
if( node.isElement() )
|
||||
{
|
||||
automationPattern()->loadSettings(
|
||||
automationClip()->loadSettings(
|
||||
node.toElement() );
|
||||
}
|
||||
}
|
||||
|
||||
@@ -24,7 +24,7 @@
|
||||
|
||||
|
||||
#include "MeterModel.h"
|
||||
#include "AutomationPattern.h"
|
||||
#include "AutomationClip.h"
|
||||
|
||||
|
||||
MeterModel::MeterModel( ::Model * _parent ) :
|
||||
@@ -53,8 +53,8 @@ void MeterModel::reset()
|
||||
m_numeratorModel.setValue( 4 );
|
||||
m_denominatorModel.setValue( 4 );
|
||||
|
||||
AutomationPattern::globalAutomationPattern( &m_numeratorModel )->clear();
|
||||
AutomationPattern::globalAutomationPattern( &m_denominatorModel )->clear();
|
||||
AutomationClip::globalAutomationClip( &m_numeratorModel )->clear();
|
||||
AutomationClip::globalAutomationClip( &m_denominatorModel )->clear();
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* FxMixer.cpp - effect mixer for LMMS
|
||||
* Mixer.cpp - effect mixer for LMMS
|
||||
*
|
||||
* Copyright (c) 2008-2011 Tobias Doerffel <tobydox/at/users.sourceforge.net>
|
||||
*
|
||||
@@ -27,7 +27,7 @@
|
||||
#include "AudioEngine.h"
|
||||
#include "AudioEngineWorkerThread.h"
|
||||
#include "BufferManager.h"
|
||||
#include "FxMixer.h"
|
||||
#include "Mixer.h"
|
||||
#include "MixHelpers.h"
|
||||
#include "Song.h"
|
||||
|
||||
@@ -36,7 +36,7 @@
|
||||
#include "BBTrackContainer.h"
|
||||
#include "TrackContainer.h" // For TrackContainer::TrackList typedef
|
||||
|
||||
FxRoute::FxRoute( FxChannel * from, FxChannel * to, float amount ) :
|
||||
MixerRoute::MixerRoute( MixerChannel * from, MixerChannel * to, float amount ) :
|
||||
m_from( from ),
|
||||
m_to( to ),
|
||||
m_amount( amount, 0, 1, 0.001, nullptr,
|
||||
@@ -47,19 +47,19 @@ FxRoute::FxRoute( FxChannel * from, FxChannel * to, float amount ) :
|
||||
}
|
||||
|
||||
|
||||
FxRoute::~FxRoute()
|
||||
MixerRoute::~MixerRoute()
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
void FxRoute::updateName()
|
||||
void MixerRoute::updateName()
|
||||
{
|
||||
m_amount.setDisplayName(
|
||||
tr( "Amount to send from channel %1 to channel %2" ).arg( m_from->m_channelIndex ).arg( m_to->m_channelIndex ) );
|
||||
}
|
||||
|
||||
|
||||
FxChannel::FxChannel( int idx, Model * _parent ) :
|
||||
MixerChannel::MixerChannel( int idx, Model * _parent ) :
|
||||
m_fxChain( nullptr ),
|
||||
m_hasInput( false ),
|
||||
m_stillRunning( false ),
|
||||
@@ -82,15 +82,15 @@ FxChannel::FxChannel( int idx, Model * _parent ) :
|
||||
|
||||
|
||||
|
||||
FxChannel::~FxChannel()
|
||||
MixerChannel::~MixerChannel()
|
||||
{
|
||||
delete[] m_buffer;
|
||||
}
|
||||
|
||||
|
||||
inline void FxChannel::processed()
|
||||
inline void MixerChannel::processed()
|
||||
{
|
||||
for( const FxRoute * receiverRoute : m_sends )
|
||||
for( const MixerRoute * receiverRoute : m_sends )
|
||||
{
|
||||
if( receiverRoute->receiver()->m_muted == false )
|
||||
{
|
||||
@@ -99,7 +99,7 @@ inline void FxChannel::processed()
|
||||
}
|
||||
}
|
||||
|
||||
void FxChannel::incrementDeps()
|
||||
void MixerChannel::incrementDeps()
|
||||
{
|
||||
int i = m_dependenciesMet++ + 1;
|
||||
if( i >= m_receives.size() && ! m_queued )
|
||||
@@ -109,7 +109,7 @@ void FxChannel::incrementDeps()
|
||||
}
|
||||
}
|
||||
|
||||
void FxChannel::unmuteForSolo()
|
||||
void MixerChannel::unmuteForSolo()
|
||||
{
|
||||
//TODO: Recursively activate every channel, this channel sends to
|
||||
m_muteModel.setValue(false);
|
||||
@@ -117,15 +117,15 @@ void FxChannel::unmuteForSolo()
|
||||
|
||||
|
||||
|
||||
void FxChannel::doProcessing()
|
||||
void MixerChannel::doProcessing()
|
||||
{
|
||||
const fpp_t fpp = Engine::audioEngine()->framesPerPeriod();
|
||||
|
||||
if( m_muted == false )
|
||||
{
|
||||
for( FxRoute * senderRoute : m_receives )
|
||||
for( MixerRoute * senderRoute : m_receives )
|
||||
{
|
||||
FxChannel * sender = senderRoute->sender();
|
||||
MixerChannel * sender = senderRoute->sender();
|
||||
FloatModel * sendModel = senderRoute->amount();
|
||||
if( ! sendModel ) qFatal( "Error: no send model found from %d to %d", senderRoute->senderIndex(), m_channelIndex );
|
||||
|
||||
@@ -188,10 +188,10 @@ void FxChannel::doProcessing()
|
||||
|
||||
|
||||
|
||||
FxMixer::FxMixer() :
|
||||
Mixer::Mixer() :
|
||||
Model( nullptr ),
|
||||
JournallingObject(),
|
||||
m_fxChannels()
|
||||
m_mixerChannels()
|
||||
{
|
||||
// create master channel
|
||||
createChannel();
|
||||
@@ -200,27 +200,27 @@ FxMixer::FxMixer() :
|
||||
|
||||
|
||||
|
||||
FxMixer::~FxMixer()
|
||||
Mixer::~Mixer()
|
||||
{
|
||||
while( ! m_fxRoutes.isEmpty() )
|
||||
while( ! m_mixerRoutes.isEmpty() )
|
||||
{
|
||||
deleteChannelSend( m_fxRoutes.first() );
|
||||
deleteChannelSend( m_mixerRoutes.first() );
|
||||
}
|
||||
while( m_fxChannels.size() )
|
||||
while( m_mixerChannels.size() )
|
||||
{
|
||||
FxChannel * f = m_fxChannels[m_fxChannels.size() - 1];
|
||||
m_fxChannels.pop_back();
|
||||
MixerChannel * f = m_mixerChannels[m_mixerChannels.size() - 1];
|
||||
m_mixerChannels.pop_back();
|
||||
delete f;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
int FxMixer::createChannel()
|
||||
int Mixer::createChannel()
|
||||
{
|
||||
const int index = m_fxChannels.size();
|
||||
const int index = m_mixerChannels.size();
|
||||
// create new channel
|
||||
m_fxChannels.push_back( new FxChannel( index, this ) );
|
||||
m_mixerChannels.push_back( new MixerChannel( index, this ) );
|
||||
|
||||
// reset channel state
|
||||
clearChannel( index );
|
||||
@@ -228,36 +228,36 @@ int FxMixer::createChannel()
|
||||
return index;
|
||||
}
|
||||
|
||||
void FxMixer::activateSolo()
|
||||
void Mixer::activateSolo()
|
||||
{
|
||||
for (int i = 1; i < m_fxChannels.size(); ++i)
|
||||
for (int i = 1; i < m_mixerChannels.size(); ++i)
|
||||
{
|
||||
m_fxChannels[i]->m_muteBeforeSolo = m_fxChannels[i]->m_muteModel.value();
|
||||
m_fxChannels[i]->m_muteModel.setValue( true );
|
||||
m_mixerChannels[i]->m_muteBeforeSolo = m_mixerChannels[i]->m_muteModel.value();
|
||||
m_mixerChannels[i]->m_muteModel.setValue( true );
|
||||
}
|
||||
}
|
||||
|
||||
void FxMixer::deactivateSolo()
|
||||
void Mixer::deactivateSolo()
|
||||
{
|
||||
for (int i = 1; i < m_fxChannels.size(); ++i)
|
||||
for (int i = 1; i < m_mixerChannels.size(); ++i)
|
||||
{
|
||||
m_fxChannels[i]->m_muteModel.setValue( m_fxChannels[i]->m_muteBeforeSolo );
|
||||
m_mixerChannels[i]->m_muteModel.setValue( m_mixerChannels[i]->m_muteBeforeSolo );
|
||||
}
|
||||
}
|
||||
|
||||
void FxMixer::toggledSolo()
|
||||
void Mixer::toggledSolo()
|
||||
{
|
||||
int soloedChan = -1;
|
||||
bool resetSolo = m_lastSoloed != -1;
|
||||
//untoggle if lastsoloed is entered
|
||||
if (resetSolo)
|
||||
{
|
||||
m_fxChannels[m_lastSoloed]->m_soloModel.setValue( false );
|
||||
m_mixerChannels[m_lastSoloed]->m_soloModel.setValue( false );
|
||||
}
|
||||
//determine the soloed channel
|
||||
for (int i = 0; i < m_fxChannels.size(); ++i)
|
||||
for (int i = 0; i < m_mixerChannels.size(); ++i)
|
||||
{
|
||||
if (m_fxChannels[i]->m_soloModel.value() == true)
|
||||
if (m_mixerChannels[i]->m_soloModel.value() == true)
|
||||
soloedChan = i;
|
||||
}
|
||||
// if no channel is soloed, unmute everything, else mute everything
|
||||
@@ -271,7 +271,7 @@ void FxMixer::toggledSolo()
|
||||
activateSolo();
|
||||
}
|
||||
// unmute the soloed chan and every channel it sends to
|
||||
m_fxChannels[soloedChan]->unmuteForSolo();
|
||||
m_mixerChannels[soloedChan]->unmuteForSolo();
|
||||
} else {
|
||||
deactivateSolo();
|
||||
}
|
||||
@@ -280,7 +280,7 @@ void FxMixer::toggledSolo()
|
||||
|
||||
|
||||
|
||||
void FxMixer::deleteChannel( int index )
|
||||
void Mixer::deleteChannel( int index )
|
||||
{
|
||||
// channel deletion is performed between mixer rounds
|
||||
Engine::audioEngine()->requestChangeInModel();
|
||||
@@ -295,38 +295,38 @@ void FxMixer::deleteChannel( int index )
|
||||
if( t->type() == Track::InstrumentTrack )
|
||||
{
|
||||
InstrumentTrack* inst = dynamic_cast<InstrumentTrack *>( t );
|
||||
int val = inst->effectChannelModel()->value(0);
|
||||
int val = inst->mixerChannelModel()->value(0);
|
||||
if( val == index )
|
||||
{
|
||||
// we are deleting this track's fx send
|
||||
// we are deleting this track's channel send
|
||||
// send to master
|
||||
inst->effectChannelModel()->setValue(0);
|
||||
inst->mixerChannelModel()->setValue(0);
|
||||
}
|
||||
else if( val > index )
|
||||
{
|
||||
// subtract 1 to make up for the missing channel
|
||||
inst->effectChannelModel()->setValue(val-1);
|
||||
inst->mixerChannelModel()->setValue(val-1);
|
||||
}
|
||||
}
|
||||
else if( t->type() == Track::SampleTrack )
|
||||
{
|
||||
SampleTrack* strk = dynamic_cast<SampleTrack *>( t );
|
||||
int val = strk->effectChannelModel()->value(0);
|
||||
int val = strk->mixerChannelModel()->value(0);
|
||||
if( val == index )
|
||||
{
|
||||
// we are deleting this track's fx send
|
||||
// we are deleting this track's channel send
|
||||
// send to master
|
||||
strk->effectChannelModel()->setValue(0);
|
||||
strk->mixerChannelModel()->setValue(0);
|
||||
}
|
||||
else if( val > index )
|
||||
{
|
||||
// subtract 1 to make up for the missing channel
|
||||
strk->effectChannelModel()->setValue(val-1);
|
||||
strk->mixerChannelModel()->setValue(val-1);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
FxChannel * ch = m_fxChannels[index];
|
||||
MixerChannel * ch = m_mixerChannels[index];
|
||||
|
||||
// delete all of this channel's sends and receives
|
||||
while( ! ch->m_sends.isEmpty() )
|
||||
@@ -344,22 +344,22 @@ void FxMixer::deleteChannel( int index )
|
||||
else if (m_lastSoloed > index) { --m_lastSoloed; }
|
||||
|
||||
// actually delete the channel
|
||||
m_fxChannels.remove(index);
|
||||
m_mixerChannels.remove(index);
|
||||
delete ch;
|
||||
|
||||
for( int i = index; i < m_fxChannels.size(); ++i )
|
||||
for( int i = index; i < m_mixerChannels.size(); ++i )
|
||||
{
|
||||
validateChannelName( i, i + 1 );
|
||||
|
||||
// set correct channel index
|
||||
m_fxChannels[i]->m_channelIndex = i;
|
||||
m_mixerChannels[i]->m_channelIndex = i;
|
||||
|
||||
// now check all routes and update names of the send models
|
||||
for( FxRoute * r : m_fxChannels[i]->m_sends )
|
||||
for( MixerRoute * r : m_mixerChannels[i]->m_sends )
|
||||
{
|
||||
r->updateName();
|
||||
}
|
||||
for( FxRoute * r : m_fxChannels[i]->m_receives )
|
||||
for( MixerRoute * r : m_mixerChannels[i]->m_receives )
|
||||
{
|
||||
r->updateName();
|
||||
}
|
||||
@@ -370,10 +370,10 @@ void FxMixer::deleteChannel( int index )
|
||||
|
||||
|
||||
|
||||
void FxMixer::moveChannelLeft( int index )
|
||||
void Mixer::moveChannelLeft( int index )
|
||||
{
|
||||
// can't move master or first channel
|
||||
if( index <= 1 || index >= m_fxChannels.size() )
|
||||
if( index <= 1 || index >= m_mixerChannels.size() )
|
||||
{
|
||||
return;
|
||||
}
|
||||
@@ -397,56 +397,56 @@ void FxMixer::moveChannelLeft( int index )
|
||||
if( trackList[i]->type() == Track::InstrumentTrack )
|
||||
{
|
||||
InstrumentTrack * inst = (InstrumentTrack *) trackList[i];
|
||||
int val = inst->effectChannelModel()->value(0);
|
||||
int val = inst->mixerChannelModel()->value(0);
|
||||
if( val == a )
|
||||
{
|
||||
inst->effectChannelModel()->setValue(b);
|
||||
inst->mixerChannelModel()->setValue(b);
|
||||
}
|
||||
else if( val == b )
|
||||
{
|
||||
inst->effectChannelModel()->setValue(a);
|
||||
inst->mixerChannelModel()->setValue(a);
|
||||
}
|
||||
}
|
||||
else if( trackList[i]->type() == Track::SampleTrack )
|
||||
{
|
||||
SampleTrack * strk = (SampleTrack *) trackList[i];
|
||||
int val = strk->effectChannelModel()->value(0);
|
||||
int val = strk->mixerChannelModel()->value(0);
|
||||
if( val == a )
|
||||
{
|
||||
strk->effectChannelModel()->setValue(b);
|
||||
strk->mixerChannelModel()->setValue(b);
|
||||
}
|
||||
else if( val == b )
|
||||
{
|
||||
strk->effectChannelModel()->setValue(a);
|
||||
strk->mixerChannelModel()->setValue(a);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Swap positions in array
|
||||
qSwap(m_fxChannels[index], m_fxChannels[index - 1]);
|
||||
qSwap(m_mixerChannels[index], m_mixerChannels[index - 1]);
|
||||
|
||||
// Update m_channelIndex of both channels
|
||||
m_fxChannels[index]->m_channelIndex = index;
|
||||
m_fxChannels[index - 1]->m_channelIndex = index -1;
|
||||
m_mixerChannels[index]->m_channelIndex = index;
|
||||
m_mixerChannels[index - 1]->m_channelIndex = index -1;
|
||||
}
|
||||
|
||||
|
||||
|
||||
void FxMixer::moveChannelRight( int index )
|
||||
void Mixer::moveChannelRight( int index )
|
||||
{
|
||||
moveChannelLeft( index + 1 );
|
||||
}
|
||||
|
||||
|
||||
|
||||
FxRoute * FxMixer::createChannelSend( fx_ch_t fromChannel, fx_ch_t toChannel,
|
||||
MixerRoute * Mixer::createChannelSend( mix_ch_t fromChannel, mix_ch_t toChannel,
|
||||
float amount )
|
||||
{
|
||||
// qDebug( "requested: %d to %d", fromChannel, toChannel );
|
||||
// find the existing connection
|
||||
FxChannel * from = m_fxChannels[fromChannel];
|
||||
FxChannel * to = m_fxChannels[toChannel];
|
||||
MixerChannel * from = m_mixerChannels[fromChannel];
|
||||
MixerChannel * to = m_mixerChannels[toChannel];
|
||||
|
||||
for( int i=0; i<from->m_sends.size(); ++i )
|
||||
{
|
||||
@@ -463,14 +463,14 @@ FxRoute * FxMixer::createChannelSend( fx_ch_t fromChannel, fx_ch_t toChannel,
|
||||
}
|
||||
|
||||
|
||||
FxRoute * FxMixer::createRoute( FxChannel * from, FxChannel * to, float amount )
|
||||
MixerRoute * Mixer::createRoute( MixerChannel * from, MixerChannel * to, float amount )
|
||||
{
|
||||
if( from == to )
|
||||
{
|
||||
return nullptr;
|
||||
}
|
||||
Engine::audioEngine()->requestChangeInModel();
|
||||
FxRoute * route = new FxRoute( from, to, amount );
|
||||
MixerRoute * route = new MixerRoute( from, to, amount );
|
||||
|
||||
// add us to from's sends
|
||||
from->m_sends.append( route );
|
||||
@@ -478,8 +478,8 @@ FxRoute * FxMixer::createRoute( FxChannel * from, FxChannel * to, float amount )
|
||||
// add us to to's receives
|
||||
to->m_receives.append( route );
|
||||
|
||||
// add us to fxmixer's list
|
||||
Engine::fxMixer()->m_fxRoutes.append( route );
|
||||
// add us to mixer's list
|
||||
Engine::mixer()->m_mixerRoutes.append( route );
|
||||
Engine::audioEngine()->doneChangeInModel();
|
||||
|
||||
return route;
|
||||
@@ -487,11 +487,11 @@ FxRoute * FxMixer::createRoute( FxChannel * from, FxChannel * to, float amount )
|
||||
|
||||
|
||||
// delete the connection made by createChannelSend
|
||||
void FxMixer::deleteChannelSend( fx_ch_t fromChannel, fx_ch_t toChannel )
|
||||
void Mixer::deleteChannelSend( mix_ch_t fromChannel, mix_ch_t toChannel )
|
||||
{
|
||||
// delete the send
|
||||
FxChannel * from = m_fxChannels[fromChannel];
|
||||
FxChannel * to = m_fxChannels[toChannel];
|
||||
MixerChannel * from = m_mixerChannels[fromChannel];
|
||||
MixerChannel * to = m_mixerChannels[toChannel];
|
||||
|
||||
// find and delete the send entry
|
||||
for( int i = 0; i < from->m_sends.size(); ++i )
|
||||
@@ -505,34 +505,34 @@ void FxMixer::deleteChannelSend( fx_ch_t fromChannel, fx_ch_t toChannel )
|
||||
}
|
||||
|
||||
|
||||
void FxMixer::deleteChannelSend( FxRoute * route )
|
||||
void Mixer::deleteChannelSend( MixerRoute * route )
|
||||
{
|
||||
Engine::audioEngine()->requestChangeInModel();
|
||||
// remove us from from's sends
|
||||
route->sender()->m_sends.remove( route->sender()->m_sends.indexOf( route ) );
|
||||
// remove us from to's receives
|
||||
route->receiver()->m_receives.remove( route->receiver()->m_receives.indexOf( route ) );
|
||||
// remove us from fxmixer's list
|
||||
Engine::fxMixer()->m_fxRoutes.remove( Engine::fxMixer()->m_fxRoutes.indexOf( route ) );
|
||||
// remove us from mixer's list
|
||||
Engine::mixer()->m_mixerRoutes.remove( Engine::mixer()->m_mixerRoutes.indexOf( route ) );
|
||||
delete route;
|
||||
Engine::audioEngine()->doneChangeInModel();
|
||||
}
|
||||
|
||||
|
||||
bool FxMixer::isInfiniteLoop( fx_ch_t sendFrom, fx_ch_t sendTo )
|
||||
bool Mixer::isInfiniteLoop( mix_ch_t sendFrom, mix_ch_t sendTo )
|
||||
{
|
||||
if( sendFrom == sendTo ) return true;
|
||||
FxChannel * from = m_fxChannels[sendFrom];
|
||||
FxChannel * to = m_fxChannels[sendTo];
|
||||
MixerChannel * from = m_mixerChannels[sendFrom];
|
||||
MixerChannel * to = m_mixerChannels[sendTo];
|
||||
bool b = checkInfiniteLoop( from, to );
|
||||
return b;
|
||||
}
|
||||
|
||||
|
||||
bool FxMixer::checkInfiniteLoop( FxChannel * from, FxChannel * to )
|
||||
bool Mixer::checkInfiniteLoop( MixerChannel * from, MixerChannel * to )
|
||||
{
|
||||
// can't send master to anything
|
||||
if( from == m_fxChannels[0] )
|
||||
if( from == m_mixerChannels[0] )
|
||||
{
|
||||
return true;
|
||||
}
|
||||
@@ -558,16 +558,16 @@ bool FxMixer::checkInfiniteLoop( FxChannel * from, FxChannel * to )
|
||||
|
||||
|
||||
// how much does fromChannel send its output to the input of toChannel?
|
||||
FloatModel * FxMixer::channelSendModel( fx_ch_t fromChannel, fx_ch_t toChannel )
|
||||
FloatModel * Mixer::channelSendModel( mix_ch_t fromChannel, mix_ch_t toChannel )
|
||||
{
|
||||
if( fromChannel == toChannel )
|
||||
{
|
||||
return nullptr;
|
||||
}
|
||||
const FxChannel * from = m_fxChannels[fromChannel];
|
||||
const FxChannel * to = m_fxChannels[toChannel];
|
||||
const MixerChannel * from = m_mixerChannels[fromChannel];
|
||||
const MixerChannel * to = m_mixerChannels[toChannel];
|
||||
|
||||
for( FxRoute * route : from->m_sends )
|
||||
for( MixerRoute * route : from->m_sends )
|
||||
{
|
||||
if( route->receiver() == to )
|
||||
{
|
||||
@@ -580,29 +580,29 @@ FloatModel * FxMixer::channelSendModel( fx_ch_t fromChannel, fx_ch_t toChannel )
|
||||
|
||||
|
||||
|
||||
void FxMixer::mixToChannel( const sampleFrame * _buf, fx_ch_t _ch )
|
||||
void Mixer::mixToChannel( const sampleFrame * _buf, mix_ch_t _ch )
|
||||
{
|
||||
if( m_fxChannels[_ch]->m_muteModel.value() == false )
|
||||
if( m_mixerChannels[_ch]->m_muteModel.value() == false )
|
||||
{
|
||||
m_fxChannels[_ch]->m_lock.lock();
|
||||
MixHelpers::add( m_fxChannels[_ch]->m_buffer, _buf, Engine::audioEngine()->framesPerPeriod() );
|
||||
m_fxChannels[_ch]->m_hasInput = true;
|
||||
m_fxChannels[_ch]->m_lock.unlock();
|
||||
m_mixerChannels[_ch]->m_lock.lock();
|
||||
MixHelpers::add( m_mixerChannels[_ch]->m_buffer, _buf, Engine::audioEngine()->framesPerPeriod() );
|
||||
m_mixerChannels[_ch]->m_hasInput = true;
|
||||
m_mixerChannels[_ch]->m_lock.unlock();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
void FxMixer::prepareMasterMix()
|
||||
void Mixer::prepareMasterMix()
|
||||
{
|
||||
BufferManager::clear( m_fxChannels[0]->m_buffer,
|
||||
BufferManager::clear( m_mixerChannels[0]->m_buffer,
|
||||
Engine::audioEngine()->framesPerPeriod() );
|
||||
}
|
||||
|
||||
|
||||
|
||||
void FxMixer::masterMix( sampleFrame * _buf )
|
||||
void Mixer::masterMix( sampleFrame * _buf )
|
||||
{
|
||||
const int fpp = Engine::audioEngine()->framesPerPeriod();
|
||||
|
||||
@@ -614,7 +614,7 @@ void FxMixer::masterMix( sampleFrame * _buf )
|
||||
// about their senders, and can just increment the deps of their
|
||||
// recipients right away.
|
||||
AudioEngineWorkerThread::resetJobQueue( AudioEngineWorkerThread::JobQueue::Dynamic );
|
||||
for( FxChannel * ch : m_fxChannels )
|
||||
for( MixerChannel * ch : m_mixerChannels )
|
||||
{
|
||||
ch->m_muted = ch->m_muteModel.value();
|
||||
if( ch->m_muted ) // instantly "process" muted channels
|
||||
@@ -628,10 +628,10 @@ void FxMixer::masterMix( sampleFrame * _buf )
|
||||
AudioEngineWorkerThread::addJob( ch );
|
||||
}
|
||||
}
|
||||
while (m_fxChannels[0]->state() != ThreadableJob::ProcessingState::Done)
|
||||
while (m_mixerChannels[0]->state() != ThreadableJob::ProcessingState::Done)
|
||||
{
|
||||
bool found = false;
|
||||
for( FxChannel * ch : m_fxChannels )
|
||||
for( MixerChannel * ch : m_mixerChannels )
|
||||
{
|
||||
const auto s = ch->state();
|
||||
if (s == ThreadableJob::ProcessingState::Queued
|
||||
@@ -649,42 +649,42 @@ void FxMixer::masterMix( sampleFrame * _buf )
|
||||
}
|
||||
|
||||
// handle sample-exact data in master volume fader
|
||||
ValueBuffer * volBuf = m_fxChannels[0]->m_volumeModel.valueBuffer();
|
||||
ValueBuffer * volBuf = m_mixerChannels[0]->m_volumeModel.valueBuffer();
|
||||
|
||||
if( volBuf )
|
||||
{
|
||||
for( int f = 0; f < fpp; f++ )
|
||||
{
|
||||
m_fxChannels[0]->m_buffer[f][0] *= volBuf->values()[f];
|
||||
m_fxChannels[0]->m_buffer[f][1] *= volBuf->values()[f];
|
||||
m_mixerChannels[0]->m_buffer[f][0] *= volBuf->values()[f];
|
||||
m_mixerChannels[0]->m_buffer[f][1] *= volBuf->values()[f];
|
||||
}
|
||||
}
|
||||
|
||||
const float v = volBuf
|
||||
? 1.0f
|
||||
: m_fxChannels[0]->m_volumeModel.value();
|
||||
MixHelpers::addSanitizedMultiplied( _buf, m_fxChannels[0]->m_buffer, v, fpp );
|
||||
: m_mixerChannels[0]->m_volumeModel.value();
|
||||
MixHelpers::addSanitizedMultiplied( _buf, m_mixerChannels[0]->m_buffer, v, fpp );
|
||||
|
||||
// clear all channel buffers and
|
||||
// reset channel process state
|
||||
for( int i = 0; i < numChannels(); ++i)
|
||||
{
|
||||
BufferManager::clear( m_fxChannels[i]->m_buffer,
|
||||
BufferManager::clear( m_mixerChannels[i]->m_buffer,
|
||||
Engine::audioEngine()->framesPerPeriod() );
|
||||
m_fxChannels[i]->reset();
|
||||
m_fxChannels[i]->m_queued = false;
|
||||
m_mixerChannels[i]->reset();
|
||||
m_mixerChannels[i]->m_queued = false;
|
||||
// also reset hasInput
|
||||
m_fxChannels[i]->m_hasInput = false;
|
||||
m_fxChannels[i]->m_dependenciesMet = 0;
|
||||
m_mixerChannels[i]->m_hasInput = false;
|
||||
m_mixerChannels[i]->m_dependenciesMet = 0;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
void FxMixer::clear()
|
||||
void Mixer::clear()
|
||||
{
|
||||
while( m_fxChannels.size() > 1 )
|
||||
while( m_mixerChannels.size() > 1 )
|
||||
{
|
||||
deleteChannel(1);
|
||||
}
|
||||
@@ -694,14 +694,14 @@ void FxMixer::clear()
|
||||
|
||||
|
||||
|
||||
void FxMixer::clearChannel(fx_ch_t index)
|
||||
void Mixer::clearChannel(mix_ch_t index)
|
||||
{
|
||||
FxChannel * ch = m_fxChannels[index];
|
||||
MixerChannel * ch = m_mixerChannels[index];
|
||||
ch->m_fxChain.clear();
|
||||
ch->m_volumeModel.setValue( 1.0f );
|
||||
ch->m_muteModel.setValue( false );
|
||||
ch->m_soloModel.setValue( false );
|
||||
ch->m_name = ( index == 0 ) ? tr( "Master" ) : tr( "FX %1" ).arg( index );
|
||||
ch->m_name = ( index == 0 ) ? tr( "Master" ) : tr( "Channel %1" ).arg( index );
|
||||
ch->m_volumeModel.setDisplayName( ch->m_name + ">" + tr( "Volume" ) );
|
||||
ch->m_muteModel.setDisplayName( ch->m_name + ">" + tr( "Mute" ) );
|
||||
ch->m_soloModel.setDisplayName( ch->m_name + ">" + tr( "Solo" ) );
|
||||
@@ -726,29 +726,29 @@ void FxMixer::clearChannel(fx_ch_t index)
|
||||
}
|
||||
}
|
||||
|
||||
void FxMixer::saveSettings( QDomDocument & _doc, QDomElement & _this )
|
||||
void Mixer::saveSettings( QDomDocument & _doc, QDomElement & _this )
|
||||
{
|
||||
// save channels
|
||||
for( int i = 0; i < m_fxChannels.size(); ++i )
|
||||
for( int i = 0; i < m_mixerChannels.size(); ++i )
|
||||
{
|
||||
FxChannel * ch = m_fxChannels[i];
|
||||
MixerChannel * ch = m_mixerChannels[i];
|
||||
|
||||
QDomElement fxch = _doc.createElement( QString( "fxchannel" ) );
|
||||
_this.appendChild( fxch );
|
||||
QDomElement mixch = _doc.createElement( QString( "mixerchannel" ) );
|
||||
_this.appendChild( mixch );
|
||||
|
||||
ch->m_fxChain.saveState( _doc, fxch );
|
||||
ch->m_volumeModel.saveSettings( _doc, fxch, "volume" );
|
||||
ch->m_muteModel.saveSettings( _doc, fxch, "muted" );
|
||||
ch->m_soloModel.saveSettings( _doc, fxch, "soloed" );
|
||||
fxch.setAttribute( "num", i );
|
||||
fxch.setAttribute( "name", ch->m_name );
|
||||
if( ch->m_hasColor ) fxch.setAttribute( "color", ch->m_color.name() );
|
||||
ch->m_fxChain.saveState( _doc, mixch );
|
||||
ch->m_volumeModel.saveSettings( _doc, mixch, "volume" );
|
||||
ch->m_muteModel.saveSettings( _doc, mixch, "muted" );
|
||||
ch->m_soloModel.saveSettings( _doc, mixch, "soloed" );
|
||||
mixch.setAttribute( "num", i );
|
||||
mixch.setAttribute( "name", ch->m_name );
|
||||
if( ch->m_hasColor ) mixch.setAttribute( "color", ch->m_color.name() );
|
||||
|
||||
// add the channel sends
|
||||
for( int si = 0; si < ch->m_sends.size(); ++si )
|
||||
{
|
||||
QDomElement sendsDom = _doc.createElement( QString( "send" ) );
|
||||
fxch.appendChild( sendsDom );
|
||||
mixch.appendChild( sendsDom );
|
||||
|
||||
sendsDom.setAttribute( "channel", ch->m_sends[si]->receiverIndex() );
|
||||
ch->m_sends[si]->amount()->saveSettings( _doc, sendsDom, "amount" );
|
||||
@@ -757,48 +757,48 @@ void FxMixer::saveSettings( QDomDocument & _doc, QDomElement & _this )
|
||||
}
|
||||
|
||||
// make sure we have at least num channels
|
||||
void FxMixer::allocateChannelsTo(int num)
|
||||
void Mixer::allocateChannelsTo(int num)
|
||||
{
|
||||
while( num > m_fxChannels.size() - 1 )
|
||||
while( num > m_mixerChannels.size() - 1 )
|
||||
{
|
||||
createChannel();
|
||||
|
||||
// delete the default send to master
|
||||
deleteChannelSend( m_fxChannels.size()-1, 0 );
|
||||
deleteChannelSend( m_mixerChannels.size()-1, 0 );
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void FxMixer::loadSettings( const QDomElement & _this )
|
||||
void Mixer::loadSettings( const QDomElement & _this )
|
||||
{
|
||||
clear();
|
||||
QDomNode node = _this.firstChild();
|
||||
|
||||
while( ! node.isNull() )
|
||||
{
|
||||
QDomElement fxch = node.toElement();
|
||||
QDomElement mixch = node.toElement();
|
||||
|
||||
// index of the channel we are about to load
|
||||
int num = fxch.attribute( "num" ).toInt();
|
||||
int num = mixch.attribute( "num" ).toInt();
|
||||
|
||||
// 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_soloModel.loadSettings( fxch, "soloed" );
|
||||
m_fxChannels[num]->m_name = fxch.attribute( "name" );
|
||||
if( fxch.hasAttribute( "color" ) )
|
||||
m_mixerChannels[num]->m_volumeModel.loadSettings( mixch, "volume" );
|
||||
m_mixerChannels[num]->m_muteModel.loadSettings( mixch, "muted" );
|
||||
m_mixerChannels[num]->m_soloModel.loadSettings( mixch, "soloed" );
|
||||
m_mixerChannels[num]->m_name = mixch.attribute( "name" );
|
||||
if( mixch.hasAttribute( "color" ) )
|
||||
{
|
||||
m_fxChannels[num]->m_hasColor = true;
|
||||
m_fxChannels[num]->m_color.setNamedColor( fxch.attribute( "color" ) );
|
||||
m_mixerChannels[num]->m_hasColor = true;
|
||||
m_mixerChannels[num]->m_color.setNamedColor( mixch.attribute( "color" ) );
|
||||
}
|
||||
|
||||
m_fxChannels[num]->m_fxChain.restoreState( fxch.firstChildElement(
|
||||
m_fxChannels[num]->m_fxChain.nodeName() ) );
|
||||
m_mixerChannels[num]->m_fxChain.restoreState( mixch.firstChildElement(
|
||||
m_mixerChannels[num]->m_fxChain.nodeName() ) );
|
||||
|
||||
// mixer sends
|
||||
QDomNodeList chData = fxch.childNodes();
|
||||
QDomNodeList chData = mixch.childNodes();
|
||||
for( unsigned int i=0; i<chData.length(); ++i )
|
||||
{
|
||||
QDomElement chDataItem = chData.at(i).toElement();
|
||||
@@ -806,8 +806,8 @@ void FxMixer::loadSettings( const QDomElement & _this )
|
||||
{
|
||||
int sendTo = chDataItem.attribute( "channel" ).toInt();
|
||||
allocateChannelsTo( sendTo ) ;
|
||||
FxRoute * fxr = createChannelSend( num, sendTo, 1.0f );
|
||||
if( fxr ) fxr->amount()->loadSettings( chDataItem, "amount" );
|
||||
MixerRoute * mxr = createChannelSend( num, sendTo, 1.0f );
|
||||
if( mxr ) mxr->amount()->loadSettings( chDataItem, "amount" );
|
||||
}
|
||||
}
|
||||
|
||||
@@ -820,10 +820,10 @@ void FxMixer::loadSettings( const QDomElement & _this )
|
||||
}
|
||||
|
||||
|
||||
void FxMixer::validateChannelName( int index, int oldIndex )
|
||||
void Mixer::validateChannelName( int index, int oldIndex )
|
||||
{
|
||||
if( m_fxChannels[index]->m_name == tr( "FX %1" ).arg( oldIndex ) )
|
||||
if( m_mixerChannels[index]->m_name == tr( "Channel %1" ).arg( oldIndex ) )
|
||||
{
|
||||
m_fxChannels[index]->m_name = tr( "FX %1" ).arg( index );
|
||||
m_mixerChannels[index]->m_name = tr( "Channel %1" ).arg( index );
|
||||
}
|
||||
}
|
||||
@@ -211,9 +211,9 @@ void Note::createDetuning()
|
||||
if( m_detuning == nullptr )
|
||||
{
|
||||
m_detuning = new DetuningHelper;
|
||||
(void) m_detuning->automationPattern();
|
||||
(void) m_detuning->automationClip();
|
||||
m_detuning->setRange( -MaxDetuning, MaxDetuning, 0.5f );
|
||||
m_detuning->automationPattern()->setProgressionType( AutomationPattern::LinearProgression );
|
||||
m_detuning->automationClip()->setProgressionType( AutomationClip::LinearProgression );
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -35,7 +35,7 @@
|
||||
#include "Song.h"
|
||||
|
||||
NotePlayHandle::BaseDetuning::BaseDetuning( DetuningHelper *detuning ) :
|
||||
m_value( detuning ? detuning->automationPattern()->valueAt( 0 ) : 0 )
|
||||
m_value( detuning ? detuning->automationClip()->valueAt( 0 ) : 0 )
|
||||
{
|
||||
}
|
||||
|
||||
@@ -559,7 +559,7 @@ void NotePlayHandle::processTimePos( const TimePos& time )
|
||||
{
|
||||
if( detuning() && time >= songGlobalParentOffset()+pos() )
|
||||
{
|
||||
const float v = detuning()->automationPattern()->valueAt( time - songGlobalParentOffset() - pos() );
|
||||
const float v = detuning()->automationClip()->valueAt( time - songGlobalParentOffset() - pos() );
|
||||
if( !typeInfo<float>::isEqual( v, m_baseDetuning->value() ) )
|
||||
{
|
||||
m_baseDetuning->setValue( v );
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* SampleTCO.cpp
|
||||
* SampleClip.cpp
|
||||
*
|
||||
* Copyright (c) 2005-2014 Tobias Doerffel <tobydox/at/users.sourceforge.net>
|
||||
*
|
||||
@@ -22,15 +22,15 @@
|
||||
*
|
||||
*/
|
||||
|
||||
#include "SampleTCO.h"
|
||||
#include "SampleClip.h"
|
||||
|
||||
#include <QDomElement>
|
||||
|
||||
#include "SampleTCOView.h"
|
||||
#include "SampleClipView.h"
|
||||
#include "TimeLineWidget.h"
|
||||
|
||||
SampleTCO::SampleTCO( Track * _track ) :
|
||||
TrackContentObject( _track ),
|
||||
SampleClip::SampleClip( Track * _track ) :
|
||||
Clip( _track ),
|
||||
m_sampleBuffer( new SampleBuffer ),
|
||||
m_isPlaying( false )
|
||||
{
|
||||
@@ -39,7 +39,7 @@ SampleTCO::SampleTCO( Track * _track ) :
|
||||
restoreJournallingState();
|
||||
|
||||
// we need to receive bpm-change-events, because then we have to
|
||||
// change length of this TCO
|
||||
// change length of this Clip
|
||||
connect( Engine::getSong(), SIGNAL( tempoChanged( bpm_t ) ),
|
||||
this, SLOT( updateLength() ), Qt::DirectConnection );
|
||||
connect( Engine::getSong(), SIGNAL( timeSignatureChanged( int,int ) ),
|
||||
@@ -57,13 +57,13 @@ SampleTCO::SampleTCO( Track * _track ) :
|
||||
//care about loops
|
||||
connect( Engine::getSong(), SIGNAL( updateSampleTracks() ),
|
||||
this, SLOT( playbackPositionChanged() ), Qt::DirectConnection );
|
||||
//care about mute TCOs
|
||||
//care about mute Clips
|
||||
connect( this, SIGNAL( dataChanged() ), this, SLOT( playbackPositionChanged() ) );
|
||||
//care about mute track
|
||||
connect( getTrack()->getMutedModel(), SIGNAL( dataChanged() ),
|
||||
this, SLOT( playbackPositionChanged() ), Qt::DirectConnection );
|
||||
//care about TCO position
|
||||
connect( this, SIGNAL( positionChanged() ), this, SLOT( updateTrackTcos() ) );
|
||||
//care about Clip position
|
||||
connect( this, SIGNAL( positionChanged() ), this, SLOT( updateTrackClips() ) );
|
||||
|
||||
switch( getTrack()->trackContainer()->type() )
|
||||
{
|
||||
@@ -77,13 +77,13 @@ SampleTCO::SampleTCO( Track * _track ) :
|
||||
setAutoResize( false );
|
||||
break;
|
||||
}
|
||||
updateTrackTcos();
|
||||
updateTrackClips();
|
||||
}
|
||||
|
||||
SampleTCO::SampleTCO(const SampleTCO& orig) :
|
||||
SampleTCO(orig.getTrack())
|
||||
SampleClip::SampleClip(const SampleClip& orig) :
|
||||
SampleClip(orig.getTrack())
|
||||
{
|
||||
// TODO: This creates a new SampleBuffer for the new TCO, eating up memory
|
||||
// TODO: This creates a new SampleBuffer for the new Clip, eating up memory
|
||||
// & eventually causing performance issues. Letting tracks share buffers
|
||||
// when they're identical would fix this, but isn't possible right now.
|
||||
*m_sampleBuffer = *orig.m_sampleBuffer;
|
||||
@@ -93,12 +93,12 @@ SampleTCO::SampleTCO(const SampleTCO& orig) :
|
||||
|
||||
|
||||
|
||||
SampleTCO::~SampleTCO()
|
||||
SampleClip::~SampleClip()
|
||||
{
|
||||
SampleTrack * sampletrack = dynamic_cast<SampleTrack*>( getTrack() );
|
||||
if ( sampletrack )
|
||||
{
|
||||
sampletrack->updateTcos();
|
||||
sampletrack->updateClips();
|
||||
}
|
||||
Engine::audioEngine()->requestChangeInModel();
|
||||
sharedObject::unref( m_sampleBuffer );
|
||||
@@ -108,22 +108,22 @@ SampleTCO::~SampleTCO()
|
||||
|
||||
|
||||
|
||||
void SampleTCO::changeLength( const TimePos & _length )
|
||||
void SampleClip::changeLength( const TimePos & _length )
|
||||
{
|
||||
TrackContentObject::changeLength( qMax( static_cast<int>( _length ), 1 ) );
|
||||
Clip::changeLength( qMax( static_cast<int>( _length ), 1 ) );
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
const QString & SampleTCO::sampleFile() const
|
||||
const QString & SampleClip::sampleFile() const
|
||||
{
|
||||
return m_sampleBuffer->audioFile();
|
||||
}
|
||||
|
||||
|
||||
|
||||
void SampleTCO::setSampleBuffer( SampleBuffer* sb )
|
||||
void SampleClip::setSampleBuffer( SampleBuffer* sb )
|
||||
{
|
||||
Engine::audioEngine()->requestChangeInModel();
|
||||
sharedObject::unref( m_sampleBuffer );
|
||||
@@ -136,11 +136,11 @@ void SampleTCO::setSampleBuffer( SampleBuffer* sb )
|
||||
|
||||
|
||||
|
||||
void SampleTCO::setSampleFile( const QString & _sf )
|
||||
void SampleClip::setSampleFile( const QString & _sf )
|
||||
{
|
||||
int length;
|
||||
if ( _sf.isEmpty() )
|
||||
{ //When creating an empty sample pattern make it a bar long
|
||||
{ //When creating an empty sample clip make it a bar long
|
||||
float nom = Engine::getSong()->getTimeSigModel().getNumerator();
|
||||
float den = Engine::getSong()->getTimeSigModel().getDenominator();
|
||||
length = DefaultTicksPerBar * ( nom / den );
|
||||
@@ -161,7 +161,7 @@ void SampleTCO::setSampleFile( const QString & _sf )
|
||||
|
||||
|
||||
|
||||
void SampleTCO::toggleRecord()
|
||||
void SampleClip::toggleRecord()
|
||||
{
|
||||
m_recordModel.setValue( !m_recordModel.value() );
|
||||
emit dataChanged();
|
||||
@@ -170,29 +170,29 @@ void SampleTCO::toggleRecord()
|
||||
|
||||
|
||||
|
||||
void SampleTCO::playbackPositionChanged()
|
||||
void SampleClip::playbackPositionChanged()
|
||||
{
|
||||
Engine::audioEngine()->removePlayHandlesOfTypes( getTrack(), PlayHandle::TypeSamplePlayHandle );
|
||||
SampleTrack * st = dynamic_cast<SampleTrack*>( getTrack() );
|
||||
st->setPlayingTcos( false );
|
||||
st->setPlayingClips( false );
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
void SampleTCO::updateTrackTcos()
|
||||
void SampleClip::updateTrackClips()
|
||||
{
|
||||
SampleTrack * sampletrack = dynamic_cast<SampleTrack*>( getTrack() );
|
||||
if( sampletrack)
|
||||
{
|
||||
sampletrack->updateTcos();
|
||||
sampletrack->updateClips();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
bool SampleTCO::isPlaying() const
|
||||
bool SampleClip::isPlaying() const
|
||||
{
|
||||
return m_isPlaying;
|
||||
}
|
||||
@@ -200,7 +200,7 @@ bool SampleTCO::isPlaying() const
|
||||
|
||||
|
||||
|
||||
void SampleTCO::setIsPlaying(bool isPlaying)
|
||||
void SampleClip::setIsPlaying(bool isPlaying)
|
||||
{
|
||||
m_isPlaying = isPlaying;
|
||||
}
|
||||
@@ -208,7 +208,7 @@ void SampleTCO::setIsPlaying(bool isPlaying)
|
||||
|
||||
|
||||
|
||||
void SampleTCO::updateLength()
|
||||
void SampleClip::updateLength()
|
||||
{
|
||||
emit sampleChanged();
|
||||
}
|
||||
@@ -216,7 +216,7 @@ void SampleTCO::updateLength()
|
||||
|
||||
|
||||
|
||||
TimePos SampleTCO::sampleLength() const
|
||||
TimePos SampleClip::sampleLength() const
|
||||
{
|
||||
return (int)( m_sampleBuffer->frames() / Engine::framesPerTick() );
|
||||
}
|
||||
@@ -224,7 +224,7 @@ TimePos SampleTCO::sampleLength() const
|
||||
|
||||
|
||||
|
||||
void SampleTCO::setSampleStartFrame(f_cnt_t startFrame)
|
||||
void SampleClip::setSampleStartFrame(f_cnt_t startFrame)
|
||||
{
|
||||
m_sampleBuffer->setStartFrame( startFrame );
|
||||
}
|
||||
@@ -232,7 +232,7 @@ void SampleTCO::setSampleStartFrame(f_cnt_t startFrame)
|
||||
|
||||
|
||||
|
||||
void SampleTCO::setSamplePlayLength(f_cnt_t length)
|
||||
void SampleClip::setSamplePlayLength(f_cnt_t length)
|
||||
{
|
||||
m_sampleBuffer->setEndFrame( length );
|
||||
}
|
||||
@@ -240,7 +240,7 @@ void SampleTCO::setSamplePlayLength(f_cnt_t length)
|
||||
|
||||
|
||||
|
||||
void SampleTCO::saveSettings( QDomDocument & _doc, QDomElement & _this )
|
||||
void SampleClip::saveSettings( QDomDocument & _doc, QDomElement & _this )
|
||||
{
|
||||
if( _this.parentNode().nodeName() == "clipboard" )
|
||||
{
|
||||
@@ -275,7 +275,7 @@ void SampleTCO::saveSettings( QDomDocument & _doc, QDomElement & _this )
|
||||
|
||||
|
||||
|
||||
void SampleTCO::loadSettings( const QDomElement & _this )
|
||||
void SampleClip::loadSettings( const QDomElement & _this )
|
||||
{
|
||||
if( _this.attribute( "pos" ).toInt() >= 0 )
|
||||
{
|
||||
@@ -307,14 +307,14 @@ void SampleTCO::loadSettings( const QDomElement & _this )
|
||||
if(_this.hasAttribute("reversed"))
|
||||
{
|
||||
m_sampleBuffer->setReversed(true);
|
||||
emit wasReversed(); // tell SampleTCOView to update the view
|
||||
emit wasReversed(); // tell SampleClipView to update the view
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
TrackContentObjectView * SampleTCO::createView( TrackView * _tv )
|
||||
ClipView * SampleClip::createView( TrackView * _tv )
|
||||
{
|
||||
return new SampleTCOView( this, _tv );
|
||||
return new SampleClipView( this, _tv );
|
||||
}
|
||||
@@ -29,7 +29,7 @@
|
||||
#include "Engine.h"
|
||||
#include "InstrumentTrack.h"
|
||||
#include "lmms_constants.h"
|
||||
#include "SampleTCO.h"
|
||||
#include "SampleClip.h"
|
||||
|
||||
|
||||
|
||||
@@ -62,11 +62,11 @@ SamplePlayHandle::SamplePlayHandle( const QString& sampleFile ) :
|
||||
|
||||
|
||||
|
||||
SamplePlayHandle::SamplePlayHandle( SampleTCO* tco ) :
|
||||
SamplePlayHandle( tco->sampleBuffer() , false)
|
||||
SamplePlayHandle::SamplePlayHandle( SampleClip* clip ) :
|
||||
SamplePlayHandle( clip->sampleBuffer() , false)
|
||||
{
|
||||
m_track = tco->getTrack();
|
||||
setAudioPort( ( (SampleTrack *)tco->getTrack() )->audioPort() );
|
||||
m_track = clip->getTrack();
|
||||
setAudioPort( ( (SampleTrack *)clip->getTrack() )->audioPort() );
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -33,13 +33,13 @@
|
||||
#include "debug.h"
|
||||
|
||||
|
||||
SampleRecordHandle::SampleRecordHandle(SampleTCO* tco , TimePos startRecordTimeOffset) :
|
||||
SampleRecordHandle::SampleRecordHandle(SampleClip* clip , TimePos startRecordTimeOffset) :
|
||||
PlayHandle( TypeSamplePlayHandle ),
|
||||
m_framesRecorded( 0 ),
|
||||
m_minLength( tco->length() ),
|
||||
m_track( tco->getTrack() ),
|
||||
m_minLength( clip->length() ),
|
||||
m_track( clip->getTrack() ),
|
||||
m_bbTrack( nullptr ),
|
||||
m_tco(tco),
|
||||
m_clip(clip),
|
||||
m_startRecordTimeOffset{startRecordTimeOffset}
|
||||
{
|
||||
}
|
||||
@@ -53,9 +53,9 @@ SampleRecordHandle::~SampleRecordHandle()
|
||||
{
|
||||
SampleBuffer* sb;
|
||||
createSampleBuffer( &sb );
|
||||
m_tco->setSampleBuffer( sb );
|
||||
m_clip->setSampleBuffer( sb );
|
||||
|
||||
m_tco->setStartTimeOffset(m_startRecordTimeOffset);
|
||||
m_clip->setStartTimeOffset(m_startRecordTimeOffset);
|
||||
}
|
||||
|
||||
while( !m_buffers.empty() )
|
||||
@@ -63,7 +63,7 @@ SampleRecordHandle::~SampleRecordHandle()
|
||||
delete[] m_buffers.front().first;
|
||||
m_buffers.erase( m_buffers.begin() );
|
||||
}
|
||||
m_tco->setRecord( false );
|
||||
m_clip->setRecord( false );
|
||||
}
|
||||
|
||||
|
||||
@@ -79,7 +79,7 @@ void SampleRecordHandle::play( sampleFrame * /*_working_buffer*/ )
|
||||
TimePos len = (tick_t)( m_framesRecorded / Engine::framesPerTick() );
|
||||
if( len > m_minLength )
|
||||
{
|
||||
// m_tco->changeLength( len );
|
||||
// m_clip->changeLength( len );
|
||||
m_minLength = len;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -44,13 +44,13 @@
|
||||
#include "ControllerConnection.h"
|
||||
#include "embed.h"
|
||||
#include "EnvelopeAndLfoParameters.h"
|
||||
#include "FxMixer.h"
|
||||
#include "FxMixerView.h"
|
||||
#include "Mixer.h"
|
||||
#include "MixerView.h"
|
||||
#include "GuiApplication.h"
|
||||
#include "ExportFilter.h"
|
||||
#include "InstrumentTrack.h"
|
||||
#include "NotePlayHandle.h"
|
||||
#include "Pattern.h"
|
||||
#include "MidiClip.h"
|
||||
#include "PianoRoll.h"
|
||||
#include "ProjectJournal.h"
|
||||
#include "ProjectNotes.h"
|
||||
@@ -89,8 +89,8 @@ Song::Song() :
|
||||
m_isCancelled( false ),
|
||||
m_playMode( Mode_None ),
|
||||
m_length( 0 ),
|
||||
m_patternToPlay( nullptr ),
|
||||
m_loopPattern( false ),
|
||||
m_midiClipToPlay( nullptr ),
|
||||
m_loopMidiClip( false ),
|
||||
m_elapsedTicks( 0 ),
|
||||
m_elapsedBars( 0 ),
|
||||
m_loopRenderCount(1),
|
||||
@@ -227,11 +227,11 @@ void Song::processNextBuffer()
|
||||
}
|
||||
break;
|
||||
|
||||
case Mode_PlayPattern:
|
||||
if (m_patternToPlay)
|
||||
case Mode_PlayMidiClip:
|
||||
if (m_midiClipToPlay)
|
||||
{
|
||||
clipNum = m_patternToPlay->getTrack()->getTCONum(m_patternToPlay);
|
||||
trackList.push_back(m_patternToPlay->getTrack());
|
||||
clipNum = m_midiClipToPlay->getTrack()->getClipNum(m_midiClipToPlay);
|
||||
trackList.push_back(m_midiClipToPlay->getTrack());
|
||||
}
|
||||
break;
|
||||
|
||||
@@ -288,15 +288,15 @@ void Song::processNextBuffer()
|
||||
frameOffsetInTick -= elapsedTicks * framesPerTick;
|
||||
getPlayPos().setCurrentFrame(frameOffsetInTick);
|
||||
|
||||
// If we are playing a BB track, or a pattern with no loop enabled,
|
||||
// If we are playing a BB track, or a MIDI clip with no loop enabled,
|
||||
// loop back to the beginning when we reach the end
|
||||
if (m_playMode == Mode_PlayBB)
|
||||
{
|
||||
enforceLoop(TimePos{0}, TimePos{Engine::getBBTrackContainer()->lengthOfCurrentBB(), 0});
|
||||
}
|
||||
else if (m_playMode == Mode_PlayPattern && m_loopPattern && !loopEnabled)
|
||||
else if (m_playMode == Mode_PlayMidiClip && m_loopMidiClip && !loopEnabled)
|
||||
{
|
||||
enforceLoop(TimePos{0}, m_patternToPlay->length());
|
||||
enforceLoop(TimePos{0}, m_midiClipToPlay->length());
|
||||
}
|
||||
|
||||
// Handle loop points, and inform VST plugins of the loop status
|
||||
@@ -362,7 +362,7 @@ void Song::processAutomations(const TrackList &tracklist, TimePos timeStart, fpp
|
||||
QSet<const AutomatableModel*> recordedModels;
|
||||
|
||||
TrackContainer* container = this;
|
||||
int tcoNum = -1;
|
||||
int clipNum = -1;
|
||||
|
||||
switch (m_playMode)
|
||||
{
|
||||
@@ -375,28 +375,28 @@ void Song::processAutomations(const TrackList &tracklist, TimePos timeStart, fpp
|
||||
auto bbTrack = dynamic_cast<BBTrack*>(tracklist.at(0));
|
||||
auto bbContainer = Engine::getBBTrackContainer();
|
||||
container = bbContainer;
|
||||
tcoNum = bbTrack->index();
|
||||
clipNum = bbTrack->index();
|
||||
}
|
||||
break;
|
||||
default:
|
||||
return;
|
||||
}
|
||||
|
||||
values = container->automatedValuesAt(timeStart, tcoNum);
|
||||
values = container->automatedValuesAt(timeStart, clipNum);
|
||||
TrackList tracks = container->tracks();
|
||||
|
||||
Track::tcoVector tcos;
|
||||
Track::clipVector clips;
|
||||
for (Track* track : tracks)
|
||||
{
|
||||
if (track->type() == Track::AutomationTrack) {
|
||||
track->getTCOsInRange(tcos, 0, timeStart);
|
||||
track->getClipsInRange(clips, 0, timeStart);
|
||||
}
|
||||
}
|
||||
|
||||
// Process recording
|
||||
for (TrackContentObject* tco : tcos)
|
||||
for (Clip* clip : clips)
|
||||
{
|
||||
auto p = dynamic_cast<AutomationPattern *>(tco);
|
||||
auto p = dynamic_cast<AutomationClip *>(clip);
|
||||
TimePos relTime = timeStart - p->startPosition();
|
||||
if (p->isRecording() && relTime >= 0 && relTime < p->length())
|
||||
{
|
||||
@@ -407,7 +407,7 @@ void Song::processAutomations(const TrackList &tracklist, TimePos timeStart, fpp
|
||||
}
|
||||
}
|
||||
|
||||
// Checks if an automated model stopped being automated by automation patterns
|
||||
// Checks if an automated model stopped being automated by automation clip
|
||||
// so we can move the control back to any connected controller again
|
||||
for (auto it = m_oldAutomatedValues.begin(); it != m_oldAutomatedValues.end(); it++)
|
||||
{
|
||||
@@ -539,19 +539,19 @@ void Song::playBB()
|
||||
|
||||
|
||||
|
||||
void Song::playPattern( const Pattern* patternToPlay, bool loop )
|
||||
void Song::playMidiClip( const MidiClip* midiClipToPlay, bool loop )
|
||||
{
|
||||
if( isStopped() == false )
|
||||
{
|
||||
stop();
|
||||
}
|
||||
|
||||
m_patternToPlay = patternToPlay;
|
||||
m_loopPattern = loop;
|
||||
m_midiClipToPlay = midiClipToPlay;
|
||||
m_loopMidiClip = loop;
|
||||
|
||||
if( m_patternToPlay != nullptr )
|
||||
if( m_midiClipToPlay != nullptr )
|
||||
{
|
||||
m_playMode = Mode_PlayPattern;
|
||||
m_playMode = Mode_PlayMidiClip;
|
||||
m_playing = true;
|
||||
m_paused = false;
|
||||
}
|
||||
@@ -835,15 +835,15 @@ bpm_t Song::getTempo()
|
||||
|
||||
|
||||
|
||||
AutomationPattern * Song::tempoAutomationPattern()
|
||||
AutomationClip * Song::tempoAutomationClip()
|
||||
{
|
||||
return AutomationPattern::globalAutomationPattern( &m_tempoModel );
|
||||
return AutomationClip::globalAutomationClip( &m_tempoModel );
|
||||
}
|
||||
|
||||
|
||||
AutomatedValueMap Song::automatedValuesAt(TimePos time, int tcoNum) const
|
||||
AutomatedValueMap Song::automatedValuesAt(TimePos time, int clipNum) const
|
||||
{
|
||||
return TrackContainer::automatedValuesFromTracks(TrackList{m_globalAutomationTrack} << tracks(), time, tcoNum);
|
||||
return TrackContainer::automatedValuesFromTracks(TrackList{m_globalAutomationTrack} << tracks(), time, clipNum);
|
||||
}
|
||||
|
||||
|
||||
@@ -874,19 +874,19 @@ void Song::clearProject()
|
||||
{
|
||||
getGUI()->songEditor()->m_editor->clearAllTracks();
|
||||
}
|
||||
if( getGUI() != nullptr && getGUI()->fxMixerView() )
|
||||
if( getGUI() != nullptr && getGUI()->mixerView() )
|
||||
{
|
||||
getGUI()->fxMixerView()->clear();
|
||||
getGUI()->mixerView()->clear();
|
||||
}
|
||||
QCoreApplication::sendPostedEvents();
|
||||
Engine::getBBTrackContainer()->clearAllTracks();
|
||||
clearAllTracks();
|
||||
|
||||
Engine::fxMixer()->clear();
|
||||
Engine::mixer()->clear();
|
||||
|
||||
if( getGUI() != nullptr && getGUI()->automationEditor() )
|
||||
{
|
||||
getGUI()->automationEditor()->setCurrentPattern( nullptr );
|
||||
getGUI()->automationEditor()->setCurrentClip( nullptr );
|
||||
}
|
||||
|
||||
if( getGUI() != nullptr && getGUI()->pianoRoll() )
|
||||
@@ -902,10 +902,10 @@ void Song::clearProject()
|
||||
// Clear the m_oldAutomatedValues AutomatedValueMap
|
||||
m_oldAutomatedValues.clear();
|
||||
|
||||
AutomationPattern::globalAutomationPattern( &m_tempoModel )->clear();
|
||||
AutomationPattern::globalAutomationPattern( &m_masterVolumeModel )->
|
||||
AutomationClip::globalAutomationClip( &m_tempoModel )->clear();
|
||||
AutomationClip::globalAutomationClip( &m_masterVolumeModel )->
|
||||
clear();
|
||||
AutomationPattern::globalAutomationPattern( &m_masterPitchModel )->
|
||||
AutomationClip::globalAutomationClip( &m_masterPitchModel )->
|
||||
clear();
|
||||
|
||||
Engine::audioEngine()->doneChangeInModel();
|
||||
@@ -1088,15 +1088,15 @@ void Song::loadProject( const QString & fileName )
|
||||
//Backward compatibility for LMMS <= 0.4.15
|
||||
PeakController::initGetControllerBySetting();
|
||||
|
||||
// Load mixer first to be able to set the correct range for FX channels
|
||||
node = dataFile.content().firstChildElement( Engine::fxMixer()->nodeName() );
|
||||
// Load mixer first to be able to set the correct range for mixer channels
|
||||
node = dataFile.content().firstChildElement( Engine::mixer()->nodeName() );
|
||||
if( !node.isNull() )
|
||||
{
|
||||
Engine::fxMixer()->restoreState( node.toElement() );
|
||||
Engine::mixer()->restoreState( node.toElement() );
|
||||
if( getGUI() != nullptr )
|
||||
{
|
||||
// refresh FxMixerView
|
||||
getGUI()->fxMixerView()->refreshDisplay();
|
||||
// refresh MixerView
|
||||
getGUI()->mixerView()->refreshDisplay();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1169,7 +1169,7 @@ void Song::loadProject( const QString & fileName )
|
||||
node = node.nextSibling();
|
||||
}
|
||||
|
||||
// quirk for fixing projects with broken positions of TCOs inside
|
||||
// quirk for fixing projects with broken positions of Clips inside
|
||||
// BB-tracks
|
||||
Engine::getBBTrackContainer()->fixIncorrectPositions();
|
||||
|
||||
@@ -1183,7 +1183,7 @@ void Song::loadProject( const QString & fileName )
|
||||
m_controllers.end());
|
||||
|
||||
// resolve all IDs so that autoModels are automated
|
||||
AutomationPattern::resolveAllIDs();
|
||||
AutomationClip::resolveAllIDs();
|
||||
|
||||
|
||||
Engine::audioEngine()->doneChangeInModel();
|
||||
@@ -1238,7 +1238,7 @@ bool Song::saveProjectFile(const QString & filename, bool withResources)
|
||||
saveState( dataFile, dataFile.content() );
|
||||
|
||||
m_globalAutomationTrack->saveState( dataFile, dataFile.content() );
|
||||
Engine::fxMixer()->saveState( dataFile, dataFile.content() );
|
||||
Engine::mixer()->saveState( dataFile, dataFile.content() );
|
||||
if( getGUI() != nullptr )
|
||||
{
|
||||
getGUI()->getControllerRackView()->saveState( dataFile, dataFile.content() );
|
||||
|
||||
@@ -33,7 +33,7 @@ const int REMOVE_RELEASED_NOTE_TIME_THRESHOLD_MS = 70;
|
||||
StepRecorder::StepRecorder(PianoRoll& pianoRoll, StepRecorderWidget& stepRecorderWidget):
|
||||
m_pianoRoll(pianoRoll),
|
||||
m_stepRecorderWidget(stepRecorderWidget),
|
||||
m_pattern(nullptr)
|
||||
m_midiClip(nullptr)
|
||||
{
|
||||
m_stepRecorderWidget.hide();
|
||||
}
|
||||
@@ -109,7 +109,7 @@ void StepRecorder::noteReleased(const Note & n)
|
||||
m_updateReleasedTimer.start(REMOVE_RELEASED_NOTE_TIME_THRESHOLD_MS);
|
||||
}
|
||||
|
||||
//check if all note are released, apply notes to pattern(or dimiss if length is zero) and prepare to record next step
|
||||
//check if all note are released, apply notes to clips (or dimiss if length is zero) and prepare to record next step
|
||||
if(allCurStepNotesReleased())
|
||||
{
|
||||
if(m_curStepLength > 0)
|
||||
@@ -226,16 +226,16 @@ void StepRecorder::stepBackwards()
|
||||
|
||||
void StepRecorder::applyStep()
|
||||
{
|
||||
m_pattern->addJournalCheckPoint();
|
||||
m_midiClip->addJournalCheckPoint();
|
||||
|
||||
for (const StepNote* stepNote : m_curStepNotes)
|
||||
{
|
||||
m_pattern->addNote(stepNote->m_note, false);
|
||||
m_midiClip->addNote(stepNote->m_note, false);
|
||||
}
|
||||
|
||||
m_pattern->rearrangeAllNotes();
|
||||
m_pattern->updateLength();
|
||||
m_pattern->dataChanged();
|
||||
m_midiClip->rearrangeAllNotes();
|
||||
m_midiClip->updateLength();
|
||||
m_midiClip->dataChanged();
|
||||
Engine::getSong()->setModified();
|
||||
|
||||
prepareNewStep();
|
||||
@@ -267,14 +267,14 @@ void StepRecorder::prepareNewStep()
|
||||
updateWidget();
|
||||
}
|
||||
|
||||
void StepRecorder::setCurrentPattern( Pattern* newPattern )
|
||||
void StepRecorder::setCurrentMidiClip( MidiClip* newMidiClip )
|
||||
{
|
||||
if(m_pattern != nullptr && m_pattern != newPattern)
|
||||
if(m_midiClip != nullptr && m_midiClip != newMidiClip)
|
||||
{
|
||||
dismissStep();
|
||||
}
|
||||
|
||||
m_pattern = newPattern;
|
||||
m_midiClip = newMidiClip;
|
||||
}
|
||||
|
||||
void StepRecorder::removeNotesReleasedForTooLong()
|
||||
|
||||
@@ -31,7 +31,7 @@
|
||||
|
||||
#include <QVariant>
|
||||
|
||||
#include "AutomationPattern.h"
|
||||
#include "AutomationClip.h"
|
||||
#include "AutomationTrack.h"
|
||||
#include "BBTrack.h"
|
||||
#include "BBTrackContainer.h"
|
||||
@@ -60,7 +60,7 @@ Track::Track( TrackTypes type, TrackContainer * tc ) :
|
||||
m_mutedModel( false, this, tr( "Mute" ) ), /*!< For controlling track muting */
|
||||
m_soloModel( false, this, tr( "Solo" ) ), /*!< For controlling track soloing */
|
||||
m_simpleSerializingMode( false ),
|
||||
m_trackContentObjects(), /*!< The track content objects (segments) */
|
||||
m_clips(), /*!< The clips (segments) */
|
||||
m_color( 0, 0, 0 ),
|
||||
m_hasColor( false )
|
||||
{
|
||||
@@ -76,7 +76,7 @@ Track::Track( TrackTypes type, TrackContainer * tc ) :
|
||||
* If the track container is a Beat+Bassline container, step through
|
||||
* its list of tracks and remove us.
|
||||
*
|
||||
* Then delete the TrackContentObject's contents, remove this track from
|
||||
* Then delete the Clip's contents, remove this track from
|
||||
* the track container.
|
||||
*
|
||||
* Finally step through this track's automation and forget all of them.
|
||||
@@ -86,9 +86,9 @@ Track::~Track()
|
||||
lock();
|
||||
emit destroyedTrack();
|
||||
|
||||
while( !m_trackContentObjects.isEmpty() )
|
||||
while( !m_clips.isEmpty() )
|
||||
{
|
||||
delete m_trackContentObjects.last();
|
||||
delete m_clips.last();
|
||||
}
|
||||
|
||||
m_trackContainer->removeTrack( this );
|
||||
@@ -124,7 +124,7 @@ Track * Track::create( TrackTypes tt, TrackContainer * tc )
|
||||
|
||||
if( tc == Engine::getBBTrackContainer() && t )
|
||||
{
|
||||
t->createTCOsForBB( Engine::getBBTrackContainer()->numOfBBs()
|
||||
t->createClipsForBB( Engine::getBBTrackContainer()->numOfBBs()
|
||||
- 1 );
|
||||
}
|
||||
|
||||
@@ -173,7 +173,7 @@ Track* Track::clone()
|
||||
saveState(doc, parent);
|
||||
Track* t = create(parent.firstChild().toElement(), m_trackContainer);
|
||||
|
||||
AutomationPattern::resolveAllIDs();
|
||||
AutomationClip::resolveAllIDs();
|
||||
return t;
|
||||
}
|
||||
|
||||
@@ -185,7 +185,7 @@ Track* Track::clone()
|
||||
/*! \brief Save this track's settings to file
|
||||
*
|
||||
* We save the track type and its muted state and solo state, then append the track-
|
||||
* specific settings. Then we iterate through the trackContentObjects
|
||||
* specific settings. Then we iterate through the clips
|
||||
* and save all their states in turn.
|
||||
*
|
||||
* \param doc The QDomDocument to use to save
|
||||
@@ -228,9 +228,9 @@ void Track::saveSettings( QDomDocument & doc, QDomElement & element )
|
||||
return;
|
||||
}
|
||||
|
||||
// now save settings of all TCO's
|
||||
for( tcoVector::const_iterator it = m_trackContentObjects.begin();
|
||||
it != m_trackContentObjects.end(); ++it )
|
||||
// now save settings of all Clip's
|
||||
for( clipVector::const_iterator it = m_clips.begin();
|
||||
it != m_clips.end(); ++it )
|
||||
{
|
||||
( *it )->saveState( doc, element );
|
||||
}
|
||||
@@ -242,10 +242,10 @@ void Track::saveSettings( QDomDocument & doc, QDomElement & element )
|
||||
/*! \brief Load the settings from a file
|
||||
*
|
||||
* We load the track's type and muted state and solo state, then clear out our
|
||||
* current TrackContentObject.
|
||||
* current Clip.
|
||||
*
|
||||
* Then we step through the QDomElement's children and load the
|
||||
* track-specific settings and trackContentObjects states from it
|
||||
* track-specific settings and clip states from it
|
||||
* one at a time.
|
||||
*
|
||||
* \param element the QDomElement to load track settings from
|
||||
@@ -294,10 +294,10 @@ void Track::loadSettings( const QDomElement & element )
|
||||
return;
|
||||
}
|
||||
|
||||
while( !m_trackContentObjects.empty() )
|
||||
while( !m_clips.empty() )
|
||||
{
|
||||
delete m_trackContentObjects.front();
|
||||
// m_trackContentObjects.erase( m_trackContentObjects.begin() );
|
||||
delete m_clips.front();
|
||||
// m_clips.erase( m_clips.begin() );
|
||||
}
|
||||
|
||||
QDomNode node = element.firstChild();
|
||||
@@ -313,9 +313,9 @@ void Track::loadSettings( const QDomElement & element )
|
||||
&& node.nodeName() != "solo"
|
||||
&& !node.toElement().attribute( "metadata" ).toInt() )
|
||||
{
|
||||
TrackContentObject * tco = createTCO(
|
||||
Clip * clip = createClip(
|
||||
TimePos( 0 ) );
|
||||
tco->restoreState( node.toElement() );
|
||||
clip->restoreState( node.toElement() );
|
||||
}
|
||||
}
|
||||
node = node.nextSibling();
|
||||
@@ -331,34 +331,32 @@ void Track::loadSettings( const QDomElement & element )
|
||||
|
||||
|
||||
|
||||
/*! \brief Add another TrackContentObject into this track
|
||||
/*! \brief Add another Clip into this track
|
||||
*
|
||||
* \param tco The TrackContentObject to attach to this track.
|
||||
* \param clip The Clip to attach to this track.
|
||||
*/
|
||||
TrackContentObject * Track::addTCO( TrackContentObject * tco )
|
||||
Clip * Track::addClip( Clip * clip )
|
||||
{
|
||||
m_trackContentObjects.push_back( tco );
|
||||
m_clips.push_back( clip );
|
||||
|
||||
emit trackContentObjectAdded( tco );
|
||||
emit clipAdded( clip );
|
||||
|
||||
return tco; // just for convenience
|
||||
return clip; // just for convenience
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
/*! \brief Remove a given TrackContentObject from this track
|
||||
/*! \brief Remove a given Clip from this track
|
||||
*
|
||||
* \param tco The TrackContentObject to remove from this track.
|
||||
* \param clip The Clip to remove from this track.
|
||||
*/
|
||||
void Track::removeTCO( TrackContentObject * tco )
|
||||
void Track::removeClip( Clip * clip )
|
||||
{
|
||||
tcoVector::iterator it = std::find( m_trackContentObjects.begin(),
|
||||
m_trackContentObjects.end(),
|
||||
tco );
|
||||
if( it != m_trackContentObjects.end() )
|
||||
clipVector::iterator it = std::find( m_clips.begin(), m_clips.end(), clip );
|
||||
if( it != m_clips.end() )
|
||||
{
|
||||
m_trackContentObjects.erase( it );
|
||||
m_clips.erase( it );
|
||||
if( Engine::getSong() )
|
||||
{
|
||||
Engine::getSong()->updateLength();
|
||||
@@ -368,105 +366,103 @@ void Track::removeTCO( TrackContentObject * tco )
|
||||
}
|
||||
|
||||
|
||||
/*! \brief Remove all TCOs from this track */
|
||||
void Track::deleteTCOs()
|
||||
/*! \brief Remove all Clips from this track */
|
||||
void Track::deleteClips()
|
||||
{
|
||||
while( ! m_trackContentObjects.isEmpty() )
|
||||
while( ! m_clips.isEmpty() )
|
||||
{
|
||||
delete m_trackContentObjects.first();
|
||||
delete m_clips.first();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*! \brief Return the number of trackContentObjects we contain
|
||||
/*! \brief Return the number of clips we contain
|
||||
*
|
||||
* \return the number of trackContentObjects we currently contain.
|
||||
* \return the number of clips we currently contain.
|
||||
*/
|
||||
int Track::numOfTCOs()
|
||||
int Track::numOfClips()
|
||||
{
|
||||
return m_trackContentObjects.size();
|
||||
return m_clips.size();
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
/*! \brief Get a TrackContentObject by number
|
||||
/*! \brief Get a Clip by number
|
||||
*
|
||||
* If the TCO number is less than our TCO array size then fetch that
|
||||
* If the Clip number is less than our Clip array size then fetch that
|
||||
* numbered object from the array. Otherwise we warn the user that
|
||||
* we've somehow requested a TCO that is too large, and create a new
|
||||
* TCO for them.
|
||||
* \param tcoNum The number of the TrackContentObject to fetch.
|
||||
* \return the given TrackContentObject or a new one if out of range.
|
||||
* \todo reject TCO numbers less than zero.
|
||||
* \todo if we create a TCO here, should we somehow attach it to the
|
||||
* we've somehow requested a Clip that is too large, and create a new
|
||||
* Clip for them.
|
||||
* \param clipNum The number of the Clip to fetch.
|
||||
* \return the given Clip or a new one if out of range.
|
||||
* \todo reject Clip numbers less than zero.
|
||||
* \todo if we create a Clip here, should we somehow attach it to the
|
||||
* track?
|
||||
*/
|
||||
TrackContentObject * Track::getTCO( int tcoNum )
|
||||
Clip * Track::getClip( int clipNum )
|
||||
{
|
||||
if( tcoNum < m_trackContentObjects.size() )
|
||||
if( clipNum < m_clips.size() )
|
||||
{
|
||||
return m_trackContentObjects[tcoNum];
|
||||
return m_clips[clipNum];
|
||||
}
|
||||
printf( "called Track::getTCO( %d ), "
|
||||
"but TCO %d doesn't exist\n", tcoNum, tcoNum );
|
||||
return createTCO( tcoNum * TimePos::ticksPerBar() );
|
||||
printf( "called Track::getClip( %d ), "
|
||||
"but Clip %d doesn't exist\n", clipNum, clipNum );
|
||||
return createClip( clipNum * TimePos::ticksPerBar() );
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
/*! \brief Determine the given TrackContentObject's number in our array.
|
||||
/*! \brief Determine the given Clip's number in our array.
|
||||
*
|
||||
* \param tco The TrackContentObject to search for.
|
||||
* \param clip The Clip to search for.
|
||||
* \return its number in our array.
|
||||
*/
|
||||
int Track::getTCONum( const TrackContentObject * tco )
|
||||
int Track::getClipNum( const Clip * clip )
|
||||
{
|
||||
// for( int i = 0; i < getTrackContentWidget()->numOfTCOs(); ++i )
|
||||
tcoVector::iterator it = std::find( m_trackContentObjects.begin(),
|
||||
m_trackContentObjects.end(),
|
||||
tco );
|
||||
if( it != m_trackContentObjects.end() )
|
||||
// for( int i = 0; i < getTrackContentWidget()->numOfClips(); ++i )
|
||||
clipVector::iterator it = std::find( m_clips.begin(), m_clips.end(), clip );
|
||||
if( it != m_clips.end() )
|
||||
{
|
||||
/* if( getTCO( i ) == _tco )
|
||||
/* if( getClip( i ) == _clip )
|
||||
{
|
||||
return i;
|
||||
}*/
|
||||
return it - m_trackContentObjects.begin();
|
||||
return it - m_clips.begin();
|
||||
}
|
||||
qWarning( "Track::getTCONum(...) -> _tco not found!\n" );
|
||||
qWarning( "Track::getClipNum(...) -> _clip not found!\n" );
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
/*! \brief Retrieve a list of trackContentObjects that fall within a period.
|
||||
/*! \brief Retrieve a list of clips that fall within a period.
|
||||
*
|
||||
* Here we're interested in a range of trackContentObjects that intersect
|
||||
* Here we're interested in a range of clips that intersect
|
||||
* the given time period.
|
||||
*
|
||||
* We return the TCOs we find in order by time, earliest TCOs first.
|
||||
* We return the Clips we find in order by time, earliest Clips first.
|
||||
*
|
||||
* \param tcoV The list to contain the found trackContentObjects.
|
||||
* \param clipV The list to contain the found clips.
|
||||
* \param start The MIDI start time of the range.
|
||||
* \param end The MIDI endi time of the range.
|
||||
*/
|
||||
void Track::getTCOsInRange( tcoVector & tcoV, const TimePos & start,
|
||||
void Track::getClipsInRange( clipVector & clipV, const TimePos & start,
|
||||
const TimePos & end )
|
||||
{
|
||||
for( TrackContentObject* tco : m_trackContentObjects )
|
||||
for( Clip* clip : m_clips )
|
||||
{
|
||||
int s = tco->startPosition();
|
||||
int e = tco->endPosition();
|
||||
int s = clip->startPosition();
|
||||
int e = clip->endPosition();
|
||||
if( ( s <= end ) && ( e >= start ) )
|
||||
{
|
||||
// TCO is within given range
|
||||
// Insert sorted by TCO's position
|
||||
tcoV.insert(std::upper_bound(tcoV.begin(), tcoV.end(), tco, TrackContentObject::comparePosition),
|
||||
tco);
|
||||
// Clip is within given range
|
||||
// Insert sorted by Clip's position
|
||||
clipV.insert(std::upper_bound(clipV.begin(), clipV.end(), clip, Clip::comparePosition),
|
||||
clip);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -474,55 +470,53 @@ void Track::getTCOsInRange( tcoVector & tcoV, const TimePos & start,
|
||||
|
||||
|
||||
|
||||
/*! \brief Swap the position of two trackContentObjects.
|
||||
/*! \brief Swap the position of two clips.
|
||||
*
|
||||
* First, we arrange to swap the positions of the two TCOs in the
|
||||
* trackContentObjects list. Then we swap their start times as well.
|
||||
* First, we arrange to swap the positions of the two Clips in the
|
||||
* clips list. Then we swap their start times as well.
|
||||
*
|
||||
* \param tcoNum1 The first TrackContentObject to swap.
|
||||
* \param tcoNum2 The second TrackContentObject to swap.
|
||||
* \param clipNum1 The first Clip to swap.
|
||||
* \param clipNum2 The second Clip to swap.
|
||||
*/
|
||||
void Track::swapPositionOfTCOs( int tcoNum1, int tcoNum2 )
|
||||
void Track::swapPositionOfClips( int clipNum1, int clipNum2 )
|
||||
{
|
||||
qSwap( m_trackContentObjects[tcoNum1],
|
||||
m_trackContentObjects[tcoNum2] );
|
||||
qSwap( m_clips[clipNum1], m_clips[clipNum2] );
|
||||
|
||||
const TimePos pos = m_trackContentObjects[tcoNum1]->startPosition();
|
||||
const TimePos pos = m_clips[clipNum1]->startPosition();
|
||||
|
||||
m_trackContentObjects[tcoNum1]->movePosition(
|
||||
m_trackContentObjects[tcoNum2]->startPosition() );
|
||||
m_trackContentObjects[tcoNum2]->movePosition( pos );
|
||||
m_clips[clipNum1]->movePosition( m_clips[clipNum2]->startPosition() );
|
||||
m_clips[clipNum2]->movePosition( pos );
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
void Track::createTCOsForBB( int bb )
|
||||
void Track::createClipsForBB( int bb )
|
||||
{
|
||||
while( numOfTCOs() < bb + 1 )
|
||||
while( numOfClips() < bb + 1 )
|
||||
{
|
||||
TimePos position = TimePos( numOfTCOs(), 0 );
|
||||
TrackContentObject * tco = createTCO( position );
|
||||
tco->changeLength( TimePos( 1, 0 ) );
|
||||
TimePos position = TimePos( numOfClips(), 0 );
|
||||
Clip * clip = createClip( position );
|
||||
clip->changeLength( TimePos( 1, 0 ) );
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
/*! \brief Move all the trackContentObjects after a certain time later by one bar.
|
||||
/*! \brief Move all the clips after a certain time later by one bar.
|
||||
*
|
||||
* \param pos The time at which we want to insert the bar.
|
||||
* \todo if we stepped through this list last to first, and the list was
|
||||
* in ascending order by TCO time, once we hit a TCO that was earlier
|
||||
* in ascending order by Clip time, once we hit a Clip that was earlier
|
||||
* than the insert time, we could fall out of the loop early.
|
||||
*/
|
||||
void Track::insertBar( const TimePos & pos )
|
||||
{
|
||||
// we'll increase the position of every TCO, positioned behind pos, by
|
||||
// we'll increase the position of every Clip, positioned behind pos, by
|
||||
// one bar
|
||||
for( tcoVector::iterator it = m_trackContentObjects.begin();
|
||||
it != m_trackContentObjects.end(); ++it )
|
||||
for( clipVector::iterator it = m_clips.begin();
|
||||
it != m_clips.end(); ++it )
|
||||
{
|
||||
if( ( *it )->startPosition() >= pos )
|
||||
{
|
||||
@@ -535,16 +529,15 @@ void Track::insertBar( const TimePos & pos )
|
||||
|
||||
|
||||
|
||||
/*! \brief Move all the trackContentObjects after a certain time earlier by one bar.
|
||||
/*! \brief Move all the clips after a certain time earlier by one bar.
|
||||
*
|
||||
* \param pos The time at which we want to remove the bar.
|
||||
*/
|
||||
void Track::removeBar( const TimePos & pos )
|
||||
{
|
||||
// we'll decrease the position of every TCO, positioned behind pos, by
|
||||
// we'll decrease the position of every Clip, positioned behind pos, by
|
||||
// one bar
|
||||
for( tcoVector::iterator it = m_trackContentObjects.begin();
|
||||
it != m_trackContentObjects.end(); ++it )
|
||||
for( clipVector::iterator it = m_clips.begin(); it != m_clips.end(); ++it )
|
||||
{
|
||||
if( ( *it )->startPosition() >= pos )
|
||||
{
|
||||
@@ -558,7 +551,7 @@ void Track::removeBar( const TimePos & pos )
|
||||
|
||||
/*! \brief Return the length of the entire track in bars
|
||||
*
|
||||
* We step through our list of TCOs and determine their end position,
|
||||
* We step through our list of Clips and determine their end position,
|
||||
* keeping track of the latest time found in ticks. Then we return
|
||||
* that in bars by dividing by the number of ticks per bar.
|
||||
*/
|
||||
@@ -566,8 +559,7 @@ bar_t Track::length() const
|
||||
{
|
||||
// find last end-position
|
||||
tick_t last = 0;
|
||||
for( tcoVector::const_iterator it = m_trackContentObjects.begin();
|
||||
it != m_trackContentObjects.end(); ++it )
|
||||
for( clipVector::const_iterator it = m_clips.begin(); it != m_clips.end(); ++it )
|
||||
{
|
||||
if( Engine::getSong()->isExporting() &&
|
||||
( *it )->isMuted() )
|
||||
|
||||
@@ -29,7 +29,7 @@
|
||||
#include <QDomElement>
|
||||
#include <QWriteLocker>
|
||||
|
||||
#include "AutomationPattern.h"
|
||||
#include "AutomationClip.h"
|
||||
#include "AutomationTrack.h"
|
||||
#include "BBTrack.h"
|
||||
#include "BBTrackContainer.h"
|
||||
@@ -238,7 +238,7 @@ bool TrackContainer::isEmpty() const
|
||||
for( TrackList::const_iterator it = m_tracks.begin();
|
||||
it != m_tracks.end(); ++it )
|
||||
{
|
||||
if( !( *it )->getTCOs().isEmpty() )
|
||||
if( !( *it )->getClips().isEmpty() )
|
||||
{
|
||||
return false;
|
||||
}
|
||||
@@ -248,15 +248,15 @@ bool TrackContainer::isEmpty() const
|
||||
|
||||
|
||||
|
||||
AutomatedValueMap TrackContainer::automatedValuesAt(TimePos time, int tcoNum) const
|
||||
AutomatedValueMap TrackContainer::automatedValuesAt(TimePos time, int clipNum) const
|
||||
{
|
||||
return automatedValuesFromTracks(tracks(), time, tcoNum);
|
||||
return automatedValuesFromTracks(tracks(), time, clipNum);
|
||||
}
|
||||
|
||||
|
||||
AutomatedValueMap TrackContainer::automatedValuesFromTracks(const TrackList &tracks, TimePos time, int tcoNum)
|
||||
AutomatedValueMap TrackContainer::automatedValuesFromTracks(const TrackList &tracks, TimePos time, int clipNum)
|
||||
{
|
||||
Track::tcoVector tcos;
|
||||
Track::clipVector clips;
|
||||
|
||||
for (Track* track: tracks)
|
||||
{
|
||||
@@ -269,11 +269,11 @@ AutomatedValueMap TrackContainer::automatedValuesFromTracks(const TrackList &tra
|
||||
case Track::AutomationTrack:
|
||||
case Track::HiddenAutomationTrack:
|
||||
case Track::BBTrack:
|
||||
if (tcoNum < 0) {
|
||||
track->getTCOsInRange(tcos, 0, time);
|
||||
if (clipNum < 0) {
|
||||
track->getClipsInRange(clips, 0, time);
|
||||
} else {
|
||||
Q_ASSERT(track->numOfTCOs() > tcoNum);
|
||||
tcos << track->getTCO(tcoNum);
|
||||
Q_ASSERT(track->numOfClips() > clipNum);
|
||||
clips << track->getClip(clipNum);
|
||||
}
|
||||
default:
|
||||
break;
|
||||
@@ -282,15 +282,15 @@ AutomatedValueMap TrackContainer::automatedValuesFromTracks(const TrackList &tra
|
||||
|
||||
AutomatedValueMap valueMap;
|
||||
|
||||
Q_ASSERT(std::is_sorted(tcos.begin(), tcos.end(), TrackContentObject::comparePosition));
|
||||
Q_ASSERT(std::is_sorted(clips.begin(), clips.end(), Clip::comparePosition));
|
||||
|
||||
for(TrackContentObject* tco : tcos)
|
||||
for(Clip* clip : clips)
|
||||
{
|
||||
if (tco->isMuted() || tco->startPosition() > time) {
|
||||
if (clip->isMuted() || clip->startPosition() > time) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (auto* p = dynamic_cast<AutomationPattern *>(tco))
|
||||
if (auto* p = dynamic_cast<AutomationClip *>(clip))
|
||||
{
|
||||
if (! p->hasAutomation()) {
|
||||
continue;
|
||||
@@ -306,13 +306,13 @@ AutomatedValueMap TrackContainer::automatedValuesFromTracks(const TrackList &tra
|
||||
valueMap[model] = value;
|
||||
}
|
||||
}
|
||||
else if (auto* bb = dynamic_cast<BBTCO *>(tco))
|
||||
else if (auto* bb = dynamic_cast<BBClip *>(clip))
|
||||
{
|
||||
auto bbIndex = dynamic_cast<class BBTrack*>(bb->getTrack())->index();
|
||||
auto bbContainer = Engine::getBBTrackContainer();
|
||||
|
||||
TimePos bbTime = time - tco->startPosition();
|
||||
bbTime = std::min(bbTime, tco->length());
|
||||
TimePos bbTime = time - clip->startPosition();
|
||||
bbTime = std::min(bbTime, clip->length());
|
||||
bbTime = bbTime % (bbContainer->lengthOfBB(bbIndex) * TimePos::ticksPerBar());
|
||||
|
||||
auto bbValues = bbContainer->automatedValuesAt(bbTime, bbIndex);
|
||||
|
||||
@@ -263,7 +263,7 @@ void AudioDevice::clearS16Buffer( int_sample_t * _outbuf, const fpp_t _frames )
|
||||
|
||||
bool AudioDevice::hqAudio() const
|
||||
{
|
||||
return ConfigManager::inst()->value( "mixer", "hqaudio" ).toInt();
|
||||
return ConfigManager::inst()->value( "audioengine", "hqaudio" ).toInt();
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -26,7 +26,7 @@
|
||||
#include "AudioDevice.h"
|
||||
#include "AudioEngine.h"
|
||||
#include "EffectChain.h"
|
||||
#include "FxMixer.h"
|
||||
#include "Mixer.h"
|
||||
#include "Engine.h"
|
||||
#include "MixHelpers.h"
|
||||
#include "BufferManager.h"
|
||||
@@ -38,7 +38,7 @@ AudioPort::AudioPort( const QString & _name, bool _has_effect_chain,
|
||||
m_bufferUsage( false ),
|
||||
m_portBuffer( BufferManager::acquire() ),
|
||||
m_extOutputEnabled( false ),
|
||||
m_nextFxChannel( 0 ),
|
||||
m_nextMixerChannel( 0 ),
|
||||
m_name( "unnamed port" ),
|
||||
m_effects( _has_effect_chain ? new EffectChain( nullptr ) : nullptr ),
|
||||
m_volumeModel( volumeModel ),
|
||||
@@ -222,7 +222,7 @@ void AudioPort::doProcessing()
|
||||
const bool me = processEffects();
|
||||
if( me || m_bufferUsage )
|
||||
{
|
||||
Engine::fxMixer()->mixToChannel( m_portBuffer, m_nextFxChannel ); // send output to fx mixer
|
||||
Engine::mixer()->mixToChannel( m_portBuffer, m_nextMixerChannel ); // send output to mixer
|
||||
// TODO: improve the flow here - convert to pull model
|
||||
m_bufferUsage = false;
|
||||
}
|
||||
|
||||
@@ -69,7 +69,15 @@ void Lv2Features::createFeatureVectors()
|
||||
// create vector of features
|
||||
for(std::pair<const char* const, void*>& pr : m_featureByUri)
|
||||
{
|
||||
Q_ASSERT(pr.second != nullptr);
|
||||
/*
|
||||
If pr.second is nullptr here, this means that the LV2_feature
|
||||
has no "data". If this happens here, this means
|
||||
* either that this feature is static
|
||||
(e.g. LV2_BUF_SIZE__boundedBlockLength)
|
||||
* or that the programmer forgot to use operator[] before feature
|
||||
vector creation (This can be done in
|
||||
Lv2Proc::initPluginSpecificFeatures or in Lv2Features::initCommon)
|
||||
*/
|
||||
m_features.push_back(LV2_Feature { pr.first, pr.second });
|
||||
}
|
||||
|
||||
|
||||
@@ -31,6 +31,7 @@
|
||||
#include <cstring>
|
||||
#include <lilv/lilv.h>
|
||||
#include <lv2.h>
|
||||
#include <lv2/lv2plug.in/ns/ext/buf-size/buf-size.h>
|
||||
#include <lv2/lv2plug.in/ns/ext/options/options.h>
|
||||
#include <QDebug>
|
||||
#include <QDir>
|
||||
@@ -78,6 +79,10 @@ Lv2Manager::Lv2Manager() :
|
||||
m_supportedFeatureURIs.insert(LV2_URID__map);
|
||||
m_supportedFeatureURIs.insert(LV2_URID__unmap);
|
||||
m_supportedFeatureURIs.insert(LV2_OPTIONS__options);
|
||||
// min/max is always passed in the options
|
||||
m_supportedFeatureURIs.insert(LV2_BUF_SIZE__boundedBlockLength);
|
||||
// block length is only changed initially in AudioEngine CTOR
|
||||
m_supportedFeatureURIs.insert(LV2_BUF_SIZE__fixedBlockLength);
|
||||
|
||||
auto supportOpt = [this](Lv2UridCache::Id id)
|
||||
{
|
||||
|
||||
@@ -39,8 +39,10 @@ MidiOss::MidiOss() :
|
||||
{
|
||||
// only start thread, if opening of MIDI-device is successful,
|
||||
// otherwise isRunning()==false indicates error
|
||||
if( m_midiDev.open( QIODevice::ReadWrite ) ||
|
||||
m_midiDev.open( QIODevice::ReadOnly ) )
|
||||
if( m_midiDev.open( QIODevice::ReadWrite |
|
||||
QIODevice::Unbuffered ) ||
|
||||
m_midiDev.open( QIODevice::ReadOnly |
|
||||
QIODevice::Unbuffered ) )
|
||||
{
|
||||
start( QThread::LowPriority );
|
||||
}
|
||||
|
||||
@@ -27,7 +27,7 @@
|
||||
#include <QMouseEvent>
|
||||
|
||||
#include "AutomatableModelView.h"
|
||||
#include "AutomationPattern.h"
|
||||
#include "AutomationClip.h"
|
||||
#include "ControllerConnectionDialog.h"
|
||||
#include "ControllerConnection.h"
|
||||
#include "embed.h"
|
||||
@@ -261,7 +261,7 @@ void AutomatableModelViewSlots::removeConnection()
|
||||
void AutomatableModelViewSlots::editSongGlobalAutomation()
|
||||
{
|
||||
getGUI()->automationEditor()->open(
|
||||
AutomationPattern::globalAutomationPattern(m_amv->modelUntyped())
|
||||
AutomationClip::globalAutomationClip(m_amv->modelUntyped())
|
||||
);
|
||||
}
|
||||
|
||||
@@ -269,7 +269,7 @@ void AutomatableModelViewSlots::editSongGlobalAutomation()
|
||||
|
||||
void AutomatableModelViewSlots::removeSongGlobalAutomation()
|
||||
{
|
||||
delete AutomationPattern::globalAutomationPattern( m_amv->modelUntyped() );
|
||||
delete AutomationClip::globalAutomationClip( m_amv->modelUntyped() );
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* AutomationPatternView.cpp - implementation of view for AutomationPattern
|
||||
* AutomationClipView.cpp - implementation of view for AutomationClip
|
||||
*
|
||||
* Copyright (c) 2008-2010 Tobias Doerffel <tobydox/at/users.sourceforge.net>
|
||||
*
|
||||
@@ -21,7 +21,7 @@
|
||||
* Boston, MA 02110-1301 USA.
|
||||
*
|
||||
*/
|
||||
#include "AutomationPatternView.h"
|
||||
#include "AutomationClipView.h"
|
||||
|
||||
#include <QMouseEvent>
|
||||
#include <QPainter>
|
||||
@@ -41,26 +41,26 @@
|
||||
#include "Engine.h"
|
||||
|
||||
|
||||
QPixmap * AutomationPatternView::s_pat_rec = nullptr;
|
||||
QPixmap * AutomationClipView::s_clip_rec = nullptr;
|
||||
|
||||
AutomationPatternView::AutomationPatternView( AutomationPattern * _pattern,
|
||||
AutomationClipView::AutomationClipView( AutomationClip * _clip,
|
||||
TrackView * _parent ) :
|
||||
TrackContentObjectView( _pattern, _parent ),
|
||||
m_pat( _pattern ),
|
||||
ClipView( _clip, _parent ),
|
||||
m_clip( _clip ),
|
||||
m_paintPixmap()
|
||||
{
|
||||
connect( m_pat, SIGNAL( dataChanged() ),
|
||||
connect( m_clip, SIGNAL( dataChanged() ),
|
||||
this, SLOT( update() ) );
|
||||
connect( getGUI()->automationEditor(), SIGNAL( currentPatternChanged() ),
|
||||
connect( getGUI()->automationEditor(), SIGNAL( currentClipChanged() ),
|
||||
this, SLOT( update() ) );
|
||||
|
||||
setAttribute( Qt::WA_OpaquePaintEvent, true );
|
||||
|
||||
ToolTip::add(this, m_pat->name());
|
||||
ToolTip::add(this, m_clip->name());
|
||||
setStyle( QApplication::style() );
|
||||
|
||||
if( s_pat_rec == nullptr ) { s_pat_rec = new QPixmap( embed::getIconPixmap(
|
||||
"pat_rec" ) ); }
|
||||
if( s_clip_rec == nullptr ) { s_clip_rec = new QPixmap( embed::getIconPixmap(
|
||||
"clip_rec" ) ); }
|
||||
|
||||
update();
|
||||
}
|
||||
@@ -68,71 +68,71 @@ AutomationPatternView::AutomationPatternView( AutomationPattern * _pattern,
|
||||
|
||||
|
||||
|
||||
AutomationPatternView::~AutomationPatternView()
|
||||
AutomationClipView::~AutomationClipView()
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
void AutomationPatternView::openInAutomationEditor()
|
||||
void AutomationClipView::openInAutomationEditor()
|
||||
{
|
||||
if(getGUI() != nullptr)
|
||||
getGUI()->automationEditor()->open(m_pat);
|
||||
getGUI()->automationEditor()->open(m_clip);
|
||||
}
|
||||
|
||||
|
||||
void AutomationPatternView::update()
|
||||
void AutomationClipView::update()
|
||||
{
|
||||
ToolTip::add(this, m_pat->name());
|
||||
ToolTip::add(this, m_clip->name());
|
||||
|
||||
TrackContentObjectView::update();
|
||||
ClipView::update();
|
||||
}
|
||||
|
||||
|
||||
|
||||
void AutomationPatternView::resetName()
|
||||
void AutomationClipView::resetName()
|
||||
{
|
||||
m_pat->setName( QString() );
|
||||
m_clip->setName( QString() );
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
void AutomationPatternView::changeName()
|
||||
void AutomationClipView::changeName()
|
||||
{
|
||||
QString s = m_pat->name();
|
||||
QString s = m_clip->name();
|
||||
RenameDialog rename_dlg( s );
|
||||
rename_dlg.exec();
|
||||
m_pat->setName( s );
|
||||
m_clip->setName( s );
|
||||
update();
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
void AutomationPatternView::disconnectObject( QAction * _a )
|
||||
void AutomationClipView::disconnectObject( QAction * _a )
|
||||
{
|
||||
JournallingObject * j = Engine::projectJournal()->
|
||||
journallingObject( _a->data().toInt() );
|
||||
if( j && dynamic_cast<AutomatableModel *>( j ) )
|
||||
{
|
||||
float oldMin = m_pat->getMin();
|
||||
float oldMax = m_pat->getMax();
|
||||
float oldMin = m_clip->getMin();
|
||||
float oldMax = m_clip->getMax();
|
||||
|
||||
m_pat->m_objects.erase( std::find( m_pat->m_objects.begin(),
|
||||
m_pat->m_objects.end(),
|
||||
m_clip->m_objects.erase( std::find( m_clip->m_objects.begin(),
|
||||
m_clip->m_objects.end(),
|
||||
dynamic_cast<AutomatableModel *>( j ) ) );
|
||||
update();
|
||||
|
||||
//If automation editor is opened, update its display after disconnection
|
||||
if( getGUI()->automationEditor() )
|
||||
{
|
||||
getGUI()->automationEditor()->m_editor->updateAfterPatternChange();
|
||||
getGUI()->automationEditor()->m_editor->updateAfterClipChange();
|
||||
}
|
||||
|
||||
//if there is no more connection connected to the AutomationPattern
|
||||
if( m_pat->m_objects.size() == 0 )
|
||||
//if there is no more connection connected to the AutomationClip
|
||||
if( m_clip->m_objects.size() == 0 )
|
||||
{
|
||||
//scale the points to fit the new min. and max. value
|
||||
this->scaleTimemapToFit( oldMin, oldMax );
|
||||
@@ -141,34 +141,34 @@ void AutomationPatternView::disconnectObject( QAction * _a )
|
||||
}
|
||||
|
||||
|
||||
void AutomationPatternView::toggleRecording()
|
||||
void AutomationClipView::toggleRecording()
|
||||
{
|
||||
m_pat->setRecording( ! m_pat->isRecording() );
|
||||
m_clip->setRecording( ! m_clip->isRecording() );
|
||||
update();
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
void AutomationPatternView::flipY()
|
||||
void AutomationClipView::flipY()
|
||||
{
|
||||
m_pat->flipY( m_pat->getMin(), m_pat->getMax() );
|
||||
m_clip->flipY( m_clip->getMin(), m_clip->getMax() );
|
||||
update();
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
void AutomationPatternView::flipX()
|
||||
void AutomationClipView::flipX()
|
||||
{
|
||||
m_pat->flipX( m_pat->length() );
|
||||
m_clip->flipX( m_clip->length() );
|
||||
update();
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
void AutomationPatternView::constructContextMenu( QMenu * _cm )
|
||||
void AutomationClipView::constructContextMenu( QMenu * _cm )
|
||||
{
|
||||
QAction * a = new QAction( embed::getIconPixmap( "automation" ),
|
||||
tr( "Open in Automation editor" ), _cm );
|
||||
@@ -179,7 +179,7 @@ void AutomationPatternView::constructContextMenu( QMenu * _cm )
|
||||
_cm->addSeparator();
|
||||
|
||||
_cm->addAction( embed::getIconPixmap( "edit_erase" ),
|
||||
tr( "Clear" ), m_pat, SLOT( clear() ) );
|
||||
tr( "Clear" ), m_clip, SLOT( clear() ) );
|
||||
_cm->addSeparator();
|
||||
|
||||
_cm->addAction( embed::getIconPixmap( "reload" ), tr( "Reset name" ),
|
||||
@@ -196,14 +196,14 @@ void AutomationPatternView::constructContextMenu( QMenu * _cm )
|
||||
_cm->addAction( embed::getIconPixmap( "flip_x" ),
|
||||
tr( "Flip Horizontally (Visible)" ),
|
||||
this, SLOT( flipX() ) );
|
||||
if( !m_pat->m_objects.isEmpty() )
|
||||
if( !m_clip->m_objects.isEmpty() )
|
||||
{
|
||||
_cm->addSeparator();
|
||||
QMenu * m = new QMenu( tr( "%1 Connections" ).
|
||||
arg( m_pat->m_objects.count() ), _cm );
|
||||
for( AutomationPattern::objectVector::iterator it =
|
||||
m_pat->m_objects.begin();
|
||||
it != m_pat->m_objects.end(); ++it )
|
||||
arg( m_clip->m_objects.count() ), _cm );
|
||||
for( AutomationClip::objectVector::iterator it =
|
||||
m_clip->m_objects.begin();
|
||||
it != m_clip->m_objects.end(); ++it )
|
||||
{
|
||||
if( *it )
|
||||
{
|
||||
@@ -222,7 +222,7 @@ void AutomationPatternView::constructContextMenu( QMenu * _cm )
|
||||
|
||||
|
||||
|
||||
void AutomationPatternView::mouseDoubleClickEvent( QMouseEvent * me )
|
||||
void AutomationClipView::mouseDoubleClickEvent( QMouseEvent * me )
|
||||
{
|
||||
if(me->button() != Qt::LeftButton)
|
||||
{
|
||||
@@ -235,7 +235,7 @@ void AutomationPatternView::mouseDoubleClickEvent( QMouseEvent * me )
|
||||
|
||||
|
||||
|
||||
void AutomationPatternView::paintEvent( QPaintEvent * )
|
||||
void AutomationClipView::paintEvent( QPaintEvent * )
|
||||
{
|
||||
QPainter painter( this );
|
||||
|
||||
@@ -256,13 +256,13 @@ void AutomationPatternView::paintEvent( QPaintEvent * )
|
||||
|
||||
QLinearGradient lingrad( 0, 0, 0, height() );
|
||||
QColor c = getColorForDisplay( painter.background().color() );
|
||||
bool muted = m_pat->getTrack()->isMuted() || m_pat->isMuted();
|
||||
bool current = getGUI()->automationEditor()->currentPattern() == m_pat;
|
||||
bool muted = m_clip->getTrack()->isMuted() || m_clip->isMuted();
|
||||
bool current = getGUI()->automationEditor()->currentClip() == m_clip;
|
||||
|
||||
lingrad.setColorAt( 1, c.darker( 300 ) );
|
||||
lingrad.setColorAt( 0, c );
|
||||
|
||||
// paint a black rectangle under the pattern to prevent glitches with transparent backgrounds
|
||||
// paint a black rectangle under the clip to prevent glitches with transparent backgrounds
|
||||
p.fillRect( rect(), QColor( 0, 0, 0 ) );
|
||||
|
||||
if( gradient() )
|
||||
@@ -275,19 +275,19 @@ void AutomationPatternView::paintEvent( QPaintEvent * )
|
||||
}
|
||||
|
||||
// pixels per bar
|
||||
const float ppb = fixedTCOs() ?
|
||||
( parentWidget()->width() - 2 * TCO_BORDER_WIDTH )
|
||||
/ (float) m_pat->timeMapLength().getBar() :
|
||||
const float ppb = fixedClips() ?
|
||||
( parentWidget()->width() - 2 * CLIP_BORDER_WIDTH )
|
||||
/ (float) m_clip->timeMapLength().getBar() :
|
||||
pixelsPerBar();
|
||||
|
||||
const float min = m_pat->firstObject()->minValue<float>();
|
||||
const float max = m_pat->firstObject()->maxValue<float>();
|
||||
const float min = m_clip->firstObject()->minValue<float>();
|
||||
const float max = m_clip->firstObject()->maxValue<float>();
|
||||
|
||||
const float y_scale = max - min;
|
||||
const float h = ( height() - 2 * TCO_BORDER_WIDTH ) / y_scale;
|
||||
const float h = ( height() - 2 * CLIP_BORDER_WIDTH ) / y_scale;
|
||||
const float ppTick = ppb / TimePos::ticksPerBar();
|
||||
|
||||
p.translate( 0.0f, max * height() / y_scale - TCO_BORDER_WIDTH );
|
||||
p.translate( 0.0f, max * height() / y_scale - CLIP_BORDER_WIDTH );
|
||||
p.scale( 1.0f, -h );
|
||||
|
||||
QLinearGradient lin2grad( 0, min, 0, max );
|
||||
@@ -300,15 +300,15 @@ void AutomationPatternView::paintEvent( QPaintEvent * )
|
||||
lin2grad.setColorAt( 0, col.darker( 150 ) );
|
||||
|
||||
p.setRenderHints( QPainter::Antialiasing, true );
|
||||
for( AutomationPattern::timeMap::const_iterator it =
|
||||
m_pat->getTimeMap().begin();
|
||||
it != m_pat->getTimeMap().end(); ++it )
|
||||
for( AutomationClip::timeMap::const_iterator it =
|
||||
m_clip->getTimeMap().begin();
|
||||
it != m_clip->getTimeMap().end(); ++it )
|
||||
{
|
||||
if( it+1 == m_pat->getTimeMap().end() )
|
||||
if( it+1 == m_clip->getTimeMap().end() )
|
||||
{
|
||||
const float x1 = POS(it) * ppTick;
|
||||
const float x2 = (float)( width() - TCO_BORDER_WIDTH );
|
||||
if( x1 > ( width() - TCO_BORDER_WIDTH ) ) break;
|
||||
const float x2 = (float)( width() - CLIP_BORDER_WIDTH );
|
||||
if( x1 > ( width() - CLIP_BORDER_WIDTH ) ) break;
|
||||
// We are drawing the space after the last node, so we use the outValue
|
||||
if( gradient() )
|
||||
{
|
||||
@@ -321,7 +321,7 @@ void AutomationPatternView::paintEvent( QPaintEvent * )
|
||||
break;
|
||||
}
|
||||
|
||||
float *values = m_pat->valuesAfter(POS(it));
|
||||
float *values = m_clip->valuesAfter(POS(it));
|
||||
|
||||
// We are creating a path to draw a polygon representing the values between two
|
||||
// nodes. When we have two nodes with discrete progression, we will basically have
|
||||
@@ -330,7 +330,7 @@ void AutomationPatternView::paintEvent( QPaintEvent * )
|
||||
// the value of the end of the shape between the two nodes will be the inValue of
|
||||
// the next node.
|
||||
float nextValue;
|
||||
if( m_pat->progressionType() == AutomationPattern::DiscreteProgression )
|
||||
if( m_clip->progressionType() == AutomationClip::DiscreteProgression )
|
||||
{
|
||||
nextValue = OUTVAL(it);
|
||||
}
|
||||
@@ -347,7 +347,7 @@ void AutomationPatternView::paintEvent( QPaintEvent * )
|
||||
for (int i = POS(it) + 1; i < POS(it + 1); i++)
|
||||
{
|
||||
x = i * ppTick;
|
||||
if( x > ( width() - TCO_BORDER_WIDTH ) ) break;
|
||||
if( x > ( width() - CLIP_BORDER_WIDTH ) ) break;
|
||||
float value = values[i - POS(it)];
|
||||
path.lineTo( QPointF( x, value ) );
|
||||
|
||||
@@ -374,39 +374,39 @@ void AutomationPatternView::paintEvent( QPaintEvent * )
|
||||
const int lineSize = 3;
|
||||
p.setPen( c.darker( 300 ) );
|
||||
|
||||
for (bar_t b = 1; b < width() - TCO_BORDER_WIDTH; ++b)
|
||||
for (bar_t b = 1; b < width() - CLIP_BORDER_WIDTH; ++b)
|
||||
{
|
||||
const int bx = TCO_BORDER_WIDTH + static_cast<int>(ppb * b) - 2;
|
||||
const int bx = CLIP_BORDER_WIDTH + static_cast<int>(ppb * b) - 2;
|
||||
|
||||
//top line
|
||||
p.drawLine(bx, TCO_BORDER_WIDTH, bx, TCO_BORDER_WIDTH + lineSize);
|
||||
p.drawLine(bx, CLIP_BORDER_WIDTH, bx, CLIP_BORDER_WIDTH + lineSize);
|
||||
|
||||
//bottom line
|
||||
p.drawLine(bx, rect().bottom() - (lineSize + TCO_BORDER_WIDTH), bx, rect().bottom() - TCO_BORDER_WIDTH);
|
||||
p.drawLine(bx, rect().bottom() - (lineSize + CLIP_BORDER_WIDTH), bx, rect().bottom() - CLIP_BORDER_WIDTH);
|
||||
}
|
||||
|
||||
// recording icon for when recording automation
|
||||
if( m_pat->isRecording() )
|
||||
if( m_clip->isRecording() )
|
||||
{
|
||||
p.drawPixmap( 1, rect().bottom() - s_pat_rec->height(), *s_pat_rec );
|
||||
p.drawPixmap( 1, rect().bottom() - s_clip_rec->height(), *s_clip_rec );
|
||||
}
|
||||
|
||||
// pattern name
|
||||
paintTextLabel(m_pat->name(), p);
|
||||
// clip name
|
||||
paintTextLabel(m_clip->name(), p);
|
||||
|
||||
// inner border
|
||||
p.setPen( c.lighter( current ? 160 : 130 ) );
|
||||
p.drawRect( 1, 1, rect().right() - TCO_BORDER_WIDTH,
|
||||
rect().bottom() - TCO_BORDER_WIDTH );
|
||||
p.drawRect( 1, 1, rect().right() - CLIP_BORDER_WIDTH,
|
||||
rect().bottom() - CLIP_BORDER_WIDTH );
|
||||
|
||||
// outer border
|
||||
p.setPen( current? c.lighter( 130 ) : c.darker( 300 ) );
|
||||
p.drawRect( 0, 0, rect().right(), rect().bottom() );
|
||||
|
||||
// draw the 'muted' pixmap only if the pattern was manualy muted
|
||||
if( m_pat->isMuted() )
|
||||
// draw the 'muted' pixmap only if the clip was manualy muted
|
||||
if( m_clip->isMuted() )
|
||||
{
|
||||
const int spacing = TCO_BORDER_WIDTH;
|
||||
const int spacing = CLIP_BORDER_WIDTH;
|
||||
const int size = 14;
|
||||
p.drawPixmap( spacing, height() - ( size + spacing ),
|
||||
embed::getIconPixmap( "muted", size, size ) );
|
||||
@@ -420,19 +420,19 @@ void AutomationPatternView::paintEvent( QPaintEvent * )
|
||||
|
||||
|
||||
|
||||
void AutomationPatternView::dragEnterEvent( QDragEnterEvent * _dee )
|
||||
void AutomationClipView::dragEnterEvent( QDragEnterEvent * _dee )
|
||||
{
|
||||
StringPairDrag::processDragEnterEvent( _dee, "automatable_model" );
|
||||
if( !_dee->isAccepted() )
|
||||
{
|
||||
TrackContentObjectView::dragEnterEvent( _dee );
|
||||
ClipView::dragEnterEvent( _dee );
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
void AutomationPatternView::dropEvent( QDropEvent * _de )
|
||||
void AutomationClipView::dropEvent( QDropEvent * _de )
|
||||
{
|
||||
QString type = StringPairDrag::decodeKey( _de );
|
||||
QString val = StringPairDrag::decodeValue( _de );
|
||||
@@ -443,12 +443,12 @@ void AutomationPatternView::dropEvent( QDropEvent * _de )
|
||||
journallingObject( val.toInt() ) );
|
||||
if( mod != nullptr )
|
||||
{
|
||||
bool added = m_pat->addObject( mod );
|
||||
bool added = m_clip->addObject( mod );
|
||||
if ( !added )
|
||||
{
|
||||
TextFloat::displayMessage( mod->displayName(),
|
||||
tr( "Model is already connected "
|
||||
"to this pattern." ),
|
||||
"to this clip." ),
|
||||
embed::getIconPixmap( "automation" ),
|
||||
2000 );
|
||||
}
|
||||
@@ -456,14 +456,14 @@ void AutomationPatternView::dropEvent( QDropEvent * _de )
|
||||
update();
|
||||
|
||||
if( getGUI()->automationEditor() &&
|
||||
getGUI()->automationEditor()->currentPattern() == m_pat )
|
||||
getGUI()->automationEditor()->currentClip() == m_clip )
|
||||
{
|
||||
getGUI()->automationEditor()->setCurrentPattern( m_pat );
|
||||
getGUI()->automationEditor()->setCurrentClip( m_clip );
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
TrackContentObjectView::dropEvent( _de );
|
||||
ClipView::dropEvent( _de );
|
||||
}
|
||||
}
|
||||
|
||||
@@ -473,10 +473,10 @@ void AutomationPatternView::dropEvent( QDropEvent * _de )
|
||||
/**
|
||||
* @brief Preserves the auto points over different scale
|
||||
*/
|
||||
void AutomationPatternView::scaleTimemapToFit( float oldMin, float oldMax )
|
||||
void AutomationClipView::scaleTimemapToFit( float oldMin, float oldMax )
|
||||
{
|
||||
float newMin = m_pat->getMin();
|
||||
float newMax = m_pat->getMax();
|
||||
float newMin = m_clip->getMin();
|
||||
float newMax = m_clip->getMax();
|
||||
|
||||
if( oldMin == newMin && oldMax == newMax )
|
||||
{
|
||||
@@ -487,8 +487,8 @@ void AutomationPatternView::scaleTimemapToFit( float oldMin, float oldMax )
|
||||
// only the inValue is being considered and the outValue is being reset to the inValue (so discrete jumps
|
||||
// are discarded). Possibly later we will want discrete jumps to be maintained so we will need to upgrade
|
||||
// the logic to account for them.
|
||||
for( AutomationPattern::timeMap::iterator it = m_pat->m_timeMap.begin();
|
||||
it != m_pat->m_timeMap.end(); ++it )
|
||||
for( AutomationClip::timeMap::iterator it = m_clip->m_timeMap.begin();
|
||||
it != m_clip->m_timeMap.end(); ++it )
|
||||
{
|
||||
// If the values are out of the previous range, fix them so they are
|
||||
// between oldMin and oldMax.
|
||||
@@ -506,5 +506,5 @@ void AutomationPatternView::scaleTimemapToFit( float oldMin, float oldMax )
|
||||
it.value().setOutValue(INVAL(it));
|
||||
}
|
||||
|
||||
m_pat->generateTangents();
|
||||
m_clip->generateTangents();
|
||||
}
|
||||
@@ -25,7 +25,7 @@
|
||||
|
||||
#include "AutomationTrackView.h"
|
||||
|
||||
#include "AutomationPattern.h"
|
||||
#include "AutomationClip.h"
|
||||
#include "embed.h"
|
||||
#include "Engine.h"
|
||||
#include "ProjectJournal.h"
|
||||
@@ -78,9 +78,9 @@ void AutomationTrackView::dropEvent( QDropEvent * _de )
|
||||
pos.setTicks( 0 );
|
||||
}
|
||||
|
||||
TrackContentObject * tco = getTrack()->createTCO( pos );
|
||||
AutomationPattern * pat = dynamic_cast<AutomationPattern *>( tco );
|
||||
pat->addObject( mod );
|
||||
Clip * clip = getTrack()->createClip( pos );
|
||||
AutomationClip * autoClip = dynamic_cast<AutomationClip *>( clip );
|
||||
autoClip->addObject( mod );
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* BBTCOView.cpp
|
||||
* BBClipView.cpp
|
||||
*
|
||||
* Copyright (c) 2004-2014 Tobias Doerffel <tobydox/at/users.sourceforge.net>
|
||||
*
|
||||
@@ -22,7 +22,7 @@
|
||||
*
|
||||
*/
|
||||
|
||||
#include "BBTCOView.h"
|
||||
#include "BBClipView.h"
|
||||
|
||||
#include <QMenu>
|
||||
#include <QPainter>
|
||||
@@ -36,18 +36,18 @@
|
||||
#include "Song.h"
|
||||
#include "ToolTip.h"
|
||||
|
||||
BBTCOView::BBTCOView( TrackContentObject * _tco, TrackView * _tv ) :
|
||||
TrackContentObjectView( _tco, _tv ),
|
||||
m_bbTCO( dynamic_cast<BBTCO *>( _tco ) ),
|
||||
BBClipView::BBClipView( Clip * _clip, TrackView * _tv ) :
|
||||
ClipView( _clip, _tv ),
|
||||
m_bbClip( dynamic_cast<BBClip *>( _clip ) ),
|
||||
m_paintPixmap()
|
||||
{
|
||||
connect( _tco->getTrack(), SIGNAL( dataChanged() ),
|
||||
connect( _clip->getTrack(), SIGNAL( dataChanged() ),
|
||||
this, SLOT( update() ) );
|
||||
|
||||
setStyle( QApplication::style() );
|
||||
}
|
||||
|
||||
void BBTCOView::constructContextMenu( QMenu * _cm )
|
||||
void BBClipView::constructContextMenu( QMenu * _cm )
|
||||
{
|
||||
QAction * a = new QAction( embed::getIconPixmap( "bb_track" ),
|
||||
tr( "Open in Beat+Bassline-Editor" ),
|
||||
@@ -67,7 +67,7 @@ void BBTCOView::constructContextMenu( QMenu * _cm )
|
||||
|
||||
|
||||
|
||||
void BBTCOView::mouseDoubleClickEvent( QMouseEvent * )
|
||||
void BBClipView::mouseDoubleClickEvent( QMouseEvent * )
|
||||
{
|
||||
openInBBEditor();
|
||||
}
|
||||
@@ -75,7 +75,7 @@ void BBTCOView::mouseDoubleClickEvent( QMouseEvent * )
|
||||
|
||||
|
||||
|
||||
void BBTCOView::paintEvent( QPaintEvent * )
|
||||
void BBClipView::paintEvent( QPaintEvent * )
|
||||
{
|
||||
QPainter painter( this );
|
||||
|
||||
@@ -100,7 +100,7 @@ void BBTCOView::paintEvent( QPaintEvent * )
|
||||
lingrad.setColorAt( 0, c.lighter( 130 ) );
|
||||
lingrad.setColorAt( 1, c.lighter( 70 ) );
|
||||
|
||||
// paint a black rectangle under the pattern to prevent glitches with transparent backgrounds
|
||||
// paint a black rectangle under the clip to prevent glitches with transparent backgrounds
|
||||
p.fillRect( rect(), QColor( 0, 0, 0 ) );
|
||||
|
||||
if( gradient() )
|
||||
@@ -116,35 +116,35 @@ void BBTCOView::paintEvent( QPaintEvent * )
|
||||
const int lineSize = 3;
|
||||
p.setPen( c.darker( 200 ) );
|
||||
|
||||
bar_t t = Engine::getBBTrackContainer()->lengthOfBB( m_bbTCO->bbTrackIndex() );
|
||||
if( m_bbTCO->length() > TimePos::ticksPerBar() && t > 0 )
|
||||
bar_t t = Engine::getBBTrackContainer()->lengthOfBB( m_bbClip->bbTrackIndex() );
|
||||
if( m_bbClip->length() > TimePos::ticksPerBar() && t > 0 )
|
||||
{
|
||||
for( int x = static_cast<int>( t * pixelsPerBar() );
|
||||
x < width() - 2;
|
||||
x += static_cast<int>( t * pixelsPerBar() ) )
|
||||
{
|
||||
p.drawLine( x, TCO_BORDER_WIDTH, x, TCO_BORDER_WIDTH + lineSize );
|
||||
p.drawLine( x, rect().bottom() - ( TCO_BORDER_WIDTH + lineSize ),
|
||||
x, rect().bottom() - TCO_BORDER_WIDTH );
|
||||
p.drawLine( x, CLIP_BORDER_WIDTH, x, CLIP_BORDER_WIDTH + lineSize );
|
||||
p.drawLine( x, rect().bottom() - ( CLIP_BORDER_WIDTH + lineSize ),
|
||||
x, rect().bottom() - CLIP_BORDER_WIDTH );
|
||||
}
|
||||
}
|
||||
|
||||
// pattern name
|
||||
paintTextLabel(m_bbTCO->name(), p);
|
||||
// clip name
|
||||
paintTextLabel(m_bbClip->name(), p);
|
||||
|
||||
// inner border
|
||||
p.setPen( c.lighter( 130 ) );
|
||||
p.drawRect( 1, 1, rect().right() - TCO_BORDER_WIDTH,
|
||||
rect().bottom() - TCO_BORDER_WIDTH );
|
||||
p.drawRect( 1, 1, rect().right() - CLIP_BORDER_WIDTH,
|
||||
rect().bottom() - CLIP_BORDER_WIDTH );
|
||||
|
||||
// outer border
|
||||
p.setPen( c.darker( 300 ) );
|
||||
p.drawRect( 0, 0, rect().right(), rect().bottom() );
|
||||
|
||||
// draw the 'muted' pixmap only if the pattern was manualy muted
|
||||
if( m_bbTCO->isMuted() )
|
||||
// draw the 'muted' pixmap only if the clip was manualy muted
|
||||
if( m_bbClip->isMuted() )
|
||||
{
|
||||
const int spacing = TCO_BORDER_WIDTH;
|
||||
const int spacing = CLIP_BORDER_WIDTH;
|
||||
const int size = 14;
|
||||
p.drawPixmap( spacing, height() - ( size + spacing ),
|
||||
embed::getIconPixmap( "muted", size, size ) );
|
||||
@@ -158,9 +158,9 @@ void BBTCOView::paintEvent( QPaintEvent * )
|
||||
|
||||
|
||||
|
||||
void BBTCOView::openInBBEditor()
|
||||
void BBClipView::openInBBEditor()
|
||||
{
|
||||
Engine::getBBTrackContainer()->setCurrentBB( m_bbTCO->bbTrackIndex() );
|
||||
Engine::getBBTrackContainer()->setCurrentBB( m_bbClip->bbTrackIndex() );
|
||||
|
||||
getGUI()->mainWindow()->toggleBBEditorWin( true );
|
||||
}
|
||||
@@ -168,24 +168,24 @@ void BBTCOView::openInBBEditor()
|
||||
|
||||
|
||||
|
||||
void BBTCOView::resetName() { m_bbTCO->setName(""); }
|
||||
void BBClipView::resetName() { m_bbClip->setName(""); }
|
||||
|
||||
|
||||
|
||||
|
||||
void BBTCOView::changeName()
|
||||
void BBClipView::changeName()
|
||||
{
|
||||
QString s = m_bbTCO->name();
|
||||
QString s = m_bbClip->name();
|
||||
RenameDialog rename_dlg( s );
|
||||
rename_dlg.exec();
|
||||
m_bbTCO->setName( s );
|
||||
m_bbClip->setName( s );
|
||||
}
|
||||
|
||||
|
||||
|
||||
void BBTCOView::update()
|
||||
void BBClipView::update()
|
||||
{
|
||||
ToolTip::add(this, m_bbTCO->name());
|
||||
ToolTip::add(this, m_bbClip->name());
|
||||
|
||||
TrackContentObjectView::update();
|
||||
ClipView::update();
|
||||
}
|
||||
@@ -5,18 +5,18 @@ SET(LMMS_SRCS
|
||||
gui/AudioAlsaSetupWidget.cpp
|
||||
gui/AudioDeviceSetupWidget.cpp
|
||||
gui/AutomatableModelView.cpp
|
||||
gui/AutomationPatternView.cpp
|
||||
gui/AutomationClipView.cpp
|
||||
gui/AutomationTrackView.cpp
|
||||
gui/ControllerConnectionDialog.cpp
|
||||
gui/ControllerDialog.cpp
|
||||
gui/BBTCOView.cpp
|
||||
gui/BBClipView.cpp
|
||||
gui/BBTrackView.cpp
|
||||
gui/EffectControlDialog.cpp
|
||||
gui/EffectSelectDialog.cpp
|
||||
gui/embed.cpp
|
||||
gui/ExportProjectDialog.cpp
|
||||
gui/FileBrowser.cpp
|
||||
gui/FxMixerView.cpp
|
||||
gui/MixerView.cpp
|
||||
gui/GuiApplication.cpp
|
||||
gui/InstrumentView.cpp
|
||||
gui/InstrumentTrackView.cpp
|
||||
@@ -28,14 +28,14 @@ SET(LMMS_SRCS
|
||||
gui/MainApplication.cpp
|
||||
gui/MainWindow.cpp
|
||||
gui/MidiCCRackView.cpp
|
||||
gui/MidiClipView.cpp
|
||||
gui/MidiSetupWidget.cpp
|
||||
gui/ModelView.cpp
|
||||
gui/PatternView.cpp
|
||||
gui/PeakControllerDialog.cpp
|
||||
gui/PianoView.cpp
|
||||
gui/PluginBrowser.cpp
|
||||
gui/RowTableView.cpp
|
||||
gui/SampleTCOView.cpp
|
||||
gui/SampleClipView.cpp
|
||||
gui/SampleTrackView.cpp
|
||||
gui/SampleTrackWindow.cpp
|
||||
gui/SetupDialog.cpp
|
||||
@@ -44,7 +44,7 @@ SET(LMMS_SRCS
|
||||
gui/TimeLineWidget.cpp
|
||||
gui/ToolPluginView.cpp
|
||||
gui/TrackContainerView.cpp
|
||||
gui/TrackContentObjectView.cpp
|
||||
gui/ClipView.cpp
|
||||
gui/TrackView.cpp
|
||||
|
||||
gui/dialogs/FileDialog.cpp
|
||||
@@ -74,8 +74,8 @@ SET(LMMS_SRCS
|
||||
gui/widgets/EnvelopeAndLfoView.cpp
|
||||
gui/widgets/FadeButton.cpp
|
||||
gui/widgets/Fader.cpp
|
||||
gui/widgets/FxLine.cpp
|
||||
gui/widgets/FxLineLcdSpinBox.cpp
|
||||
gui/widgets/MixerLine.cpp
|
||||
gui/widgets/MixerLineLcdSpinBox.cpp
|
||||
gui/widgets/Graph.cpp
|
||||
gui/widgets/GroupBox.cpp
|
||||
gui/widgets/InstrumentFunctionViews.cpp
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -859,7 +859,7 @@ bool FileBrowserTreeWidget::openInNewSampleTrack(FileItem* item)
|
||||
|
||||
// Add the sample clip to the track
|
||||
Engine::audioEngine()->requestChangeInModel();
|
||||
SampleTCO* clip = static_cast<SampleTCO*>(sampleTrack->createTCO(0));
|
||||
SampleClip* clip = static_cast<SampleClip*>(sampleTrack->createClip(0));
|
||||
clip->setSampleFile(item->fullName());
|
||||
Engine::audioEngine()->doneChangeInModel();
|
||||
return true;
|
||||
|
||||
@@ -33,7 +33,7 @@
|
||||
#include "BBEditor.h"
|
||||
#include "ConfigManager.h"
|
||||
#include "ControllerRackView.h"
|
||||
#include "FxMixerView.h"
|
||||
#include "MixerView.h"
|
||||
#include "InstrumentTrack.h"
|
||||
#include "MainWindow.h"
|
||||
#include "MicrotunerConfig.h"
|
||||
@@ -138,8 +138,8 @@ GuiApplication::GuiApplication()
|
||||
connect(m_songEditor, SIGNAL(destroyed(QObject*)), this, SLOT(childDestroyed(QObject*)));
|
||||
|
||||
displayInitProgress(tr("Preparing mixer"));
|
||||
m_fxMixerView = new FxMixerView;
|
||||
connect(m_fxMixerView, SIGNAL(destroyed(QObject*)), this, SLOT(childDestroyed(QObject*)));
|
||||
m_mixerView = new MixerView;
|
||||
connect(m_mixerView, SIGNAL(destroyed(QObject*)), this, SLOT(childDestroyed(QObject*)));
|
||||
|
||||
displayInitProgress(tr("Preparing controller rack"));
|
||||
m_controllerRackView = new ControllerRackView;
|
||||
@@ -189,15 +189,15 @@ void GuiApplication::displayInitProgress(const QString &msg)
|
||||
|
||||
void GuiApplication::childDestroyed(QObject *obj)
|
||||
{
|
||||
// when any object that can be reached via getGUI()->mainWindow(), getGUI()->fxMixerView(), etc
|
||||
// when any object that can be reached via getGUI()->mainWindow(), getGUI()->mixerView(), etc
|
||||
// is destroyed, ensure that their accessor functions will return null instead of a garbage pointer.
|
||||
if (obj == m_mainWindow)
|
||||
{
|
||||
m_mainWindow = nullptr;
|
||||
}
|
||||
else if (obj == m_fxMixerView)
|
||||
else if (obj == m_mixerView)
|
||||
{
|
||||
m_fxMixerView = nullptr;
|
||||
m_mixerView = nullptr;
|
||||
}
|
||||
else if (obj == m_songEditor)
|
||||
{
|
||||
|
||||
@@ -36,9 +36,9 @@
|
||||
#include "ControllerConnectionDialog.h"
|
||||
#include "Engine.h"
|
||||
#include "FadeButton.h"
|
||||
#include "FxLineLcdSpinBox.h"
|
||||
#include "FxMixer.h"
|
||||
#include "FxMixerView.h"
|
||||
#include "MixerLineLcdSpinBox.h"
|
||||
#include "Mixer.h"
|
||||
#include "MixerView.h"
|
||||
#include "GuiApplication.h"
|
||||
#include "InstrumentTrack.h"
|
||||
#include "InstrumentTrackWindow.h"
|
||||
@@ -219,27 +219,27 @@ InstrumentTrackWindow * InstrumentTrackView::topLevelInstrumentTrackWindow()
|
||||
|
||||
|
||||
|
||||
/*! \brief Create and assign a new FX Channel for this track */
|
||||
void InstrumentTrackView::createFxLine()
|
||||
/*! \brief Create and assign a new mixer Channel for this track */
|
||||
void InstrumentTrackView::createMixerLine()
|
||||
{
|
||||
int channelIndex = getGUI()->fxMixerView()->addNewChannel();
|
||||
auto channel = Engine::fxMixer()->effectChannel(channelIndex);
|
||||
int channelIndex = getGUI()->mixerView()->addNewChannel();
|
||||
auto channel = Engine::mixer()->mixerChannel(channelIndex);
|
||||
|
||||
channel->m_name = getTrack()->name();
|
||||
if (getTrack()->useColor()) { channel->setColor (getTrack()->color()); }
|
||||
|
||||
assignFxLine(channelIndex);
|
||||
assignMixerLine(channelIndex);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
/*! \brief Assign a specific FX Channel for this track */
|
||||
void InstrumentTrackView::assignFxLine(int channelIndex)
|
||||
/*! \brief Assign a specific mixer Channel for this track */
|
||||
void InstrumentTrackView::assignMixerLine(int channelIndex)
|
||||
{
|
||||
model()->effectChannelModel()->setValue( channelIndex );
|
||||
model()->mixerChannelModel()->setValue( channelIndex );
|
||||
|
||||
getGUI()->fxMixerView()->setCurrentFxLine( channelIndex );
|
||||
getGUI()->mixerView()->setCurrentMixerLine( channelIndex );
|
||||
}
|
||||
|
||||
|
||||
@@ -349,38 +349,38 @@ void InstrumentTrackView::midiConfigChanged()
|
||||
|
||||
|
||||
|
||||
//FIXME: This is identical to SampleTrackView::createFxMenu
|
||||
QMenu * InstrumentTrackView::createFxMenu(QString title, QString newFxLabel)
|
||||
//FIXME: This is identical to SampleTrackView::createMixerMenu
|
||||
QMenu * InstrumentTrackView::createMixerMenu(QString title, QString newMixerLabel)
|
||||
{
|
||||
int channelIndex = model()->effectChannelModel()->value();
|
||||
int channelIndex = model()->mixerChannelModel()->value();
|
||||
|
||||
FxChannel *fxChannel = Engine::fxMixer()->effectChannel( channelIndex );
|
||||
MixerChannel *mixerChannel = Engine::mixer()->mixerChannel( channelIndex );
|
||||
|
||||
// If title allows interpolation, pass channel index and name
|
||||
if ( title.contains( "%2" ) )
|
||||
{
|
||||
title = title.arg( channelIndex ).arg( fxChannel->m_name );
|
||||
title = title.arg( channelIndex ).arg( mixerChannel->m_name );
|
||||
}
|
||||
|
||||
QMenu *fxMenu = new QMenu( title );
|
||||
QMenu *mixerMenu = new QMenu( title );
|
||||
|
||||
fxMenu->addAction( newFxLabel, this, SLOT( createFxLine() ) );
|
||||
fxMenu->addSeparator();
|
||||
mixerMenu->addAction( newMixerLabel, this, SLOT( createMixerLine() ) );
|
||||
mixerMenu->addSeparator();
|
||||
|
||||
for (int i = 0; i < Engine::fxMixer()->numChannels(); ++i)
|
||||
for (int i = 0; i < Engine::mixer()->numChannels(); ++i)
|
||||
{
|
||||
FxChannel * currentChannel = Engine::fxMixer()->effectChannel( i );
|
||||
MixerChannel * currentChannel = Engine::mixer()->mixerChannel( i );
|
||||
|
||||
if ( currentChannel != fxChannel )
|
||||
if ( currentChannel != mixerChannel )
|
||||
{
|
||||
auto index = currentChannel->m_channelIndex;
|
||||
QString label = tr( "FX %1: %2" ).arg( currentChannel->m_channelIndex ).arg( currentChannel->m_name );
|
||||
fxMenu->addAction(label, [this, index](){
|
||||
assignFxLine(index);
|
||||
QString label = tr( "%1: %2" ).arg( currentChannel->m_channelIndex ).arg( currentChannel->m_name );
|
||||
mixerMenu->addAction(label, [this, index](){
|
||||
assignMixerLine(index);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
return fxMenu;
|
||||
return mixerMenu;
|
||||
}
|
||||
|
||||
|
||||
@@ -40,8 +40,8 @@
|
||||
#include "Engine.h"
|
||||
#include "FileBrowser.h"
|
||||
#include "FileDialog.h"
|
||||
#include "FxLineLcdSpinBox.h"
|
||||
#include "FxMixer.h"
|
||||
#include "MixerLineLcdSpinBox.h"
|
||||
#include "Mixer.h"
|
||||
#include "GuiApplication.h"
|
||||
#include "gui_templates.h"
|
||||
#include "Instrument.h"
|
||||
@@ -190,13 +190,13 @@ InstrumentTrackWindow::InstrumentTrackWindow( InstrumentTrackView * _itv ) :
|
||||
basicControlsLayout->setColumnStretch(5, 1);
|
||||
|
||||
|
||||
// setup spinbox for selecting FX-channel
|
||||
m_effectChannelNumber = new FxLineLcdSpinBox( 2, nullptr, tr( "FX channel" ), m_itv );
|
||||
// setup spinbox for selecting Mixer-channel
|
||||
m_mixerChannelNumber = new MixerLineLcdSpinBox( 2, nullptr, tr( "Mixer channel" ), m_itv );
|
||||
|
||||
basicControlsLayout->addWidget( m_effectChannelNumber, 0, 6 );
|
||||
basicControlsLayout->setAlignment( m_effectChannelNumber, widgetAlignment );
|
||||
basicControlsLayout->addWidget( m_mixerChannelNumber, 0, 6 );
|
||||
basicControlsLayout->setAlignment( m_mixerChannelNumber, widgetAlignment );
|
||||
|
||||
label = new QLabel( tr( "FX" ), this );
|
||||
label = new QLabel( tr( "CHANNEL" ), this );
|
||||
label->setStyleSheet( labelStyleSheet );
|
||||
basicControlsLayout->addWidget( label, 1, 6);
|
||||
basicControlsLayout->setAlignment( label, labelAlignment );
|
||||
@@ -316,7 +316,7 @@ void InstrumentTrackWindow::setInstrumentTrackView( InstrumentTrackView* view )
|
||||
}
|
||||
|
||||
m_itv = view;
|
||||
m_effectChannelNumber->setTrackView(m_itv);
|
||||
m_mixerChannelNumber->setTrackView(m_itv);
|
||||
}
|
||||
|
||||
|
||||
@@ -338,7 +338,7 @@ void InstrumentTrackWindow::modelChanged()
|
||||
|
||||
m_volumeKnob->setModel( &m_track->m_volumeModel );
|
||||
m_panningKnob->setModel( &m_track->m_panningModel );
|
||||
m_effectChannelNumber->setModel( &m_track->m_effectChannelModel );
|
||||
m_mixerChannelNumber->setModel( &m_track->m_mixerChannelModel );
|
||||
m_pianoView->setModel( &m_track->m_piano );
|
||||
|
||||
if( m_track->instrument() && m_track->instrument()->flags().testFlag( Instrument::IsNotBendable ) == false )
|
||||
@@ -387,20 +387,20 @@ void InstrumentTrackWindow::modelChanged()
|
||||
|
||||
void InstrumentTrackWindow::saveSettingsBtnClicked()
|
||||
{
|
||||
FileDialog sfd( this, tr( "Save preset" ), "", tr( "XML preset file (*.xpf)" ) );
|
||||
FileDialog sfd(this, tr("Save preset"), "", tr("XML preset file (*.xpf)"));
|
||||
|
||||
QString presetRoot = ConfigManager::inst()->userPresetsDir();
|
||||
if( !QDir( presetRoot ).exists() )
|
||||
if(!QDir(presetRoot).exists())
|
||||
{
|
||||
QDir().mkdir( presetRoot );
|
||||
QDir().mkdir(presetRoot);
|
||||
}
|
||||
if( !QDir( presetRoot + m_track->instrumentName() ).exists() )
|
||||
if(!QDir(presetRoot + m_track->instrumentName()).exists())
|
||||
{
|
||||
QDir( presetRoot ).mkdir( m_track->instrumentName() );
|
||||
QDir(presetRoot).mkdir(m_track->instrumentName());
|
||||
}
|
||||
|
||||
sfd.setAcceptMode( FileDialog::AcceptSave );
|
||||
sfd.setDirectory( presetRoot + m_track->instrumentName() );
|
||||
sfd.setAcceptMode(FileDialog::AcceptSave);
|
||||
sfd.setDirectory(presetRoot + m_track->instrumentName());
|
||||
sfd.setFileMode( FileDialog::AnyFile );
|
||||
QString fname = m_track->name();
|
||||
sfd.selectFile(fname.remove(QRegExp(FILENAME_FILTER)));
|
||||
@@ -410,11 +410,17 @@ void InstrumentTrackWindow::saveSettingsBtnClicked()
|
||||
!sfd.selectedFiles().isEmpty() &&
|
||||
!sfd.selectedFiles().first().isEmpty() )
|
||||
{
|
||||
DataFile dataFile( DataFile::InstrumentTrackSettings );
|
||||
DataFile dataFile(DataFile::InstrumentTrackSettings);
|
||||
QDomElement& content(dataFile.content());
|
||||
|
||||
m_track->setSimpleSerializing();
|
||||
m_track->saveSettings( dataFile, dataFile.content() );
|
||||
m_track->saveSettings(dataFile, content);
|
||||
//We don't want to save muted & solo settings when we're saving a preset
|
||||
content.setAttribute("muted", 0);
|
||||
content.setAttribute("solo", 0);
|
||||
content.setAttribute("mutedBeforeSolo", 0);
|
||||
QString f = sfd.selectedFiles()[0];
|
||||
dataFile.writeFile( f );
|
||||
dataFile.writeFile(f);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -45,11 +45,11 @@ QLinearGradient getGradient( const QColor & _col, const QRectF & _rect )
|
||||
qreal saturation = _col.saturationF();
|
||||
|
||||
QColor c = _col;
|
||||
c.setHsvF( hue, 0.42 * saturation, 0.98 * value ); // TODO: pattern: 1.08
|
||||
c.setHsvF( hue, 0.42 * saturation, 0.98 * value ); // TODO: MIDI clip: 1.08
|
||||
g.setColorAt( 0, c );
|
||||
c.setHsvF( hue, 0.58 * saturation, 0.95 * value ); // TODO: pattern: 1.05
|
||||
c.setHsvF( hue, 0.58 * saturation, 0.95 * value ); // TODO: MIDI clip: 1.05
|
||||
g.setColorAt( 0.25, c );
|
||||
c.setHsvF( hue, 0.70 * saturation, 0.93 * value ); // TODO: pattern: 1.03
|
||||
c.setHsvF( hue, 0.70 * saturation, 0.93 * value ); // TODO: MIDI clip: 1.03
|
||||
g.setColorAt( 0.5, c );
|
||||
|
||||
c.setHsvF( hue, 0.95 * saturation, 0.9 * value );
|
||||
|
||||
@@ -48,7 +48,7 @@
|
||||
#include "ExportProjectDialog.h"
|
||||
#include "FileBrowser.h"
|
||||
#include "FileDialog.h"
|
||||
#include "FxMixerView.h"
|
||||
#include "MixerView.h"
|
||||
#include "GuiApplication.h"
|
||||
#include "ImportFilter.h"
|
||||
#include "InstrumentTrackView.h"
|
||||
@@ -526,12 +526,12 @@ void MainWindow::finalize()
|
||||
m_toolBar );
|
||||
automation_editor_window->setShortcut( Qt::CTRL + Qt::Key_4 );
|
||||
|
||||
ToolButton * fx_mixer_window = new ToolButton(
|
||||
embed::getIconPixmap( "fx_mixer" ),
|
||||
tr( "FX Mixer" ) + " (Ctrl+5)",
|
||||
this, SLOT( toggleFxMixerWin() ),
|
||||
ToolButton * mixer_window = new ToolButton(
|
||||
embed::getIconPixmap( "mixer" ),
|
||||
tr( "Mixer" ) + " (Ctrl+5)",
|
||||
this, SLOT( toggleMixerWin() ),
|
||||
m_toolBar );
|
||||
fx_mixer_window->setShortcut( Qt::CTRL + Qt::Key_5 );
|
||||
mixer_window->setShortcut( Qt::CTRL + Qt::Key_5 );
|
||||
|
||||
ToolButton * controllers_window = new ToolButton(
|
||||
embed::getIconPixmap( "controller" ),
|
||||
@@ -561,7 +561,7 @@ void MainWindow::finalize()
|
||||
m_toolBarLayout->addWidget( bb_editor_window, 1, 2 );
|
||||
m_toolBarLayout->addWidget( piano_roll_window, 1, 3 );
|
||||
m_toolBarLayout->addWidget( automation_editor_window, 1, 4 );
|
||||
m_toolBarLayout->addWidget( fx_mixer_window, 1, 5 );
|
||||
m_toolBarLayout->addWidget( mixer_window, 1, 5 );
|
||||
m_toolBarLayout->addWidget( controllers_window, 1, 6 );
|
||||
m_toolBarLayout->addWidget( project_notes_window, 1, 7 );
|
||||
m_toolBarLayout->addWidget( microtuner_window, 1, 8 );
|
||||
@@ -579,7 +579,7 @@ void MainWindow::finalize()
|
||||
// user and is using AudioDummy as a fallback
|
||||
// or the audio device is set to invalid one
|
||||
else if( Engine::audioEngine()->audioDevStartFailed() || !AudioEngine::isAudioDevNameValid(
|
||||
ConfigManager::inst()->value( "mixer", "audiodev" ) ) )
|
||||
ConfigManager::inst()->value( "audioengine", "audiodev" ) ) )
|
||||
{
|
||||
// if so, offer the audio settings section of the setup dialog
|
||||
SetupDialog sd( SetupDialog::AudioSettings );
|
||||
@@ -745,7 +745,7 @@ void MainWindow::clearKeyModifiers()
|
||||
|
||||
void MainWindow::saveWidgetState( QWidget * _w, QDomElement & _de )
|
||||
{
|
||||
// If our widget is the main content of a window (e.g. piano roll, FxMixer, etc),
|
||||
// If our widget is the main content of a window (e.g. piano roll, Mixer, etc),
|
||||
// we really care about the position of the *window* - not the position of the widget within its window
|
||||
if( _w->parentWidget() != nullptr &&
|
||||
_w->parentWidget()->inherits( "QMdiSubWindow" ) )
|
||||
@@ -782,7 +782,7 @@ void MainWindow::restoreWidgetState( QWidget * _w, const QDomElement & _de )
|
||||
qMax( _w->minimumHeight(), _de.attribute( "height" ).toInt() ) );
|
||||
if( _de.hasAttribute( "visible" ) && !r.isNull() )
|
||||
{
|
||||
// If our widget is the main content of a window (e.g. piano roll, FxMixer, etc),
|
||||
// If our widget is the main content of a window (e.g. piano roll, Mixer, etc),
|
||||
// we really care about the position of the *window* - not the position of the widget within its window
|
||||
if ( _w->parentWidget() != nullptr &&
|
||||
_w->parentWidget()->inherits( "QMdiSubWindow" ) )
|
||||
@@ -1118,9 +1118,9 @@ void MainWindow::toggleAutomationEditorWin()
|
||||
|
||||
|
||||
|
||||
void MainWindow::toggleFxMixerWin()
|
||||
void MainWindow::toggleMixerWin()
|
||||
{
|
||||
toggleWindow( getGUI()->fxMixerView() );
|
||||
toggleWindow( getGUI()->mixerView() );
|
||||
}
|
||||
|
||||
|
||||
@@ -1131,6 +1131,8 @@ void MainWindow::toggleMicrotunerWin()
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
void MainWindow::updateViewMenu()
|
||||
{
|
||||
m_viewMenu->clear();
|
||||
@@ -1154,9 +1156,9 @@ void MainWindow::updateViewMenu()
|
||||
this,
|
||||
SLOT( toggleAutomationEditorWin())
|
||||
);
|
||||
m_viewMenu->addAction(embed::getIconPixmap( "fx_mixer" ),
|
||||
tr( "FX Mixer" ) + "\tCtrl+5",
|
||||
this, SLOT( toggleFxMixerWin() )
|
||||
m_viewMenu->addAction(embed::getIconPixmap( "mixer" ),
|
||||
tr( "Mixer" ) + "\tCtrl+5",
|
||||
this, SLOT( toggleMixerWin() )
|
||||
);
|
||||
m_viewMenu->addAction(embed::getIconPixmap( "controller" ),
|
||||
tr( "Controller Rack" ) + "\tCtrl+6",
|
||||
@@ -1288,7 +1290,7 @@ void MainWindow::updatePlayPauseIcons()
|
||||
getGUI()->songEditor()->setPauseIcon( true );
|
||||
break;
|
||||
|
||||
case Song::Mode_PlayAutomationPattern:
|
||||
case Song::Mode_PlayAutomationClip:
|
||||
getGUI()->automationEditor()->setPauseIcon( true );
|
||||
break;
|
||||
|
||||
@@ -1296,7 +1298,7 @@ void MainWindow::updatePlayPauseIcons()
|
||||
getGUI()->getBBEditor()->setPauseIcon( true );
|
||||
break;
|
||||
|
||||
case Song::Mode_PlayPattern:
|
||||
case Song::Mode_PlayMidiClip:
|
||||
getGUI()->pianoRoll()->setPauseIcon( true );
|
||||
break;
|
||||
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Pattern.cpp - implementation of class pattern which holds notes
|
||||
* MidiClipView.cpp - implementation of class MidiClipView which displays notes
|
||||
*
|
||||
* Copyright (c) 2004-2014 Tobias Doerffel <tobydox/at/users.sourceforge.net>
|
||||
* Copyright (c) 2005-2007 Danny McRae <khjklujn/at/yahoo.com>
|
||||
@@ -23,7 +23,7 @@
|
||||
*
|
||||
*/
|
||||
|
||||
#include "PatternView.h"
|
||||
#include "MidiClipView.h"
|
||||
|
||||
#include <QApplication>
|
||||
#include <QMenu>
|
||||
@@ -35,9 +35,9 @@
|
||||
#include "PianoRoll.h"
|
||||
#include "RenameDialog.h"
|
||||
|
||||
PatternView::PatternView( Pattern* pattern, TrackView* parent ) :
|
||||
TrackContentObjectView( pattern, parent ),
|
||||
m_pat( pattern ),
|
||||
MidiClipView::MidiClipView( MidiClip* clip, TrackView* parent ) :
|
||||
ClipView( clip, parent ),
|
||||
m_clip( clip ),
|
||||
m_paintPixmap(),
|
||||
m_noteFillColor(255, 255, 255, 220),
|
||||
m_noteBorderColor(255, 255, 255, 220),
|
||||
@@ -45,7 +45,7 @@ PatternView::PatternView( Pattern* pattern, TrackView* parent ) :
|
||||
m_mutedNoteBorderColor(100, 100, 100, 220),
|
||||
m_legacySEBB(ConfigManager::inst()->value("ui","legacysebb","0").toInt())
|
||||
{
|
||||
connect( getGUI()->pianoRoll(), SIGNAL( currentPatternChanged() ),
|
||||
connect( getGUI()->pianoRoll(), SIGNAL( currentMidiClipChanged() ),
|
||||
this, SLOT( update() ) );
|
||||
|
||||
if( s_stepBtnOn0 == nullptr )
|
||||
@@ -80,27 +80,27 @@ PatternView::PatternView( Pattern* pattern, TrackView* parent ) :
|
||||
|
||||
|
||||
|
||||
Pattern* PatternView::getPattern()
|
||||
MidiClip* MidiClipView::getMidiClip()
|
||||
{
|
||||
return m_pat;
|
||||
return m_clip;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
void PatternView::update()
|
||||
void MidiClipView::update()
|
||||
{
|
||||
ToolTip::add(this, m_pat->name());
|
||||
ToolTip::add(this, m_clip->name());
|
||||
|
||||
TrackContentObjectView::update();
|
||||
ClipView::update();
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
void PatternView::openInPianoRoll()
|
||||
void MidiClipView::openInPianoRoll()
|
||||
{
|
||||
getGUI()->pianoRoll()->setCurrentPattern( m_pat );
|
||||
getGUI()->pianoRoll()->setCurrentMidiClip( m_clip );
|
||||
getGUI()->pianoRoll()->parentWidget()->show();
|
||||
getGUI()->pianoRoll()->show();
|
||||
getGUI()->pianoRoll()->setFocus();
|
||||
@@ -110,9 +110,9 @@ void PatternView::openInPianoRoll()
|
||||
|
||||
|
||||
|
||||
void PatternView::setGhostInPianoRoll()
|
||||
void MidiClipView::setGhostInPianoRoll()
|
||||
{
|
||||
getGUI()->pianoRoll()->setGhostPattern( m_pat );
|
||||
getGUI()->pianoRoll()->setGhostMidiClip( m_clip );
|
||||
getGUI()->pianoRoll()->parentWidget()->show();
|
||||
getGUI()->pianoRoll()->show();
|
||||
getGUI()->pianoRoll()->setFocus();
|
||||
@@ -121,23 +121,23 @@ void PatternView::setGhostInPianoRoll()
|
||||
|
||||
|
||||
|
||||
void PatternView::resetName() { m_pat->setName(""); }
|
||||
void MidiClipView::resetName() { m_clip->setName(""); }
|
||||
|
||||
|
||||
|
||||
|
||||
void PatternView::changeName()
|
||||
void MidiClipView::changeName()
|
||||
{
|
||||
QString s = m_pat->name();
|
||||
QString s = m_clip->name();
|
||||
RenameDialog rename_dlg( s );
|
||||
rename_dlg.exec();
|
||||
m_pat->setName( s );
|
||||
m_clip->setName( s );
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
void PatternView::constructContextMenu( QMenu * _cm )
|
||||
void MidiClipView::constructContextMenu( QMenu * _cm )
|
||||
{
|
||||
QAction * a = new QAction( embed::getIconPixmap( "piano" ),
|
||||
tr( "Open in piano-roll" ), _cm );
|
||||
@@ -147,7 +147,7 @@ void PatternView::constructContextMenu( QMenu * _cm )
|
||||
|
||||
QAction * b = new QAction( embed::getIconPixmap( "ghost_note" ),
|
||||
tr( "Set as ghost in piano-roll" ), _cm );
|
||||
if( m_pat->empty() ) { b->setEnabled( false ); }
|
||||
if( m_clip->empty() ) { b->setEnabled( false ); }
|
||||
_cm->insertAction( _cm->actions()[1], b );
|
||||
connect( b, SIGNAL( triggered( bool ) ),
|
||||
this, SLOT( setGhostInPianoRoll() ) );
|
||||
@@ -155,7 +155,7 @@ void PatternView::constructContextMenu( QMenu * _cm )
|
||||
_cm->addSeparator();
|
||||
|
||||
_cm->addAction( embed::getIconPixmap( "edit_erase" ),
|
||||
tr( "Clear all notes" ), m_pat, SLOT( clear() ) );
|
||||
tr( "Clear all notes" ), m_clip, SLOT( clear() ) );
|
||||
_cm->addSeparator();
|
||||
|
||||
_cm->addAction( embed::getIconPixmap( "reload" ), tr( "Reset name" ),
|
||||
@@ -164,27 +164,27 @@ void PatternView::constructContextMenu( QMenu * _cm )
|
||||
tr( "Change name" ),
|
||||
this, SLOT( changeName() ) );
|
||||
|
||||
if ( m_pat->type() == Pattern::BeatPattern )
|
||||
if ( m_clip->type() == MidiClip::BeatClip )
|
||||
{
|
||||
_cm->addSeparator();
|
||||
|
||||
_cm->addAction( embed::getIconPixmap( "step_btn_add" ),
|
||||
tr( "Add steps" ), m_pat, SLOT( addSteps() ) );
|
||||
tr( "Add steps" ), m_clip, SLOT( addSteps() ) );
|
||||
_cm->addAction( embed::getIconPixmap( "step_btn_remove" ),
|
||||
tr( "Remove steps" ), m_pat, SLOT( removeSteps() ) );
|
||||
tr( "Remove steps" ), m_clip, SLOT( removeSteps() ) );
|
||||
_cm->addAction( embed::getIconPixmap( "step_btn_duplicate" ),
|
||||
tr( "Clone Steps" ), m_pat, SLOT( cloneSteps() ) );
|
||||
tr( "Clone Steps" ), m_clip, SLOT( cloneSteps() ) );
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
void PatternView::mousePressEvent( QMouseEvent * _me )
|
||||
void MidiClipView::mousePressEvent( QMouseEvent * _me )
|
||||
{
|
||||
bool displayBB = fixedTCOs() || (pixelsPerBar() >= 96 && m_legacySEBB);
|
||||
bool displayBB = fixedClips() || (pixelsPerBar() >= 96 && m_legacySEBB);
|
||||
if( _me->button() == Qt::LeftButton &&
|
||||
m_pat->m_patternType == Pattern::BeatPattern &&
|
||||
m_clip->m_clipType == MidiClip::BeatClip &&
|
||||
displayBB && _me->y() > height() - s_stepBtnOff->height() )
|
||||
|
||||
// when mouse button is pressed in beat/bassline -mode
|
||||
@@ -192,36 +192,36 @@ void PatternView::mousePressEvent( QMouseEvent * _me )
|
||||
{
|
||||
// get the step number that was clicked on and
|
||||
// do calculations in floats to prevent rounding errors...
|
||||
float tmp = ( ( float(_me->x()) - TCO_BORDER_WIDTH ) *
|
||||
float( m_pat -> m_steps ) ) / float(width() - TCO_BORDER_WIDTH*2);
|
||||
float tmp = ( ( float(_me->x()) - CLIP_BORDER_WIDTH ) *
|
||||
float( m_clip -> m_steps ) ) / float(width() - CLIP_BORDER_WIDTH*2);
|
||||
|
||||
int step = int( tmp );
|
||||
|
||||
// debugging to ensure we get the correct step...
|
||||
// qDebug( "Step (%f) %d", tmp, step );
|
||||
|
||||
if( step >= m_pat->m_steps )
|
||||
if( step >= m_clip->m_steps )
|
||||
{
|
||||
qDebug( "Something went wrong in pattern.cpp: step %d doesn't exist in pattern!", step );
|
||||
qDebug( "Something went wrong in clip.cpp: step %d doesn't exist in clip!", step );
|
||||
return;
|
||||
}
|
||||
|
||||
Note * n = m_pat->noteAtStep( step );
|
||||
Note * n = m_clip->noteAtStep( step );
|
||||
|
||||
if( n == nullptr )
|
||||
{
|
||||
m_pat->addStepNote( step );
|
||||
m_clip->addStepNote( step );
|
||||
}
|
||||
else // note at step found
|
||||
{
|
||||
m_pat->addJournalCheckPoint();
|
||||
m_pat->setStep( step, false );
|
||||
m_clip->addJournalCheckPoint();
|
||||
m_clip->setStep( step, false );
|
||||
}
|
||||
|
||||
Engine::getSong()->setModified();
|
||||
update();
|
||||
|
||||
if( getGUI()->pianoRoll()->currentPattern() == m_pat )
|
||||
if( getGUI()->pianoRoll()->currentMidiClip() == m_clip )
|
||||
{
|
||||
getGUI()->pianoRoll()->update();
|
||||
}
|
||||
@@ -231,18 +231,18 @@ void PatternView::mousePressEvent( QMouseEvent * _me )
|
||||
// if not in beat/bassline -mode, let parent class handle the event
|
||||
|
||||
{
|
||||
TrackContentObjectView::mousePressEvent( _me );
|
||||
ClipView::mousePressEvent( _me );
|
||||
}
|
||||
}
|
||||
|
||||
void PatternView::mouseDoubleClickEvent(QMouseEvent *_me)
|
||||
void MidiClipView::mouseDoubleClickEvent(QMouseEvent *_me)
|
||||
{
|
||||
if( _me->button() != Qt::LeftButton )
|
||||
{
|
||||
_me->ignore();
|
||||
return;
|
||||
}
|
||||
if( m_pat->m_patternType == Pattern::MelodyPattern || !fixedTCOs() )
|
||||
if( m_clip->m_clipType == MidiClip::MelodyClip || !fixedClips() )
|
||||
{
|
||||
openInPianoRoll();
|
||||
}
|
||||
@@ -251,28 +251,28 @@ void PatternView::mouseDoubleClickEvent(QMouseEvent *_me)
|
||||
|
||||
|
||||
|
||||
void PatternView::wheelEvent(QWheelEvent * we)
|
||||
void MidiClipView::wheelEvent(QWheelEvent * we)
|
||||
{
|
||||
if(m_pat->m_patternType == Pattern::BeatPattern &&
|
||||
(fixedTCOs() || pixelsPerBar() >= 96) &&
|
||||
if(m_clip->m_clipType == MidiClip::BeatClip &&
|
||||
(fixedClips() || pixelsPerBar() >= 96) &&
|
||||
position(we).y() > height() - s_stepBtnOff->height())
|
||||
{
|
||||
// get the step number that was wheeled on and
|
||||
// do calculations in floats to prevent rounding errors...
|
||||
float tmp = ((float(position(we).x()) - TCO_BORDER_WIDTH) *
|
||||
float(m_pat -> m_steps)) / float(width() - TCO_BORDER_WIDTH*2);
|
||||
float tmp = ((float(position(we).x()) - CLIP_BORDER_WIDTH) *
|
||||
float(m_clip -> m_steps)) / float(width() - CLIP_BORDER_WIDTH*2);
|
||||
|
||||
int step = int( tmp );
|
||||
|
||||
if( step >= m_pat->m_steps )
|
||||
if( step >= m_clip->m_steps )
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
Note * n = m_pat->noteAtStep( step );
|
||||
Note * n = m_clip->noteAtStep( step );
|
||||
if(!n && we->angleDelta().y() > 0)
|
||||
{
|
||||
n = m_pat->addStepNote( step );
|
||||
n = m_clip->addStepNote( step );
|
||||
n->setVolume( 0 );
|
||||
}
|
||||
if( n != nullptr )
|
||||
@@ -290,7 +290,7 @@ void PatternView::wheelEvent(QWheelEvent * we)
|
||||
|
||||
Engine::getSong()->setModified();
|
||||
update();
|
||||
if( getGUI()->pianoRoll()->currentPattern() == m_pat )
|
||||
if( getGUI()->pianoRoll()->currentMidiClip() == m_clip )
|
||||
{
|
||||
getGUI()->pianoRoll()->update();
|
||||
}
|
||||
@@ -299,7 +299,7 @@ void PatternView::wheelEvent(QWheelEvent * we)
|
||||
}
|
||||
else
|
||||
{
|
||||
TrackContentObjectView::wheelEvent(we);
|
||||
ClipView::wheelEvent(we);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -309,7 +309,7 @@ static int computeNoteRange(int minKey, int maxKey)
|
||||
return (maxKey - minKey) + 1;
|
||||
}
|
||||
|
||||
void PatternView::paintEvent( QPaintEvent * )
|
||||
void MidiClipView::paintEvent( QPaintEvent * )
|
||||
{
|
||||
QPainter painter( this );
|
||||
|
||||
@@ -329,14 +329,14 @@ void PatternView::paintEvent( QPaintEvent * )
|
||||
QPainter p( &m_paintPixmap );
|
||||
|
||||
QColor c;
|
||||
bool const muted = m_pat->getTrack()->isMuted() || m_pat->isMuted();
|
||||
bool current = getGUI()->pianoRoll()->currentPattern() == m_pat;
|
||||
bool beatPattern = m_pat->m_patternType == Pattern::BeatPattern;
|
||||
bool const muted = m_clip->getTrack()->isMuted() || m_clip->isMuted();
|
||||
bool current = getGUI()->pianoRoll()->currentMidiClip() == m_clip;
|
||||
bool beatClip = m_clip->m_clipType == MidiClip::BeatClip;
|
||||
|
||||
if( beatPattern )
|
||||
if( beatClip )
|
||||
{
|
||||
// Do not paint BBTCOs how we paint pattern TCOs
|
||||
c = BBPatternBackground();
|
||||
// Do not paint BBClips how we paint MidiClips
|
||||
c = BBClipBackground();
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -345,10 +345,10 @@ void PatternView::paintEvent( QPaintEvent * )
|
||||
|
||||
// invert the gradient for the background in the B&B editor
|
||||
QLinearGradient lingrad( 0, 0, 0, height() );
|
||||
lingrad.setColorAt( beatPattern ? 0 : 1, c.darker( 300 ) );
|
||||
lingrad.setColorAt( beatPattern ? 1 : 0, c );
|
||||
lingrad.setColorAt( beatClip ? 0 : 1, c.darker( 300 ) );
|
||||
lingrad.setColorAt( beatClip ? 1 : 0, c );
|
||||
|
||||
// paint a black rectangle under the pattern to prevent glitches with transparent backgrounds
|
||||
// paint a black rectangle under the clip to prevent glitches with transparent backgrounds
|
||||
p.fillRect( rect(), QColor( 0, 0, 0 ) );
|
||||
|
||||
if( gradient() )
|
||||
@@ -362,12 +362,12 @@ void PatternView::paintEvent( QPaintEvent * )
|
||||
|
||||
// Check whether we will paint a text box and compute its potential height
|
||||
// This is needed so we can paint the notes underneath it.
|
||||
bool const drawName = !m_pat->name().isEmpty();
|
||||
bool const drawTextBox = !beatPattern && drawName;
|
||||
bool const drawName = !m_clip->name().isEmpty();
|
||||
bool const drawTextBox = !beatClip && drawName;
|
||||
|
||||
// TODO Warning! This might cause problems if TrackContentObjectView::paintTextLabel changes
|
||||
// TODO Warning! This might cause problems if ClipView::paintTextLabel changes
|
||||
int textBoxHeight = 0;
|
||||
const int textTop = TCO_BORDER_WIDTH + 1;
|
||||
const int textTop = CLIP_BORDER_WIDTH + 1;
|
||||
if (drawTextBox)
|
||||
{
|
||||
QFont labelFont = this->font();
|
||||
@@ -378,22 +378,22 @@ void PatternView::paintEvent( QPaintEvent * )
|
||||
}
|
||||
|
||||
// Compute pixels per bar
|
||||
const int baseWidth = fixedTCOs() ? parentWidget()->width() - 2 * TCO_BORDER_WIDTH
|
||||
: width() - TCO_BORDER_WIDTH;
|
||||
const float pixelsPerBar = baseWidth / (float) m_pat->length().getBar();
|
||||
const int baseWidth = fixedClips() ? parentWidget()->width() - 2 * CLIP_BORDER_WIDTH
|
||||
: width() - CLIP_BORDER_WIDTH;
|
||||
const float pixelsPerBar = baseWidth / (float) m_clip->length().getBar();
|
||||
|
||||
// Length of one bar/beat in the [0,1] x [0,1] coordinate system
|
||||
const float barLength = 1. / m_pat->length().getBar();
|
||||
const float barLength = 1. / m_clip->length().getBar();
|
||||
const float tickLength = barLength / TimePos::ticksPerBar();
|
||||
|
||||
const int x_base = TCO_BORDER_WIDTH;
|
||||
const int x_base = CLIP_BORDER_WIDTH;
|
||||
|
||||
bool displayBB = fixedTCOs() || (pixelsPerBar >= 96 && m_legacySEBB);
|
||||
// melody pattern paint event
|
||||
NoteVector const & noteCollection = m_pat->m_notes;
|
||||
if( m_pat->m_patternType == Pattern::MelodyPattern && !noteCollection.empty() )
|
||||
bool displayBB = fixedClips() || (pixelsPerBar >= 96 && m_legacySEBB);
|
||||
// melody clip paint event
|
||||
NoteVector const & noteCollection = m_clip->m_notes;
|
||||
if( m_clip->m_clipType == MidiClip::MelodyClip && !noteCollection.empty() )
|
||||
{
|
||||
// Compute the minimum and maximum key in the pattern
|
||||
// Compute the minimum and maximum key in the clip
|
||||
// so that we know how much there is to draw.
|
||||
int maxKey = std::numeric_limits<int>::min();
|
||||
int minKey = std::numeric_limits<int>::max();
|
||||
@@ -456,7 +456,7 @@ void PatternView::paintEvent( QPaintEvent * )
|
||||
// set colour based on mute status
|
||||
QColor noteFillColor = muted ? getMutedNoteFillColor() : getNoteFillColor();
|
||||
QColor noteBorderColor = muted ? getMutedNoteBorderColor()
|
||||
: ( m_pat->hasColor() ? c.lighter( 200 ) : getNoteBorderColor() );
|
||||
: ( m_clip->hasColor() ? c.lighter( 200 ) : getNoteBorderColor() );
|
||||
|
||||
bool const drawAsLines = height() < 64;
|
||||
if (drawAsLines)
|
||||
@@ -477,7 +477,7 @@ void PatternView::paintEvent( QPaintEvent * )
|
||||
|
||||
float const noteHeight = 1. / adjustedNoteRange;
|
||||
|
||||
// scan through all the notes and draw them on the pattern
|
||||
// scan through all the notes and draw them on the clip
|
||||
for (Note const * currentNote : noteCollection)
|
||||
{
|
||||
// Map to 0, 1, 2, ...
|
||||
@@ -504,18 +504,18 @@ void PatternView::paintEvent( QPaintEvent * )
|
||||
|
||||
p.restore();
|
||||
}
|
||||
// beat pattern paint event
|
||||
else if( beatPattern && displayBB )
|
||||
// beat clip paint event
|
||||
else if( beatClip && displayBB )
|
||||
{
|
||||
QPixmap stepon0;
|
||||
QPixmap stepon200;
|
||||
QPixmap stepoff;
|
||||
QPixmap stepoffl;
|
||||
const int steps = qMax( 1,
|
||||
m_pat->m_steps );
|
||||
const int w = width() - 2 * TCO_BORDER_WIDTH;
|
||||
m_clip->m_steps );
|
||||
const int w = width() - 2 * CLIP_BORDER_WIDTH;
|
||||
|
||||
// scale step graphics to fit the beat pattern length
|
||||
// scale step graphics to fit the beat clip length
|
||||
stepon0 = s_stepBtnOn0->scaled( w / steps,
|
||||
s_stepBtnOn0->height(),
|
||||
Qt::IgnoreAspectRatio,
|
||||
@@ -533,12 +533,12 @@ void PatternView::paintEvent( QPaintEvent * )
|
||||
Qt::IgnoreAspectRatio,
|
||||
Qt::SmoothTransformation );
|
||||
|
||||
for( int it = 0; it < steps; it++ ) // go through all the steps in the beat pattern
|
||||
for( int it = 0; it < steps; it++ ) // go through all the steps in the beat clip
|
||||
{
|
||||
Note * n = m_pat->noteAtStep( it );
|
||||
Note * n = m_clip->noteAtStep( it );
|
||||
|
||||
// figure out x and y coordinates for step graphic
|
||||
const int x = TCO_BORDER_WIDTH + static_cast<int>( it * w / steps );
|
||||
const int x = CLIP_BORDER_WIDTH + static_cast<int>( it * w / steps );
|
||||
const int y = height() - s_stepBtnOff->height() - 1;
|
||||
|
||||
if( n )
|
||||
@@ -560,7 +560,7 @@ void PatternView::paintEvent( QPaintEvent * )
|
||||
}
|
||||
} // end for loop
|
||||
|
||||
// draw a transparent rectangle over muted patterns
|
||||
// draw a transparent rectangle over muted clips
|
||||
if ( muted )
|
||||
{
|
||||
p.setBrush( mutedBackgroundColor() );
|
||||
@@ -573,39 +573,39 @@ void PatternView::paintEvent( QPaintEvent * )
|
||||
const int lineSize = 3;
|
||||
p.setPen( c.darker( 200 ) );
|
||||
|
||||
for( bar_t t = 1; t < m_pat->length().getBar(); ++t )
|
||||
for( bar_t t = 1; t < m_clip->length().getBar(); ++t )
|
||||
{
|
||||
p.drawLine( x_base + static_cast<int>( pixelsPerBar * t ) - 1,
|
||||
TCO_BORDER_WIDTH, x_base + static_cast<int>(
|
||||
pixelsPerBar * t ) - 1, TCO_BORDER_WIDTH + lineSize );
|
||||
CLIP_BORDER_WIDTH, x_base + static_cast<int>(
|
||||
pixelsPerBar * t ) - 1, CLIP_BORDER_WIDTH + lineSize );
|
||||
p.drawLine( x_base + static_cast<int>( pixelsPerBar * t ) - 1,
|
||||
rect().bottom() - ( lineSize + TCO_BORDER_WIDTH ),
|
||||
rect().bottom() - ( lineSize + CLIP_BORDER_WIDTH ),
|
||||
x_base + static_cast<int>( pixelsPerBar * t ) - 1,
|
||||
rect().bottom() - TCO_BORDER_WIDTH );
|
||||
rect().bottom() - CLIP_BORDER_WIDTH );
|
||||
}
|
||||
|
||||
// pattern name
|
||||
// clip name
|
||||
if (drawTextBox)
|
||||
{
|
||||
paintTextLabel(m_pat->name(), p);
|
||||
paintTextLabel(m_clip->name(), p);
|
||||
}
|
||||
|
||||
if( !( fixedTCOs() && beatPattern ) )
|
||||
if( !( fixedClips() && beatClip ) )
|
||||
{
|
||||
// inner border
|
||||
p.setPen( c.lighter( current ? 160 : 130 ) );
|
||||
p.drawRect( 1, 1, rect().right() - TCO_BORDER_WIDTH,
|
||||
rect().bottom() - TCO_BORDER_WIDTH );
|
||||
p.drawRect( 1, 1, rect().right() - CLIP_BORDER_WIDTH,
|
||||
rect().bottom() - CLIP_BORDER_WIDTH );
|
||||
|
||||
// outer border
|
||||
p.setPen( current ? c.lighter( 130 ) : c.darker( 300 ) );
|
||||
p.drawRect( 0, 0, rect().right(), rect().bottom() );
|
||||
}
|
||||
|
||||
// draw the 'muted' pixmap only if the pattern was manually muted
|
||||
if( m_pat->isMuted() )
|
||||
// draw the 'muted' pixmap only if the clip was manually muted
|
||||
if( m_clip->isMuted() )
|
||||
{
|
||||
const int spacing = TCO_BORDER_WIDTH;
|
||||
const int spacing = CLIP_BORDER_WIDTH;
|
||||
const int size = 14;
|
||||
p.drawPixmap( spacing, height() - ( size + spacing ),
|
||||
embed::getIconPixmap( "muted", size, size ) );
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* FxMixerView.cpp - effect-mixer-view for LMMS
|
||||
* MixerView.cpp - effect-mixer-view for LMMS
|
||||
*
|
||||
* Copyright (c) 2008-2014 Tobias Doerffel <tobydox/at/users.sourceforge.net>
|
||||
*
|
||||
@@ -38,10 +38,10 @@
|
||||
|
||||
#include "lmms_math.h"
|
||||
|
||||
#include "FxMixerView.h"
|
||||
#include "MixerView.h"
|
||||
#include "Knob.h"
|
||||
#include "FxLine.h"
|
||||
#include "FxMixer.h"
|
||||
#include "MixerLine.h"
|
||||
#include "Mixer.h"
|
||||
#include "GuiApplication.h"
|
||||
#include "MainWindow.h"
|
||||
#include "AudioEngine.h"
|
||||
@@ -52,12 +52,12 @@
|
||||
#include "BBTrackContainer.h"
|
||||
#include "TrackContainer.h" // For TrackContainer::TrackList typedef
|
||||
|
||||
FxMixerView::FxMixerView() :
|
||||
MixerView::MixerView() :
|
||||
QWidget(),
|
||||
ModelView( nullptr, this ),
|
||||
SerializingObjectHook()
|
||||
{
|
||||
FxMixer * m = Engine::fxMixer();
|
||||
Mixer * m = Engine::mixer();
|
||||
m->setHook( this );
|
||||
|
||||
//QPalette pal = palette();
|
||||
@@ -67,8 +67,8 @@ FxMixerView::FxMixerView() :
|
||||
setAutoFillBackground( true );
|
||||
setSizePolicy( QSizePolicy::Preferred, QSizePolicy::Fixed );
|
||||
|
||||
setWindowTitle( tr( "FX-Mixer" ) );
|
||||
setWindowIcon( embed::getIconPixmap( "fx_mixer" ) );
|
||||
setWindowTitle( tr( "Mixer" ) );
|
||||
setWindowIcon( embed::getIconPixmap( "mixer" ) );
|
||||
|
||||
// main-layout
|
||||
QHBoxLayout * ml = new QHBoxLayout;
|
||||
@@ -91,21 +91,21 @@ FxMixerView::FxMixerView() :
|
||||
m_racksWidget->setLayout( m_racksLayout );
|
||||
|
||||
// add master channel
|
||||
m_fxChannelViews.resize( m->numChannels() );
|
||||
m_fxChannelViews[0] = new FxChannelView( this, this, 0 );
|
||||
m_mixerChannelViews.resize( m->numChannels() );
|
||||
m_mixerChannelViews[0] = new MixerChannelView( this, this, 0 );
|
||||
|
||||
m_racksLayout->addWidget( m_fxChannelViews[0]->m_rackView );
|
||||
m_racksLayout->addWidget( m_mixerChannelViews[0]->m_rackView );
|
||||
|
||||
FxChannelView * masterView = m_fxChannelViews[0];
|
||||
ml->addWidget( masterView->m_fxLine, 0, Qt::AlignTop );
|
||||
MixerChannelView * masterView = m_mixerChannelViews[0];
|
||||
ml->addWidget( masterView->m_mixerLine, 0, Qt::AlignTop );
|
||||
|
||||
QSize fxLineSize = masterView->m_fxLine->size();
|
||||
QSize mixerLineSize = masterView->m_mixerLine->size();
|
||||
|
||||
// add mixer channels
|
||||
for( int i = 1; i < m_fxChannelViews.size(); ++i )
|
||||
for( int i = 1; i < m_mixerChannelViews.size(); ++i )
|
||||
{
|
||||
m_fxChannelViews[i] = new FxChannelView(m_channelAreaWidget, this, i);
|
||||
chLayout->addWidget( m_fxChannelViews[i]->m_fxLine );
|
||||
m_mixerChannelViews[i] = new MixerChannelView(m_channelAreaWidget, this, i);
|
||||
chLayout->addWidget( m_mixerChannelViews[i]->m_mixerLine );
|
||||
}
|
||||
|
||||
// add the scrolling section to the main layout
|
||||
@@ -113,7 +113,7 @@ FxMixerView::FxMixerView() :
|
||||
class ChannelArea : public QScrollArea
|
||||
{
|
||||
public:
|
||||
ChannelArea( QWidget * parent, FxMixerView * mv ) :
|
||||
ChannelArea( QWidget * parent, MixerView * mv ) :
|
||||
QScrollArea( parent ), m_mv( mv ) {}
|
||||
~ChannelArea() {}
|
||||
void keyPressEvent( QKeyEvent * e ) override
|
||||
@@ -121,29 +121,29 @@ FxMixerView::FxMixerView() :
|
||||
m_mv->keyPressEvent( e );
|
||||
}
|
||||
private:
|
||||
FxMixerView * m_mv;
|
||||
MixerView * m_mv;
|
||||
};
|
||||
channelArea = new ChannelArea( this, this );
|
||||
channelArea->setWidget( m_channelAreaWidget );
|
||||
channelArea->setVerticalScrollBarPolicy( Qt::ScrollBarAlwaysOff );
|
||||
channelArea->setFrameStyle( QFrame::NoFrame );
|
||||
channelArea->setMinimumWidth( fxLineSize.width() * 6 );
|
||||
channelArea->setFixedHeight( fxLineSize.height() +
|
||||
channelArea->setMinimumWidth( mixerLineSize.width() * 6 );
|
||||
channelArea->setFixedHeight( mixerLineSize.height() +
|
||||
style()->pixelMetric( QStyle::PM_ScrollBarExtent ) );
|
||||
ml->addWidget( channelArea, 1, Qt::AlignTop );
|
||||
|
||||
// show the add new effect channel button
|
||||
// show the add new mixer channel button
|
||||
QPushButton * newChannelBtn = new QPushButton( embed::getIconPixmap( "new_channel" ), QString(), this );
|
||||
newChannelBtn->setObjectName( "newChannelBtn" );
|
||||
newChannelBtn->setFixedSize( fxLineSize );
|
||||
newChannelBtn->setFixedSize( mixerLineSize );
|
||||
connect( newChannelBtn, SIGNAL( clicked() ), this, SLOT( addNewChannel() ) );
|
||||
ml->addWidget( newChannelBtn, 0, Qt::AlignTop );
|
||||
|
||||
|
||||
// add the stacked layout for the effect racks of fx channels
|
||||
// add the stacked layout for the effect racks of mixer channels
|
||||
ml->addWidget( m_racksWidget, 0, Qt::AlignTop | Qt::AlignRight );
|
||||
|
||||
setCurrentFxLine( m_fxChannelViews[0]->m_fxLine );
|
||||
setCurrentMixerLine( m_mixerChannelViews[0]->m_mixerLine );
|
||||
|
||||
setLayout( ml );
|
||||
updateGeometry();
|
||||
@@ -168,28 +168,28 @@ FxMixerView::FxMixerView() :
|
||||
setModel( m );
|
||||
}
|
||||
|
||||
FxMixerView::~FxMixerView()
|
||||
MixerView::~MixerView()
|
||||
{
|
||||
for (int i=0; i<m_fxChannelViews.size(); i++)
|
||||
for (int i=0; i<m_mixerChannelViews.size(); i++)
|
||||
{
|
||||
delete m_fxChannelViews.at(i);
|
||||
delete m_mixerChannelViews.at(i);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
int FxMixerView::addNewChannel()
|
||||
int MixerView::addNewChannel()
|
||||
{
|
||||
// add new fx mixer channel and redraw the form.
|
||||
FxMixer * mix = Engine::fxMixer();
|
||||
// add new mixer channel and redraw the form.
|
||||
Mixer * mix = Engine::mixer();
|
||||
|
||||
int newChannelIndex = mix->createChannel();
|
||||
m_fxChannelViews.push_back(new FxChannelView(m_channelAreaWidget, this,
|
||||
m_mixerChannelViews.push_back(new MixerChannelView(m_channelAreaWidget, this,
|
||||
newChannelIndex));
|
||||
chLayout->addWidget( m_fxChannelViews[newChannelIndex]->m_fxLine );
|
||||
m_racksLayout->addWidget( m_fxChannelViews[newChannelIndex]->m_rackView );
|
||||
chLayout->addWidget( m_mixerChannelViews[newChannelIndex]->m_mixerLine );
|
||||
m_racksLayout->addWidget( m_mixerChannelViews[newChannelIndex]->m_rackView );
|
||||
|
||||
updateFxLine(newChannelIndex);
|
||||
updateMixerLine(newChannelIndex);
|
||||
|
||||
updateMaxChannelSelector();
|
||||
|
||||
@@ -197,38 +197,38 @@ int FxMixerView::addNewChannel()
|
||||
}
|
||||
|
||||
|
||||
void FxMixerView::refreshDisplay()
|
||||
void MixerView::refreshDisplay()
|
||||
{
|
||||
// delete all views and re-add them
|
||||
for( int i = 1; i<m_fxChannelViews.size(); ++i )
|
||||
for( int i = 1; i<m_mixerChannelViews.size(); ++i )
|
||||
{
|
||||
chLayout->removeWidget(m_fxChannelViews[i]->m_fxLine);
|
||||
m_racksLayout->removeWidget( m_fxChannelViews[i]->m_rackView );
|
||||
delete m_fxChannelViews[i]->m_fader;
|
||||
delete m_fxChannelViews[i]->m_muteBtn;
|
||||
delete m_fxChannelViews[i]->m_soloBtn;
|
||||
delete m_fxChannelViews[i]->m_fxLine;
|
||||
delete m_fxChannelViews[i]->m_rackView;
|
||||
delete m_fxChannelViews[i];
|
||||
chLayout->removeWidget(m_mixerChannelViews[i]->m_mixerLine);
|
||||
m_racksLayout->removeWidget( m_mixerChannelViews[i]->m_rackView );
|
||||
delete m_mixerChannelViews[i]->m_fader;
|
||||
delete m_mixerChannelViews[i]->m_muteBtn;
|
||||
delete m_mixerChannelViews[i]->m_soloBtn;
|
||||
delete m_mixerChannelViews[i]->m_mixerLine;
|
||||
delete m_mixerChannelViews[i]->m_rackView;
|
||||
delete m_mixerChannelViews[i];
|
||||
}
|
||||
m_channelAreaWidget->adjustSize();
|
||||
|
||||
// re-add the views
|
||||
m_fxChannelViews.resize(Engine::fxMixer()->numChannels());
|
||||
for( int i = 1; i < m_fxChannelViews.size(); ++i )
|
||||
m_mixerChannelViews.resize(Engine::mixer()->numChannels());
|
||||
for( int i = 1; i < m_mixerChannelViews.size(); ++i )
|
||||
{
|
||||
m_fxChannelViews[i] = new FxChannelView(m_channelAreaWidget, this, i);
|
||||
chLayout->addWidget(m_fxChannelViews[i]->m_fxLine);
|
||||
m_racksLayout->addWidget( m_fxChannelViews[i]->m_rackView );
|
||||
m_mixerChannelViews[i] = new MixerChannelView(m_channelAreaWidget, this, i);
|
||||
chLayout->addWidget(m_mixerChannelViews[i]->m_mixerLine);
|
||||
m_racksLayout->addWidget( m_mixerChannelViews[i]->m_rackView );
|
||||
}
|
||||
|
||||
// set selected fx line to 0
|
||||
setCurrentFxLine( 0 );
|
||||
// set selected mixer line to 0
|
||||
setCurrentMixerLine( 0 );
|
||||
|
||||
// update all fx lines
|
||||
for( int i = 0; i < m_fxChannelViews.size(); ++i )
|
||||
// update all mixer lines
|
||||
for( int i = 0; i < m_mixerChannelViews.size(); ++i )
|
||||
{
|
||||
updateFxLine( i );
|
||||
updateMixerLine( i );
|
||||
}
|
||||
|
||||
updateMaxChannelSelector();
|
||||
@@ -236,7 +236,7 @@ void FxMixerView::refreshDisplay()
|
||||
|
||||
|
||||
// update the and max. channel number for every instrument
|
||||
void FxMixerView::updateMaxChannelSelector()
|
||||
void MixerView::updateMaxChannelSelector()
|
||||
{
|
||||
TrackContainer::TrackList songTrackList = Engine::getSong()->tracks();
|
||||
TrackContainer::TrackList bbTrackList = Engine::getBBTrackContainer()->tracks();
|
||||
@@ -250,21 +250,21 @@ void FxMixerView::updateMaxChannelSelector()
|
||||
if( trackList[i]->type() == Track::InstrumentTrack )
|
||||
{
|
||||
InstrumentTrack * inst = (InstrumentTrack *) trackList[i];
|
||||
inst->effectChannelModel()->setRange(0,
|
||||
m_fxChannelViews.size()-1,1);
|
||||
inst->mixerChannelModel()->setRange(0,
|
||||
m_mixerChannelViews.size()-1,1);
|
||||
}
|
||||
else if( trackList[i]->type() == Track::SampleTrack )
|
||||
{
|
||||
SampleTrack * strk = (SampleTrack *) trackList[i];
|
||||
strk->effectChannelModel()->setRange(0,
|
||||
m_fxChannelViews.size()-1,1);
|
||||
strk->mixerChannelModel()->setRange(0,
|
||||
m_mixerChannelViews.size()-1,1);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void FxMixerView::saveSettings( QDomDocument & _doc, QDomElement & _this )
|
||||
void MixerView::saveSettings( QDomDocument & _doc, QDomElement & _this )
|
||||
{
|
||||
MainWindow::saveWidgetState( this, _this );
|
||||
}
|
||||
@@ -272,97 +272,97 @@ void FxMixerView::saveSettings( QDomDocument & _doc, QDomElement & _this )
|
||||
|
||||
|
||||
|
||||
void FxMixerView::loadSettings( const QDomElement & _this )
|
||||
void MixerView::loadSettings( const QDomElement & _this )
|
||||
{
|
||||
MainWindow::restoreWidgetState( this, _this );
|
||||
}
|
||||
|
||||
|
||||
FxMixerView::FxChannelView::FxChannelView(QWidget * _parent, FxMixerView * _mv,
|
||||
MixerView::MixerChannelView::MixerChannelView(QWidget * _parent, MixerView * _mv,
|
||||
int channelIndex )
|
||||
{
|
||||
m_fxLine = new FxLine(_parent, _mv, channelIndex);
|
||||
m_mixerLine = new MixerLine(_parent, _mv, channelIndex);
|
||||
|
||||
FxChannel *fxChannel = Engine::fxMixer()->effectChannel(channelIndex);
|
||||
MixerChannel *mixerChannel = Engine::mixer()->mixerChannel(channelIndex);
|
||||
|
||||
m_fader = new Fader( &fxChannel->m_volumeModel,
|
||||
tr( "FX Fader %1" ).arg( channelIndex ), m_fxLine );
|
||||
m_fader = new Fader( &mixerChannel->m_volumeModel,
|
||||
tr( "Fader %1" ).arg( channelIndex ), m_mixerLine );
|
||||
m_fader->setLevelsDisplayedInDBFS();
|
||||
m_fader->setMinPeak(dbfsToAmp(-42));
|
||||
m_fader->setMaxPeak(dbfsToAmp(9));
|
||||
|
||||
m_fader->move( 16-m_fader->width()/2,
|
||||
m_fxLine->height()-
|
||||
m_mixerLine->height()-
|
||||
m_fader->height()-5 );
|
||||
|
||||
m_muteBtn = new PixmapButton( m_fxLine, tr( "Mute" ) );
|
||||
m_muteBtn->setModel( &fxChannel->m_muteModel );
|
||||
m_muteBtn = new PixmapButton( m_mixerLine, tr( "Mute" ) );
|
||||
m_muteBtn->setModel( &mixerChannel->m_muteModel );
|
||||
m_muteBtn->setActiveGraphic(
|
||||
embed::getIconPixmap( "led_off" ) );
|
||||
m_muteBtn->setInactiveGraphic(
|
||||
embed::getIconPixmap( "led_green" ) );
|
||||
m_muteBtn->setCheckable( true );
|
||||
m_muteBtn->move( 9, m_fader->y()-11);
|
||||
ToolTip::add( m_muteBtn, tr( "Mute this FX channel" ) );
|
||||
ToolTip::add( m_muteBtn, tr( "Mute this channel" ) );
|
||||
|
||||
m_soloBtn = new PixmapButton( m_fxLine, tr( "Solo" ) );
|
||||
m_soloBtn->setModel( &fxChannel->m_soloModel );
|
||||
m_soloBtn = new PixmapButton( m_mixerLine, tr( "Solo" ) );
|
||||
m_soloBtn->setModel( &mixerChannel->m_soloModel );
|
||||
m_soloBtn->setActiveGraphic(
|
||||
embed::getIconPixmap( "led_red" ) );
|
||||
m_soloBtn->setInactiveGraphic(
|
||||
embed::getIconPixmap( "led_off" ) );
|
||||
m_soloBtn->setCheckable( true );
|
||||
m_soloBtn->move( 9, m_fader->y()-21);
|
||||
connect(&fxChannel->m_soloModel, SIGNAL( dataChanged() ),
|
||||
connect(&mixerChannel->m_soloModel, SIGNAL( dataChanged() ),
|
||||
_mv, SLOT ( toggledSolo() ), Qt::DirectConnection );
|
||||
ToolTip::add( m_soloBtn, tr( "Solo FX channel" ) );
|
||||
ToolTip::add( m_soloBtn, tr( "Solo this channel" ) );
|
||||
|
||||
// Create EffectRack for the channel
|
||||
m_rackView = new EffectRackView( &fxChannel->m_fxChain, _mv->m_racksWidget );
|
||||
m_rackView->setFixedSize( EffectRackView::DEFAULT_WIDTH, FxLine::FxLineHeight );
|
||||
m_rackView = new EffectRackView( &mixerChannel->m_fxChain, _mv->m_racksWidget );
|
||||
m_rackView->setFixedSize( EffectRackView::DEFAULT_WIDTH, MixerLine::MixerLineHeight );
|
||||
}
|
||||
|
||||
|
||||
void FxMixerView::FxChannelView::setChannelIndex( int index )
|
||||
void MixerView::MixerChannelView::setChannelIndex( int index )
|
||||
{
|
||||
FxChannel* fxChannel = Engine::fxMixer()->effectChannel( index );
|
||||
MixerChannel* mixerChannel = Engine::mixer()->mixerChannel( index );
|
||||
|
||||
m_fader->setModel( &fxChannel->m_volumeModel );
|
||||
m_muteBtn->setModel( &fxChannel->m_muteModel );
|
||||
m_soloBtn->setModel( &fxChannel->m_soloModel );
|
||||
m_rackView->setModel( &fxChannel->m_fxChain );
|
||||
m_fader->setModel( &mixerChannel->m_volumeModel );
|
||||
m_muteBtn->setModel( &mixerChannel->m_muteModel );
|
||||
m_soloBtn->setModel( &mixerChannel->m_soloModel );
|
||||
m_rackView->setModel( &mixerChannel->m_fxChain );
|
||||
}
|
||||
|
||||
|
||||
void FxMixerView::toggledSolo()
|
||||
void MixerView::toggledSolo()
|
||||
{
|
||||
Engine::fxMixer()->toggledSolo();
|
||||
Engine::mixer()->toggledSolo();
|
||||
}
|
||||
|
||||
|
||||
|
||||
void FxMixerView::setCurrentFxLine( FxLine * _line )
|
||||
void MixerView::setCurrentMixerLine( MixerLine * _line )
|
||||
{
|
||||
// select
|
||||
m_currentFxLine = _line;
|
||||
m_racksLayout->setCurrentWidget( m_fxChannelViews[ _line->channelIndex() ]->m_rackView );
|
||||
m_currentMixerLine = _line;
|
||||
m_racksLayout->setCurrentWidget( m_mixerChannelViews[ _line->channelIndex() ]->m_rackView );
|
||||
|
||||
// set up send knob
|
||||
for(int i = 0; i < m_fxChannelViews.size(); ++i)
|
||||
for(int i = 0; i < m_mixerChannelViews.size(); ++i)
|
||||
{
|
||||
updateFxLine(i);
|
||||
updateMixerLine(i);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void FxMixerView::updateFxLine(int index)
|
||||
void MixerView::updateMixerLine(int index)
|
||||
{
|
||||
FxMixer * mix = Engine::fxMixer();
|
||||
Mixer * mix = Engine::mixer();
|
||||
|
||||
// does current channel send to this channel?
|
||||
int selIndex = m_currentFxLine->channelIndex();
|
||||
FxLine * thisLine = m_fxChannelViews[index]->m_fxLine;
|
||||
thisLine->setToolTip( Engine::fxMixer()->effectChannel( index )->m_name );
|
||||
int selIndex = m_currentMixerLine->channelIndex();
|
||||
MixerLine * thisLine = m_mixerChannelViews[index]->m_mixerLine;
|
||||
thisLine->setToolTip( Engine::mixer()->mixerChannel( index )->m_name );
|
||||
|
||||
FloatModel * sendModel = mix->channelSendModel(selIndex, index);
|
||||
if( sendModel == nullptr )
|
||||
@@ -384,60 +384,60 @@ void FxMixerView::updateFxLine(int index)
|
||||
}
|
||||
|
||||
|
||||
void FxMixerView::deleteChannel(int index)
|
||||
void MixerView::deleteChannel(int index)
|
||||
{
|
||||
// can't delete master
|
||||
if( index == 0 ) return;
|
||||
|
||||
// remember selected line
|
||||
int selLine = m_currentFxLine->channelIndex();
|
||||
int selLine = m_currentMixerLine->channelIndex();
|
||||
|
||||
// in case the deleted channel is soloed or the remaining
|
||||
// channels will be left in a muted state
|
||||
Engine::fxMixer()->clearChannel(index);
|
||||
Engine::mixer()->clearChannel(index);
|
||||
|
||||
// delete the real channel
|
||||
Engine::fxMixer()->deleteChannel(index);
|
||||
Engine::mixer()->deleteChannel(index);
|
||||
|
||||
// delete the view
|
||||
chLayout->removeWidget(m_fxChannelViews[index]->m_fxLine);
|
||||
m_racksLayout->removeWidget( m_fxChannelViews[index]->m_rackView );
|
||||
delete m_fxChannelViews[index]->m_fader;
|
||||
delete m_fxChannelViews[index]->m_muteBtn;
|
||||
delete m_fxChannelViews[index]->m_soloBtn;
|
||||
// delete fxLine later to prevent a crash when deleting from context menu
|
||||
m_fxChannelViews[index]->m_fxLine->hide();
|
||||
m_fxChannelViews[index]->m_fxLine->deleteLater();
|
||||
delete m_fxChannelViews[index]->m_rackView;
|
||||
delete m_fxChannelViews[index];
|
||||
chLayout->removeWidget(m_mixerChannelViews[index]->m_mixerLine);
|
||||
m_racksLayout->removeWidget( m_mixerChannelViews[index]->m_rackView );
|
||||
delete m_mixerChannelViews[index]->m_fader;
|
||||
delete m_mixerChannelViews[index]->m_muteBtn;
|
||||
delete m_mixerChannelViews[index]->m_soloBtn;
|
||||
// delete mixerLine later to prevent a crash when deleting from context menu
|
||||
m_mixerChannelViews[index]->m_mixerLine->hide();
|
||||
m_mixerChannelViews[index]->m_mixerLine->deleteLater();
|
||||
delete m_mixerChannelViews[index]->m_rackView;
|
||||
delete m_mixerChannelViews[index];
|
||||
m_channelAreaWidget->adjustSize();
|
||||
|
||||
// make sure every channel knows what index it is
|
||||
for(int i=index + 1; i<m_fxChannelViews.size(); ++i)
|
||||
for(int i=index + 1; i<m_mixerChannelViews.size(); ++i)
|
||||
{
|
||||
m_fxChannelViews[i]->m_fxLine->setChannelIndex(i-1);
|
||||
m_mixerChannelViews[i]->m_mixerLine->setChannelIndex(i-1);
|
||||
}
|
||||
m_fxChannelViews.remove(index);
|
||||
m_mixerChannelViews.remove(index);
|
||||
|
||||
// select the next channel
|
||||
if( selLine >= m_fxChannelViews.size() )
|
||||
if( selLine >= m_mixerChannelViews.size() )
|
||||
{
|
||||
selLine = m_fxChannelViews.size()-1;
|
||||
selLine = m_mixerChannelViews.size()-1;
|
||||
}
|
||||
setCurrentFxLine(selLine);
|
||||
setCurrentMixerLine(selLine);
|
||||
|
||||
updateMaxChannelSelector();
|
||||
}
|
||||
|
||||
|
||||
|
||||
void FxMixerView::deleteUnusedChannels()
|
||||
void MixerView::deleteUnusedChannels()
|
||||
{
|
||||
TrackContainer::TrackList tracks;
|
||||
tracks += Engine::getSong()->tracks();
|
||||
tracks += Engine::getBBTrackContainer()->tracks();
|
||||
|
||||
std::vector<bool> inUse(m_fxChannelViews.size(), false);
|
||||
std::vector<bool> inUse(m_mixerChannelViews.size(), false);
|
||||
|
||||
//Populate inUse by checking the destination channel for every track
|
||||
for (Track* t: tracks)
|
||||
@@ -448,93 +448,93 @@ void FxMixerView::deleteUnusedChannels()
|
||||
if (t->type() == Track::InstrumentTrack)
|
||||
{
|
||||
InstrumentTrack* inst = dynamic_cast<InstrumentTrack *>(t);
|
||||
channel = inst->effectChannelModel()->value();
|
||||
channel = inst->mixerChannelModel()->value();
|
||||
}
|
||||
else if (t->type() == Track::SampleTrack)
|
||||
{
|
||||
SampleTrack *strack = dynamic_cast<SampleTrack *>(t);
|
||||
channel = strack->effectChannelModel()->value();
|
||||
channel = strack->mixerChannelModel()->value();
|
||||
}
|
||||
inUse[channel] = true;
|
||||
}
|
||||
|
||||
//Check all channels except master, delete those with no incoming sends
|
||||
for(int i = m_fxChannelViews.size()-1; i > 0; --i)
|
||||
for(int i = m_mixerChannelViews.size()-1; i > 0; --i)
|
||||
{
|
||||
if (!inUse[i] && Engine::fxMixer()->effectChannel(i)->m_receives.isEmpty())
|
||||
if (!inUse[i] && Engine::mixer()->mixerChannel(i)->m_receives.isEmpty())
|
||||
{ deleteChannel(i); }
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
void FxMixerView::moveChannelLeft(int index, int focusIndex)
|
||||
void MixerView::moveChannelLeft(int index, int focusIndex)
|
||||
{
|
||||
// can't move master or first channel left or last channel right
|
||||
if( index <= 1 || index >= m_fxChannelViews.size() ) return;
|
||||
if( index <= 1 || index >= m_mixerChannelViews.size() ) return;
|
||||
|
||||
FxMixer *m = Engine::fxMixer();
|
||||
Mixer *m = Engine::mixer();
|
||||
|
||||
// Move instruments channels
|
||||
m->moveChannelLeft( index );
|
||||
|
||||
// Update widgets models
|
||||
m_fxChannelViews[index]->setChannelIndex( index );
|
||||
m_fxChannelViews[index - 1]->setChannelIndex( index - 1 );
|
||||
m_mixerChannelViews[index]->setChannelIndex( index );
|
||||
m_mixerChannelViews[index - 1]->setChannelIndex( index - 1 );
|
||||
|
||||
// Focus on new position
|
||||
setCurrentFxLine( focusIndex );
|
||||
setCurrentMixerLine( focusIndex );
|
||||
}
|
||||
|
||||
|
||||
|
||||
void FxMixerView::moveChannelLeft(int index)
|
||||
void MixerView::moveChannelLeft(int index)
|
||||
{
|
||||
moveChannelLeft( index, index - 1 );
|
||||
}
|
||||
|
||||
|
||||
|
||||
void FxMixerView::moveChannelRight(int index)
|
||||
void MixerView::moveChannelRight(int index)
|
||||
{
|
||||
moveChannelLeft( index + 1, index + 1 );
|
||||
}
|
||||
|
||||
|
||||
void FxMixerView::renameChannel(int index)
|
||||
void MixerView::renameChannel(int index)
|
||||
{
|
||||
m_fxChannelViews[index]->m_fxLine->renameChannel();
|
||||
m_mixerChannelViews[index]->m_mixerLine->renameChannel();
|
||||
}
|
||||
|
||||
|
||||
|
||||
void FxMixerView::keyPressEvent(QKeyEvent * e)
|
||||
void MixerView::keyPressEvent(QKeyEvent * e)
|
||||
{
|
||||
switch(e->key())
|
||||
{
|
||||
case Qt::Key_Delete:
|
||||
deleteChannel(m_currentFxLine->channelIndex());
|
||||
deleteChannel(m_currentMixerLine->channelIndex());
|
||||
break;
|
||||
case Qt::Key_Left:
|
||||
if( e->modifiers() & Qt::AltModifier )
|
||||
{
|
||||
moveChannelLeft( m_currentFxLine->channelIndex() );
|
||||
moveChannelLeft( m_currentMixerLine->channelIndex() );
|
||||
}
|
||||
else
|
||||
{
|
||||
// select channel to the left
|
||||
setCurrentFxLine( m_currentFxLine->channelIndex()-1 );
|
||||
setCurrentMixerLine( m_currentMixerLine->channelIndex()-1 );
|
||||
}
|
||||
break;
|
||||
case Qt::Key_Right:
|
||||
if( e->modifiers() & Qt::AltModifier )
|
||||
{
|
||||
moveChannelRight( m_currentFxLine->channelIndex() );
|
||||
moveChannelRight( m_currentMixerLine->channelIndex() );
|
||||
}
|
||||
else
|
||||
{
|
||||
// select channel to the right
|
||||
setCurrentFxLine( m_currentFxLine->channelIndex()+1 );
|
||||
setCurrentMixerLine( m_currentMixerLine->channelIndex()+1 );
|
||||
}
|
||||
break;
|
||||
case Qt::Key_Insert:
|
||||
@@ -546,14 +546,14 @@ void FxMixerView::keyPressEvent(QKeyEvent * e)
|
||||
case Qt::Key_Enter:
|
||||
case Qt::Key_Return:
|
||||
case Qt::Key_F2:
|
||||
renameChannel( m_currentFxLine->channelIndex() );
|
||||
renameChannel( m_currentMixerLine->channelIndex() );
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
void FxMixerView::closeEvent( QCloseEvent * _ce )
|
||||
void MixerView::closeEvent( QCloseEvent * _ce )
|
||||
{
|
||||
if( parentWidget() )
|
||||
{
|
||||
@@ -568,19 +568,19 @@ void FxMixerView::closeEvent( QCloseEvent * _ce )
|
||||
|
||||
|
||||
|
||||
void FxMixerView::setCurrentFxLine( int _line )
|
||||
void MixerView::setCurrentMixerLine( int _line )
|
||||
{
|
||||
if( _line >= 0 && _line < m_fxChannelViews.size() )
|
||||
if( _line >= 0 && _line < m_mixerChannelViews.size() )
|
||||
{
|
||||
setCurrentFxLine( m_fxChannelViews[_line]->m_fxLine );
|
||||
setCurrentMixerLine( m_mixerChannelViews[_line]->m_mixerLine );
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
void FxMixerView::clear()
|
||||
void MixerView::clear()
|
||||
{
|
||||
Engine::fxMixer()->clear();
|
||||
Engine::mixer()->clear();
|
||||
|
||||
refreshDisplay();
|
||||
}
|
||||
@@ -588,39 +588,39 @@ void FxMixerView::clear()
|
||||
|
||||
|
||||
|
||||
void FxMixerView::updateFaders()
|
||||
void MixerView::updateFaders()
|
||||
{
|
||||
FxMixer * m = Engine::fxMixer();
|
||||
Mixer * m = Engine::mixer();
|
||||
|
||||
// apply master gain
|
||||
m->effectChannel(0)->m_peakLeft *= Engine::audioEngine()->masterGain();
|
||||
m->effectChannel(0)->m_peakRight *= Engine::audioEngine()->masterGain();
|
||||
m->mixerChannel(0)->m_peakLeft *= Engine::audioEngine()->masterGain();
|
||||
m->mixerChannel(0)->m_peakRight *= Engine::audioEngine()->masterGain();
|
||||
|
||||
for( int i = 0; i < m_fxChannelViews.size(); ++i )
|
||||
for( int i = 0; i < m_mixerChannelViews.size(); ++i )
|
||||
{
|
||||
const float opl = m_fxChannelViews[i]->m_fader->getPeak_L();
|
||||
const float opr = m_fxChannelViews[i]->m_fader->getPeak_R();
|
||||
const float opl = m_mixerChannelViews[i]->m_fader->getPeak_L();
|
||||
const float opr = m_mixerChannelViews[i]->m_fader->getPeak_R();
|
||||
const float fallOff = 1.25;
|
||||
if( m->effectChannel(i)->m_peakLeft >= opl/fallOff )
|
||||
if( m->mixerChannel(i)->m_peakLeft >= opl/fallOff )
|
||||
{
|
||||
m_fxChannelViews[i]->m_fader->setPeak_L( m->effectChannel(i)->m_peakLeft );
|
||||
m_mixerChannelViews[i]->m_fader->setPeak_L( m->mixerChannel(i)->m_peakLeft );
|
||||
// Set to -1 so later we'll know if this value has been refreshed yet.
|
||||
m->effectChannel(i)->m_peakLeft = -1;
|
||||
m->mixerChannel(i)->m_peakLeft = -1;
|
||||
}
|
||||
else if( m->effectChannel(i)->m_peakLeft != -1 )
|
||||
else if( m->mixerChannel(i)->m_peakLeft != -1 )
|
||||
{
|
||||
m_fxChannelViews[i]->m_fader->setPeak_L( opl/fallOff );
|
||||
m_mixerChannelViews[i]->m_fader->setPeak_L( opl/fallOff );
|
||||
}
|
||||
|
||||
if( m->effectChannel(i)->m_peakRight >= opr/fallOff )
|
||||
if( m->mixerChannel(i)->m_peakRight >= opr/fallOff )
|
||||
{
|
||||
m_fxChannelViews[i]->m_fader->setPeak_R( m->effectChannel(i)->m_peakRight );
|
||||
m_mixerChannelViews[i]->m_fader->setPeak_R( m->mixerChannel(i)->m_peakRight );
|
||||
// Set to -1 so later we'll know if this value has been refreshed yet.
|
||||
m->effectChannel(i)->m_peakRight = -1;
|
||||
m->mixerChannel(i)->m_peakRight = -1;
|
||||
}
|
||||
else if( m->effectChannel(i)->m_peakRight != -1 )
|
||||
else if( m->mixerChannel(i)->m_peakRight != -1 )
|
||||
{
|
||||
m_fxChannelViews[i]->m_fader->setPeak_R( opr/fallOff );
|
||||
m_mixerChannelViews[i]->m_fader->setPeak_R( opr/fallOff );
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* SampleTCOView.cpp
|
||||
* SampleClipView.cpp
|
||||
*
|
||||
* Copyright (c) 2005-2014 Tobias Doerffel <tobydox/at/users.sourceforge.net>
|
||||
*
|
||||
@@ -22,7 +22,7 @@
|
||||
*
|
||||
*/
|
||||
|
||||
#include "SampleTCOView.h"
|
||||
#include "SampleClipView.h"
|
||||
|
||||
#include <QMenu>
|
||||
#include <QPainter>
|
||||
@@ -34,43 +34,43 @@
|
||||
#include "StringPairDrag.h"
|
||||
#include "ToolTip.h"
|
||||
|
||||
SampleTCOView::SampleTCOView( SampleTCO * _tco, TrackView * _tv ) :
|
||||
TrackContentObjectView( _tco, _tv ),
|
||||
m_tco( _tco ),
|
||||
SampleClipView::SampleClipView( SampleClip * _clip, TrackView * _tv ) :
|
||||
ClipView( _clip, _tv ),
|
||||
m_clip( _clip ),
|
||||
m_paintPixmap()
|
||||
{
|
||||
// update UI and tooltip
|
||||
updateSample();
|
||||
|
||||
// track future changes of SampleTCO
|
||||
connect(m_tco, SIGNAL(sampleChanged()), this, SLOT(updateSample()));
|
||||
// track future changes of SampleClip
|
||||
connect(m_clip, SIGNAL(sampleChanged()), this, SLOT(updateSample()));
|
||||
|
||||
connect(m_tco, SIGNAL(wasReversed()), this, SLOT(update()));
|
||||
connect(m_clip, SIGNAL(wasReversed()), this, SLOT(update()));
|
||||
|
||||
setStyle( QApplication::style() );
|
||||
}
|
||||
|
||||
void SampleTCOView::updateSample()
|
||||
void SampleClipView::updateSample()
|
||||
{
|
||||
update();
|
||||
// set tooltip to filename so that user can see what sample this
|
||||
// sample-tco contains
|
||||
ToolTip::add( this, ( m_tco->m_sampleBuffer->audioFile() != "" ) ?
|
||||
PathUtil::toAbsolute(m_tco->m_sampleBuffer->audioFile()) :
|
||||
// sample-clip contains
|
||||
ToolTip::add( this, ( m_clip->m_sampleBuffer->audioFile() != "" ) ?
|
||||
PathUtil::toAbsolute(m_clip->m_sampleBuffer->audioFile()) :
|
||||
tr( "Double-click to open sample" ) );
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
void SampleTCOView::constructContextMenu(QMenu* cm)
|
||||
void SampleClipView::constructContextMenu(QMenu* cm)
|
||||
{
|
||||
cm->addSeparator();
|
||||
|
||||
|
||||
cm->addAction(embed::getIconPixmap( "record" ),
|
||||
tr("Set/clear record"),
|
||||
m_tco, SLOT(toggleRecord()));
|
||||
m_clip, SLOT(toggleRecord()));
|
||||
|
||||
cm->addAction(
|
||||
embed::getIconPixmap("flip_x"),
|
||||
@@ -85,12 +85,12 @@ void SampleTCOView::constructContextMenu(QMenu* cm)
|
||||
|
||||
|
||||
|
||||
void SampleTCOView::dragEnterEvent( QDragEnterEvent * _dee )
|
||||
void SampleClipView::dragEnterEvent( QDragEnterEvent * _dee )
|
||||
{
|
||||
if( StringPairDrag::processDragEnterEvent( _dee,
|
||||
"samplefile,sampledata" ) == false )
|
||||
{
|
||||
TrackContentObjectView::dragEnterEvent( _dee );
|
||||
ClipView::dragEnterEvent( _dee );
|
||||
}
|
||||
}
|
||||
|
||||
@@ -99,85 +99,85 @@ void SampleTCOView::dragEnterEvent( QDragEnterEvent * _dee )
|
||||
|
||||
|
||||
|
||||
void SampleTCOView::dropEvent( QDropEvent * _de )
|
||||
void SampleClipView::dropEvent( QDropEvent * _de )
|
||||
{
|
||||
if( StringPairDrag::decodeKey( _de ) == "samplefile" )
|
||||
{
|
||||
m_tco->setSampleFile( StringPairDrag::decodeValue( _de ) );
|
||||
m_clip->setSampleFile( StringPairDrag::decodeValue( _de ) );
|
||||
_de->accept();
|
||||
}
|
||||
else if( StringPairDrag::decodeKey( _de ) == "sampledata" )
|
||||
{
|
||||
m_tco->m_sampleBuffer->loadFromBase64(
|
||||
m_clip->m_sampleBuffer->loadFromBase64(
|
||||
StringPairDrag::decodeValue( _de ) );
|
||||
m_tco->updateLength();
|
||||
m_clip->updateLength();
|
||||
update();
|
||||
_de->accept();
|
||||
Engine::getSong()->setModified();
|
||||
}
|
||||
else
|
||||
{
|
||||
TrackContentObjectView::dropEvent( _de );
|
||||
ClipView::dropEvent( _de );
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
void SampleTCOView::mousePressEvent( QMouseEvent * _me )
|
||||
void SampleClipView::mousePressEvent( QMouseEvent * _me )
|
||||
{
|
||||
if( _me->button() == Qt::LeftButton &&
|
||||
_me->modifiers() & Qt::ControlModifier &&
|
||||
_me->modifiers() & Qt::ShiftModifier )
|
||||
{
|
||||
m_tco->toggleRecord();
|
||||
m_clip->toggleRecord();
|
||||
}
|
||||
else
|
||||
{
|
||||
if( _me->button() == Qt::MiddleButton && _me->modifiers() == Qt::ControlModifier )
|
||||
{
|
||||
SampleTCO * sTco = dynamic_cast<SampleTCO*>( getTrackContentObject() );
|
||||
if( sTco )
|
||||
SampleClip * sClip = dynamic_cast<SampleClip*>( getClip() );
|
||||
if( sClip )
|
||||
{
|
||||
sTco->updateTrackTcos();
|
||||
sClip->updateTrackClips();
|
||||
}
|
||||
}
|
||||
TrackContentObjectView::mousePressEvent( _me );
|
||||
ClipView::mousePressEvent( _me );
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
void SampleTCOView::mouseReleaseEvent(QMouseEvent *_me)
|
||||
void SampleClipView::mouseReleaseEvent(QMouseEvent *_me)
|
||||
{
|
||||
if( _me->button() == Qt::MiddleButton && !_me->modifiers() )
|
||||
{
|
||||
SampleTCO * sTco = dynamic_cast<SampleTCO*>( getTrackContentObject() );
|
||||
if( sTco )
|
||||
SampleClip * sClip = dynamic_cast<SampleClip*>( getClip() );
|
||||
if( sClip )
|
||||
{
|
||||
sTco->playbackPositionChanged();
|
||||
sClip->playbackPositionChanged();
|
||||
}
|
||||
}
|
||||
TrackContentObjectView::mouseReleaseEvent( _me );
|
||||
ClipView::mouseReleaseEvent( _me );
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
void SampleTCOView::mouseDoubleClickEvent( QMouseEvent * )
|
||||
void SampleClipView::mouseDoubleClickEvent( QMouseEvent * )
|
||||
{
|
||||
QString af = m_tco->m_sampleBuffer->openAudioFile();
|
||||
QString af = m_clip->m_sampleBuffer->openAudioFile();
|
||||
|
||||
if ( af.isEmpty() ) {} //Don't do anything if no file is loaded
|
||||
else if ( af == m_tco->m_sampleBuffer->audioFile() )
|
||||
else if ( af == m_clip->m_sampleBuffer->audioFile() )
|
||||
{ //Instead of reloading the existing file, just reset the size
|
||||
int length = (int) ( m_tco->m_sampleBuffer->frames() / Engine::framesPerTick() );
|
||||
m_tco->changeLength(length);
|
||||
int length = (int) ( m_clip->m_sampleBuffer->frames() / Engine::framesPerTick() );
|
||||
m_clip->changeLength(length);
|
||||
}
|
||||
else
|
||||
{ //Otherwise load the new file as ususal
|
||||
m_tco->setSampleFile( af );
|
||||
m_clip->setSampleFile( af );
|
||||
Engine::getSong()->setModified();
|
||||
}
|
||||
}
|
||||
@@ -185,7 +185,7 @@ void SampleTCOView::mouseDoubleClickEvent( QMouseEvent * )
|
||||
|
||||
|
||||
|
||||
void SampleTCOView::paintEvent( QPaintEvent * pe )
|
||||
void SampleClipView::paintEvent( QPaintEvent * pe )
|
||||
{
|
||||
QPainter painter( this );
|
||||
|
||||
@@ -204,7 +204,7 @@ void SampleTCOView::paintEvent( QPaintEvent * pe )
|
||||
|
||||
QPainter p( &m_paintPixmap );
|
||||
|
||||
bool muted = m_tco->getTrack()->isMuted() || m_tco->isMuted();
|
||||
bool muted = m_clip->getTrack()->isMuted() || m_clip->isMuted();
|
||||
bool selected = isSelected();
|
||||
|
||||
QLinearGradient lingrad(0, 0, 0, height());
|
||||
@@ -215,7 +215,7 @@ void SampleTCOView::paintEvent( QPaintEvent * pe )
|
||||
lingrad.setColorAt( 1, c.darker( 300 ) );
|
||||
lingrad.setColorAt( 0, c );
|
||||
|
||||
// paint a black rectangle under the pattern to prevent glitches with transparent backgrounds
|
||||
// paint a black rectangle under the clip to prevent glitches with transparent backgrounds
|
||||
p.fillRect( rect(), QColor( 0, 0, 0 ) );
|
||||
|
||||
if( gradient() )
|
||||
@@ -227,13 +227,13 @@ void SampleTCOView::paintEvent( QPaintEvent * pe )
|
||||
p.fillRect( rect(), c );
|
||||
}
|
||||
|
||||
auto tcoColor = m_tco->hasColor()
|
||||
? (m_tco->usesCustomClipColor()
|
||||
? m_tco->color()
|
||||
: m_tco->getTrack()->color())
|
||||
auto clipColor = m_clip->hasColor()
|
||||
? (m_clip->usesCustomClipColor()
|
||||
? m_clip->color()
|
||||
: m_clip->getTrack()->color())
|
||||
: painter.pen().brush().color();
|
||||
|
||||
p.setPen(tcoColor);
|
||||
p.setPen(clipColor);
|
||||
|
||||
if (muted)
|
||||
{
|
||||
@@ -246,22 +246,22 @@ void SampleTCOView::paintEvent( QPaintEvent * pe )
|
||||
p.setPen(p.pen().brush().color().darker(150));
|
||||
}
|
||||
|
||||
const int spacing = TCO_BORDER_WIDTH + 1;
|
||||
const float ppb = fixedTCOs() ?
|
||||
( parentWidget()->width() - 2 * TCO_BORDER_WIDTH )
|
||||
/ (float) m_tco->length().getBar() :
|
||||
const int spacing = CLIP_BORDER_WIDTH + 1;
|
||||
const float ppb = fixedClips() ?
|
||||
( parentWidget()->width() - 2 * CLIP_BORDER_WIDTH )
|
||||
/ (float) m_clip->length().getBar() :
|
||||
pixelsPerBar();
|
||||
|
||||
float nom = Engine::getSong()->getTimeSigModel().getNumerator();
|
||||
float den = Engine::getSong()->getTimeSigModel().getDenominator();
|
||||
float ticksPerBar = DefaultTicksPerBar * nom / den;
|
||||
|
||||
float offset = m_tco->startTimeOffset() / ticksPerBar * pixelsPerBar();
|
||||
float offset = m_clip->startTimeOffset() / ticksPerBar * pixelsPerBar();
|
||||
QRect r = QRect( offset, spacing,
|
||||
qMax( static_cast<int>( m_tco->sampleLength() * ppb / ticksPerBar ), 1 ), rect().bottom() - 2 * spacing );
|
||||
m_tco->m_sampleBuffer->visualize( p, r, pe->rect() );
|
||||
qMax( static_cast<int>( m_clip->sampleLength() * ppb / ticksPerBar ), 1 ), rect().bottom() - 2 * spacing );
|
||||
m_clip->m_sampleBuffer->visualize( p, r, pe->rect() );
|
||||
|
||||
QString name = PathUtil::cleanName(m_tco->m_sampleBuffer->audioFile());
|
||||
QString name = PathUtil::cleanName(m_clip->m_sampleBuffer->audioFile());
|
||||
paintTextLabel(name, p);
|
||||
|
||||
// disable antialiasing for borders, since its not needed
|
||||
@@ -269,17 +269,17 @@ void SampleTCOView::paintEvent( QPaintEvent * pe )
|
||||
|
||||
// inner border
|
||||
p.setPen( c.lighter( 135 ) );
|
||||
p.drawRect( 1, 1, rect().right() - TCO_BORDER_WIDTH,
|
||||
rect().bottom() - TCO_BORDER_WIDTH );
|
||||
p.drawRect( 1, 1, rect().right() - CLIP_BORDER_WIDTH,
|
||||
rect().bottom() - CLIP_BORDER_WIDTH );
|
||||
|
||||
// outer border
|
||||
p.setPen( c.darker( 200 ) );
|
||||
p.drawRect( 0, 0, rect().right(), rect().bottom() );
|
||||
|
||||
// draw the 'muted' pixmap only if the pattern was manualy muted
|
||||
if( m_tco->isMuted() )
|
||||
// draw the 'muted' pixmap only if the clip was manualy muted
|
||||
if( m_clip->isMuted() )
|
||||
{
|
||||
const int spacing = TCO_BORDER_WIDTH;
|
||||
const int spacing = CLIP_BORDER_WIDTH;
|
||||
const int size = 14;
|
||||
p.drawPixmap( spacing, height() - ( size + spacing ),
|
||||
embed::getIconPixmap( "muted", size, size ) );
|
||||
@@ -291,7 +291,7 @@ void SampleTCOView::paintEvent( QPaintEvent * pe )
|
||||
}
|
||||
// recording sample tracks is not possible at the moment
|
||||
|
||||
if(m_tco->isRecord())
|
||||
if(m_clip->isRecord())
|
||||
{
|
||||
p.setFont( pointSize<7>( p.font() ) );
|
||||
|
||||
@@ -312,9 +312,9 @@ void SampleTCOView::paintEvent( QPaintEvent * pe )
|
||||
|
||||
|
||||
|
||||
void SampleTCOView::reverseSample()
|
||||
void SampleClipView::reverseSample()
|
||||
{
|
||||
m_tco->sampleBuffer()->setReversed(!m_tco->sampleBuffer()->reversed());
|
||||
m_clip->sampleBuffer()->setReversed(!m_clip->sampleBuffer()->reversed());
|
||||
Engine::getSong()->setModified();
|
||||
update();
|
||||
}
|
||||
@@ -322,32 +322,32 @@ void SampleTCOView::reverseSample()
|
||||
|
||||
|
||||
|
||||
//! Split this TCO.
|
||||
//! Split this Clip.
|
||||
/*! \param pos the position of the split, relative to the start of the clip */
|
||||
bool SampleTCOView::splitTCO( const TimePos pos )
|
||||
bool SampleClipView::splitClip( const TimePos pos )
|
||||
{
|
||||
setMarkerEnabled( false );
|
||||
|
||||
const TimePos splitPos = m_initialTCOPos + pos;
|
||||
const TimePos splitPos = m_initialClipPos + pos;
|
||||
|
||||
//Don't split if we slid off the TCO or if we're on the clip's start/end
|
||||
//Don't split if we slid off the Clip or if we're on the clip's start/end
|
||||
//Cutting at exactly the start/end position would create a zero length
|
||||
//clip (bad), and a clip the same length as the original one (pointless).
|
||||
if ( splitPos > m_initialTCOPos && splitPos < m_initialTCOEnd )
|
||||
if ( splitPos > m_initialClipPos && splitPos < m_initialClipEnd )
|
||||
{
|
||||
m_tco->getTrack()->addJournalCheckPoint();
|
||||
m_tco->getTrack()->saveJournallingState( false );
|
||||
m_clip->getTrack()->addJournalCheckPoint();
|
||||
m_clip->getTrack()->saveJournallingState( false );
|
||||
|
||||
SampleTCO * rightTCO = new SampleTCO ( *m_tco );
|
||||
SampleClip * rightClip = new SampleClip ( *m_clip );
|
||||
|
||||
m_tco->changeLength( splitPos - m_initialTCOPos );
|
||||
m_clip->changeLength( splitPos - m_initialClipPos );
|
||||
|
||||
rightTCO->movePosition( splitPos );
|
||||
rightTCO->changeLength( m_initialTCOEnd - splitPos );
|
||||
rightTCO->setStartTimeOffset( m_tco->startTimeOffset() - m_tco->length() );
|
||||
rightClip->movePosition( splitPos );
|
||||
rightClip->changeLength( m_initialClipEnd - splitPos );
|
||||
rightClip->setStartTimeOffset( m_clip->startTimeOffset() - m_clip->length() );
|
||||
|
||||
m_tco->getTrack()->restoreJournallingState();
|
||||
m_clip->getTrack()->restoreJournallingState();
|
||||
return true;
|
||||
}
|
||||
else { return false; }
|
||||
}
|
||||
}
|
||||
@@ -28,7 +28,7 @@
|
||||
|
||||
#include "embed.h"
|
||||
#include "Engine.h"
|
||||
#include "FxMixerView.h"
|
||||
#include "MixerView.h"
|
||||
#include "gui_templates.h"
|
||||
#include "GuiApplication.h"
|
||||
#include "Knob.h"
|
||||
@@ -114,39 +114,39 @@ SampleTrackView::~SampleTrackView()
|
||||
|
||||
|
||||
|
||||
//FIXME: This is identical to InstrumentTrackView::createFxMenu
|
||||
QMenu * SampleTrackView::createFxMenu(QString title, QString newFxLabel)
|
||||
//FIXME: This is identical to InstrumentTrackView::createMixerMenu
|
||||
QMenu * SampleTrackView::createMixerMenu(QString title, QString newMixerLabel)
|
||||
{
|
||||
int channelIndex = model()->effectChannelModel()->value();
|
||||
int channelIndex = model()->mixerChannelModel()->value();
|
||||
|
||||
FxChannel *fxChannel = Engine::fxMixer()->effectChannel(channelIndex);
|
||||
MixerChannel *mixerChannel = Engine::mixer()->mixerChannel(channelIndex);
|
||||
|
||||
// If title allows interpolation, pass channel index and name
|
||||
if (title.contains("%2"))
|
||||
{
|
||||
title = title.arg(channelIndex).arg(fxChannel->m_name);
|
||||
title = title.arg(channelIndex).arg(mixerChannel->m_name);
|
||||
}
|
||||
|
||||
QMenu *fxMenu = new QMenu(title);
|
||||
QMenu *mixerMenu = new QMenu(title);
|
||||
|
||||
fxMenu->addAction(newFxLabel, this, SLOT(createFxLine()));
|
||||
fxMenu->addSeparator();
|
||||
mixerMenu->addAction(newMixerLabel, this, SLOT(createMixerLine()));
|
||||
mixerMenu->addSeparator();
|
||||
|
||||
for (int i = 0; i < Engine::fxMixer()->numChannels(); ++i)
|
||||
for (int i = 0; i < Engine::mixer()->numChannels(); ++i)
|
||||
{
|
||||
FxChannel * currentChannel = Engine::fxMixer()->effectChannel(i);
|
||||
MixerChannel * currentChannel = Engine::mixer()->mixerChannel(i);
|
||||
|
||||
if (currentChannel != fxChannel)
|
||||
if (currentChannel != mixerChannel)
|
||||
{
|
||||
const auto index = currentChannel->m_channelIndex;
|
||||
QString label = tr("FX %1: %2").arg(currentChannel->m_channelIndex).arg(currentChannel->m_name);
|
||||
fxMenu->addAction(label, [this, index](){
|
||||
assignFxLine(index);
|
||||
QString label = tr("%1: %2").arg(currentChannel->m_channelIndex).arg(currentChannel->m_name);
|
||||
mixerMenu->addAction(label, [this, index](){
|
||||
assignMixerLine(index);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
return fxMenu;
|
||||
return mixerMenu;
|
||||
}
|
||||
|
||||
|
||||
@@ -193,39 +193,39 @@ void SampleTrackView::dropEvent(QDropEvent *de)
|
||||
? trackHeadWidth
|
||||
: de->pos().x();
|
||||
|
||||
TimePos tcoPos = trackContainerView()->fixedTCOs()
|
||||
TimePos clipPos = trackContainerView()->fixedClips()
|
||||
? TimePos(0)
|
||||
: TimePos(((xPos - trackHeadWidth) / trackContainerView()->pixelsPerBar()
|
||||
* TimePos::ticksPerBar()) + trackContainerView()->currentPosition()
|
||||
).quantize(1.0);
|
||||
|
||||
SampleTCO * sTco = static_cast<SampleTCO*>(getTrack()->createTCO(tcoPos));
|
||||
if (sTco) { sTco->setSampleFile(value); }
|
||||
SampleClip * sClip = static_cast<SampleClip*>(getTrack()->createClip(clipPos));
|
||||
if (sClip) { sClip->setSampleFile(value); }
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
/*! \brief Create and assign a new FX Channel for this track */
|
||||
void SampleTrackView::createFxLine()
|
||||
/*! \brief Create and assign a new mixer Channel for this track */
|
||||
void SampleTrackView::createMixerLine()
|
||||
{
|
||||
int channelIndex = getGUI()->fxMixerView()->addNewChannel();
|
||||
auto channel = Engine::fxMixer()->effectChannel(channelIndex);
|
||||
int channelIndex = getGUI()->mixerView()->addNewChannel();
|
||||
auto channel = Engine::mixer()->mixerChannel(channelIndex);
|
||||
|
||||
channel->m_name = getTrack()->name();
|
||||
if (getTrack()->useColor()) { channel->setColor (getTrack()->color()); }
|
||||
|
||||
assignFxLine(channelIndex);
|
||||
assignMixerLine(channelIndex);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
/*! \brief Assign a specific FX Channel for this track */
|
||||
void SampleTrackView::assignFxLine(int channelIndex)
|
||||
/*! \brief Assign a specific mixer Channel for this track */
|
||||
void SampleTrackView::assignMixerLine(int channelIndex)
|
||||
{
|
||||
model()->effectChannelModel()->setValue(channelIndex);
|
||||
model()->mixerChannelModel()->setValue(channelIndex);
|
||||
|
||||
getGUI()->fxMixerView()->setCurrentFxLine(channelIndex);
|
||||
getGUI()->mixerView()->setCurrentMixerLine(channelIndex);
|
||||
}
|
||||
@@ -113,13 +113,13 @@ SampleTrackWindow::SampleTrackWindow(SampleTrackView * tv) :
|
||||
basicControlsLayout->setColumnStretch(2, 1);
|
||||
|
||||
|
||||
// setup spinbox for selecting FX-channel
|
||||
m_effectChannelNumber = new FxLineLcdSpinBox(2, nullptr, tr("FX channel"), m_stv);
|
||||
// setup spinbox for selecting Mixer-channel
|
||||
m_mixerChannelNumber = new MixerLineLcdSpinBox(2, nullptr, tr("Mixer channel"), m_stv);
|
||||
|
||||
basicControlsLayout->addWidget(m_effectChannelNumber, 0, 3);
|
||||
basicControlsLayout->setAlignment(m_effectChannelNumber, widgetAlignment);
|
||||
basicControlsLayout->addWidget(m_mixerChannelNumber, 0, 3);
|
||||
basicControlsLayout->setAlignment(m_mixerChannelNumber, widgetAlignment);
|
||||
|
||||
label = new QLabel(tr("FX"), this);
|
||||
label = new QLabel(tr("CHANNEL"), this);
|
||||
label->setStyleSheet(labelStyleSheet);
|
||||
basicControlsLayout->addWidget(label, 1, 3);
|
||||
basicControlsLayout->setAlignment(label, labelAlignment);
|
||||
@@ -183,7 +183,7 @@ void SampleTrackWindow::modelChanged()
|
||||
|
||||
m_volumeKnob->setModel(&m_track->m_volumeModel);
|
||||
m_panningKnob->setModel(&m_track->m_panningModel);
|
||||
m_effectChannelNumber->setModel(&m_track->m_effectChannelModel);
|
||||
m_mixerChannelNumber->setModel(&m_track->m_mixerChannelModel);
|
||||
|
||||
updateName();
|
||||
}
|
||||
|
||||
@@ -141,9 +141,9 @@ SetupDialog::SetupDialog(ConfigTabs tab_to_open) :
|
||||
m_NaNHandler(ConfigManager::inst()->value(
|
||||
"app", "nanhandler", "1").toInt()),
|
||||
m_hqAudioDev(ConfigManager::inst()->value(
|
||||
"mixer", "hqaudio").toInt()),
|
||||
"audioengine", "hqaudio").toInt()),
|
||||
m_bufferSize(ConfigManager::inst()->value(
|
||||
"mixer", "framesperaudiobuffer").toInt()),
|
||||
"audioengine", "framesperaudiobuffer").toInt()),
|
||||
m_workingDir(QDir::toNativeSeparators(ConfigManager::inst()->workingDir())),
|
||||
m_vstDir(QDir::toNativeSeparators(ConfigManager::inst()->vstDir())),
|
||||
m_ladspaDir(QDir::toNativeSeparators(ConfigManager::inst()->ladspaDir())),
|
||||
@@ -533,11 +533,11 @@ SetupDialog::SetupDialog(ConfigTabs tab_to_open) :
|
||||
}
|
||||
|
||||
// If no preferred audio device is saved, save the current one.
|
||||
QString audioDevName = ConfigManager::inst()->value("mixer", "audiodev");
|
||||
QString audioDevName = ConfigManager::inst()->value("audioengine", "audiodev");
|
||||
if (m_audioInterfaces->findText(audioDevName) < 0)
|
||||
{
|
||||
audioDevName = Engine::audioEngine()->audioDevName();
|
||||
ConfigManager::inst()->setValue("mixer", "audiodev", audioDevName);
|
||||
ConfigManager::inst()->setValue("audioengine", "audiodev", audioDevName);
|
||||
}
|
||||
m_audioInterfaces->
|
||||
setCurrentIndex(m_audioInterfaces->findText(audioDevName));
|
||||
@@ -678,11 +678,11 @@ SetupDialog::SetupDialog(ConfigTabs tab_to_open) :
|
||||
m_midiInterfaces->addItem(it.key());
|
||||
}
|
||||
|
||||
QString midiDevName = ConfigManager::inst()->value("mixer", "mididev");
|
||||
QString midiDevName = ConfigManager::inst()->value("audioengine", "mididev");
|
||||
if (m_midiInterfaces->findText(midiDevName) < 0)
|
||||
{
|
||||
midiDevName = Engine::audioEngine()->midiClientName();
|
||||
ConfigManager::inst()->setValue("mixer", "mididev", midiDevName);
|
||||
ConfigManager::inst()->setValue("audioengine", "mididev", midiDevName);
|
||||
}
|
||||
m_midiInterfaces->setCurrentIndex(m_midiInterfaces->findText(midiDevName));
|
||||
m_midiIfaceSetupWidgets[midiDevName]->show();
|
||||
@@ -950,15 +950,15 @@ void SetupDialog::accept()
|
||||
QString::number(m_syncVSTPlugins));
|
||||
ConfigManager::inst()->setValue("ui", "disableautoquit",
|
||||
QString::number(m_disableAutoQuit));
|
||||
ConfigManager::inst()->setValue("mixer", "audiodev",
|
||||
ConfigManager::inst()->setValue("audioengine", "audiodev",
|
||||
m_audioIfaceNames[m_audioInterfaces->currentText()]);
|
||||
ConfigManager::inst()->setValue("app", "nanhandler",
|
||||
QString::number(m_NaNHandler));
|
||||
ConfigManager::inst()->setValue("mixer", "hqaudio",
|
||||
ConfigManager::inst()->setValue("audioengine", "hqaudio",
|
||||
QString::number(m_hqAudioDev));
|
||||
ConfigManager::inst()->setValue("mixer", "framesperaudiobuffer",
|
||||
ConfigManager::inst()->setValue("audioengine", "framesperaudiobuffer",
|
||||
QString::number(m_bufferSize));
|
||||
ConfigManager::inst()->setValue("mixer", "mididev",
|
||||
ConfigManager::inst()->setValue("audioengine", "mididev",
|
||||
m_midiIfaceNames[m_midiInterfaces->currentText()]);
|
||||
ConfigManager::inst()->setValue("midi", "midiautoassign",
|
||||
m_assignableMidiDevices->currentText());
|
||||
|
||||
@@ -238,7 +238,8 @@ void TimeLineWidget::paintEvent( QPaintEvent * )
|
||||
p.fillRect( 0, 0, width(), height(), p.background() );
|
||||
|
||||
// Clip so that we only draw everything starting from the offset
|
||||
p.setClipRect( m_xOffset, 0, width() - m_xOffset, height() );
|
||||
const int leftMargin = m_xOffset + s_posMarkerPixmap->width() / 2;
|
||||
p.setClipRect(leftMargin, 0, width() - leftMargin, height() );
|
||||
|
||||
// Draw the loop rectangle
|
||||
int const & loopRectMargin = getLoopRectangleVerticalPadding();
|
||||
@@ -296,9 +297,14 @@ void TimeLineWidget::paintEvent( QPaintEvent * )
|
||||
p.setBrush( Qt::NoBrush );
|
||||
p.drawRect( innerRectangle );
|
||||
|
||||
// Draw the position marker
|
||||
p.setOpacity( 0.6 );
|
||||
p.drawPixmap( m_posMarkerX, height() - s_posMarkerPixmap->height(), *s_posMarkerPixmap );
|
||||
// Only draw the position marker if the position line is in view
|
||||
if (m_posMarkerX >= m_xOffset && m_posMarkerX < width() - s_posMarkerPixmap->width() / 2)
|
||||
{
|
||||
// Let the position marker extrude to the left
|
||||
p.setClipping(false);
|
||||
p.setOpacity(0.6);
|
||||
p.drawPixmap(m_posMarkerX, height() - s_posMarkerPixmap->height(), *s_posMarkerPixmap);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -324,7 +330,7 @@ void TimeLineWidget::mousePressEvent( QMouseEvent* event )
|
||||
}
|
||||
else if( event->button() == Qt::LeftButton && (event->modifiers() & Qt::ShiftModifier) )
|
||||
{
|
||||
m_action = SelectSongTCO;
|
||||
m_action = SelectSongClip;
|
||||
m_initalXSelect = event->x();
|
||||
}
|
||||
else if( event->button() == Qt::RightButton )
|
||||
@@ -416,7 +422,7 @@ void TimeLineWidget::mouseMoveEvent( QMouseEvent* event )
|
||||
update();
|
||||
break;
|
||||
}
|
||||
case SelectSongTCO:
|
||||
case SelectSongClip:
|
||||
emit regionSelectedFromPixels( m_initalXSelect , event->x() );
|
||||
break;
|
||||
|
||||
@@ -432,6 +438,6 @@ void TimeLineWidget::mouseReleaseEvent( QMouseEvent* event )
|
||||
{
|
||||
delete m_hint;
|
||||
m_hint = nullptr;
|
||||
if ( m_action == SelectSongTCO ) { emit selectionFinished(); }
|
||||
if ( m_action == SelectSongClip ) { emit selectionFinished(); }
|
||||
m_action = NoAction;
|
||||
}
|
||||
|
||||
@@ -44,7 +44,7 @@
|
||||
#include "ToolTip.h"
|
||||
#include "Track.h"
|
||||
#include "TrackContainerView.h"
|
||||
#include "TrackContentObjectView.h"
|
||||
#include "ClipView.h"
|
||||
|
||||
|
||||
/*! \brief Create a new track View.
|
||||
@@ -89,8 +89,8 @@ TrackView::TrackView( Track * track, TrackContainerView * tcv ) :
|
||||
|
||||
connect( m_track, SIGNAL( destroyedTrack() ), this, SLOT( close() ) );
|
||||
connect( m_track,
|
||||
SIGNAL( trackContentObjectAdded( TrackContentObject * ) ),
|
||||
this, SLOT( createTCOView( TrackContentObject * ) ),
|
||||
SIGNAL( clipAdded( Clip * ) ),
|
||||
this, SLOT( createClipView( Clip * ) ),
|
||||
Qt::QueuedConnection );
|
||||
|
||||
connect( &m_track->m_mutedModel, SIGNAL( dataChanged() ),
|
||||
@@ -102,12 +102,10 @@ TrackView::TrackView( Track * track, TrackContainerView * tcv ) :
|
||||
connect( &m_track->m_soloModel, SIGNAL( dataChanged() ),
|
||||
m_track, SLOT( toggleSolo() ), Qt::DirectConnection );
|
||||
|
||||
// create views for already existing TCOs
|
||||
for( Track::tcoVector::iterator it =
|
||||
m_track->m_trackContentObjects.begin();
|
||||
it != m_track->m_trackContentObjects.end(); ++it )
|
||||
// create views for already existing clips
|
||||
for( Track::clipVector::iterator it = m_track->m_clips.begin(); it != m_track->m_clips.end(); ++it )
|
||||
{
|
||||
createTCOView( *it );
|
||||
createClipView( *it );
|
||||
}
|
||||
|
||||
m_trackContainerView->addTrackView( this );
|
||||
@@ -155,7 +153,7 @@ void TrackView::resizeEvent( QResizeEvent * re )
|
||||
void TrackView::update()
|
||||
{
|
||||
m_trackContentWidget.update();
|
||||
if( !m_trackContainerView->fixedTCOs() )
|
||||
if( !m_trackContainerView->fixedClips() )
|
||||
{
|
||||
m_trackContentWidget.changePosition();
|
||||
}
|
||||
@@ -168,10 +166,10 @@ void TrackView::update()
|
||||
/*! \brief Create a menu for assigning/creating channels for this track.
|
||||
*
|
||||
*/
|
||||
QMenu * TrackView::createFxMenu(QString title, QString newFxLabel)
|
||||
QMenu * TrackView::createMixerMenu(QString title, QString newMixerLabel)
|
||||
{
|
||||
Q_UNUSED(title)
|
||||
Q_UNUSED(newFxLabel)
|
||||
Q_UNUSED(newMixerLabel)
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
@@ -418,19 +416,19 @@ void TrackView::paintEvent( QPaintEvent * pe )
|
||||
|
||||
|
||||
|
||||
/*! \brief Create a TrackContentObject View in this track View.
|
||||
/*! \brief Create a Clip View in this track View.
|
||||
*
|
||||
* \param tco the TrackContentObject to create the view for.
|
||||
* \param clip the Clip to create the view for.
|
||||
* \todo is this a good description for what this method does?
|
||||
*/
|
||||
void TrackView::createTCOView( TrackContentObject * tco )
|
||||
void TrackView::createClipView( Clip * clip )
|
||||
{
|
||||
TrackContentObjectView * tv = tco->createView( this );
|
||||
if( tco->getSelectViewOnCreate() == true )
|
||||
ClipView * tv = clip->createView( this );
|
||||
if( clip->getSelectViewOnCreate() == true )
|
||||
{
|
||||
tv->setSelected( true );
|
||||
}
|
||||
tco->selectViewOnCreate( false );
|
||||
clip->selectViewOnCreate( false );
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -81,7 +81,7 @@ AutomationEditor::AutomationEditor() :
|
||||
m_zoomingXModel(),
|
||||
m_zoomingYModel(),
|
||||
m_quantizeModel(),
|
||||
m_pattern(nullptr),
|
||||
m_clip(nullptr),
|
||||
m_minLevel( 0 ),
|
||||
m_maxLevel( 0 ),
|
||||
m_step( 1 ),
|
||||
@@ -109,8 +109,8 @@ AutomationEditor::AutomationEditor() :
|
||||
m_crossColor(0, 0, 0),
|
||||
m_backgroundShade(0, 0, 0)
|
||||
{
|
||||
connect( this, SIGNAL( currentPatternChanged() ),
|
||||
this, SLOT( updateAfterPatternChange() ),
|
||||
connect( this, SIGNAL( currentClipChanged() ),
|
||||
this, SLOT( updateAfterClipChange() ),
|
||||
Qt::QueuedConnection );
|
||||
connect( Engine::getSong(), SIGNAL( timeSignatureChanged( int, int ) ),
|
||||
this, SLOT( update() ) );
|
||||
@@ -146,9 +146,9 @@ AutomationEditor::AutomationEditor() :
|
||||
// add time-line
|
||||
m_timeLine = new TimeLineWidget( VALUES_WIDTH, 0, m_ppb,
|
||||
Engine::getSong()->getPlayPos(
|
||||
Song::Mode_PlayAutomationPattern ),
|
||||
Song::Mode_PlayAutomationClip ),
|
||||
m_currentPosition,
|
||||
Song::Mode_PlayAutomationPattern, this );
|
||||
Song::Mode_PlayAutomationClip, this );
|
||||
connect( this, SIGNAL( positionChanged( const TimePos & ) ),
|
||||
m_timeLine, SLOT( updatePosition( const TimePos & ) ) );
|
||||
connect( m_timeLine, SIGNAL( positionChanged( const TimePos & ) ),
|
||||
@@ -184,7 +184,7 @@ AutomationEditor::AutomationEditor() :
|
||||
s_toolMove = new QPixmap(embed::getIconPixmap("edit_move"));
|
||||
}
|
||||
|
||||
setCurrentPattern(nullptr);
|
||||
setCurrentClip(nullptr);
|
||||
|
||||
setMouseTracking( true );
|
||||
setFocusPolicy( Qt::StrongFocus );
|
||||
@@ -207,21 +207,21 @@ AutomationEditor::~AutomationEditor()
|
||||
|
||||
|
||||
|
||||
void AutomationEditor::setCurrentPattern(AutomationPattern * new_pattern )
|
||||
void AutomationEditor::setCurrentClip(AutomationClip * new_clip )
|
||||
{
|
||||
if (m_pattern)
|
||||
if (m_clip)
|
||||
{
|
||||
m_pattern->disconnect(this);
|
||||
m_clip->disconnect(this);
|
||||
}
|
||||
|
||||
m_pattern = new_pattern;
|
||||
m_clip = new_clip;
|
||||
|
||||
if (m_pattern != nullptr)
|
||||
if (m_clip != nullptr)
|
||||
{
|
||||
connect(m_pattern, SIGNAL(dataChanged()), this, SLOT(update()));
|
||||
connect(m_clip, SIGNAL(dataChanged()), this, SLOT(update()));
|
||||
}
|
||||
|
||||
emit currentPatternChanged();
|
||||
emit currentClipChanged();
|
||||
}
|
||||
|
||||
|
||||
@@ -243,11 +243,11 @@ void AutomationEditor::loadSettings( const QDomElement & dom_parent)
|
||||
|
||||
|
||||
|
||||
void AutomationEditor::updateAfterPatternChange()
|
||||
void AutomationEditor::updateAfterClipChange()
|
||||
{
|
||||
m_currentPosition = 0;
|
||||
|
||||
if( !validPattern() )
|
||||
if( !validClip() )
|
||||
{
|
||||
m_minLevel = m_maxLevel = m_scrollLevel = 0;
|
||||
m_step = 1;
|
||||
@@ -255,12 +255,12 @@ void AutomationEditor::updateAfterPatternChange()
|
||||
return;
|
||||
}
|
||||
|
||||
m_minLevel = m_pattern->firstObject()->minValue<float>();
|
||||
m_maxLevel = m_pattern->firstObject()->maxValue<float>();
|
||||
m_step = m_pattern->firstObject()->step<float>();
|
||||
m_minLevel = m_clip->firstObject()->minValue<float>();
|
||||
m_maxLevel = m_clip->firstObject()->maxValue<float>();
|
||||
m_step = m_clip->firstObject()->step<float>();
|
||||
centerTopBottomScroll();
|
||||
|
||||
m_tensionModel->setValue( m_pattern->getTension() );
|
||||
m_tensionModel->setValue( m_clip->getTension() );
|
||||
|
||||
// resizeEvent() does the rest for us (scrolling, range-checking
|
||||
// of levels and so on...)
|
||||
@@ -277,7 +277,7 @@ void AutomationEditor::update()
|
||||
QWidget::update();
|
||||
|
||||
// Note detuning?
|
||||
if( m_pattern && !m_pattern->getTrack() )
|
||||
if( m_clip && !m_clip->getTrack() )
|
||||
{
|
||||
getGUI()->pianoRoll()->update();
|
||||
}
|
||||
@@ -344,8 +344,8 @@ void AutomationEditor::leaveEvent(QEvent * e )
|
||||
|
||||
void AutomationEditor::drawLine( int x0In, float y0, int x1In, float y1 )
|
||||
{
|
||||
int x0 = Note::quantized( x0In, AutomationPattern::quantization() );
|
||||
int x1 = Note::quantized( x1In, AutomationPattern::quantization() );
|
||||
int x0 = Note::quantized( x0In, AutomationClip::quantization() );
|
||||
int x1 = Note::quantized( x1In, AutomationClip::quantization() );
|
||||
int deltax = qAbs( x1 - x0 );
|
||||
float deltay = qAbs<float>( y1 - y0 );
|
||||
int x = x0;
|
||||
@@ -353,22 +353,22 @@ void AutomationEditor::drawLine( int x0In, float y0, int x1In, float y1 )
|
||||
int xstep;
|
||||
int ystep;
|
||||
|
||||
if( deltax < AutomationPattern::quantization() )
|
||||
if( deltax < AutomationClip::quantization() )
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
deltax /= AutomationPattern::quantization();
|
||||
deltax /= AutomationClip::quantization();
|
||||
|
||||
float yscale = deltay / ( deltax );
|
||||
|
||||
if( x0 < x1 )
|
||||
{
|
||||
xstep = AutomationPattern::quantization();
|
||||
xstep = AutomationClip::quantization();
|
||||
}
|
||||
else
|
||||
{
|
||||
xstep = -( AutomationPattern::quantization() );
|
||||
xstep = -( AutomationClip::quantization() );
|
||||
}
|
||||
|
||||
float lineAdjust;
|
||||
@@ -390,8 +390,8 @@ void AutomationEditor::drawLine( int x0In, float y0, int x1In, float y1 )
|
||||
|
||||
x += xstep;
|
||||
i += 1;
|
||||
m_pattern->removeNode(TimePos(x));
|
||||
m_pattern->putValue( TimePos( x ), y );
|
||||
m_clip->removeNode(TimePos(x));
|
||||
m_clip->putValue( TimePos( x ), y );
|
||||
}
|
||||
}
|
||||
|
||||
@@ -400,7 +400,7 @@ void AutomationEditor::drawLine( int x0In, float y0, int x1In, float y1 )
|
||||
|
||||
bool AutomationEditor::fineTuneValue(timeMap::iterator node, bool editingOutValue)
|
||||
{
|
||||
if (node == m_pattern->getTimeMap().end()) { return false; }
|
||||
if (node == m_clip->getTimeMap().end()) { return false; }
|
||||
|
||||
// Display dialog to edit the value
|
||||
bool ok;
|
||||
@@ -413,8 +413,8 @@ bool AutomationEditor::fineTuneValue(timeMap::iterator node, bool editingOutValu
|
||||
editingOutValue
|
||||
? OUTVAL(node)
|
||||
: INVAL(node),
|
||||
m_pattern->firstObject()->minValue<float>(),
|
||||
m_pattern->firstObject()->maxValue<float>(),
|
||||
m_clip->firstObject()->minValue<float>(),
|
||||
m_clip->firstObject()->maxValue<float>(),
|
||||
3,
|
||||
&ok
|
||||
);
|
||||
@@ -447,7 +447,7 @@ bool AutomationEditor::fineTuneValue(timeMap::iterator node, bool editingOutValu
|
||||
|
||||
void AutomationEditor::mousePressEvent( QMouseEvent* mouseEvent )
|
||||
{
|
||||
if( !validPattern() )
|
||||
if( !validClip() )
|
||||
{
|
||||
return;
|
||||
}
|
||||
@@ -455,15 +455,15 @@ void AutomationEditor::mousePressEvent( QMouseEvent* mouseEvent )
|
||||
// Some helper lambda functions to avoid repetition of code
|
||||
auto eraseNode = [this](timeMap::iterator node)
|
||||
{
|
||||
if (node != m_pattern->getTimeMap().end())
|
||||
if (node != m_clip->getTimeMap().end())
|
||||
{
|
||||
m_pattern->removeNode(POS(node));
|
||||
m_clip->removeNode(POS(node));
|
||||
Engine::getSong()->setModified();
|
||||
}
|
||||
};
|
||||
auto resetNode = [this](timeMap::iterator node)
|
||||
{
|
||||
if (node != m_pattern->getTimeMap().end())
|
||||
if (node != m_clip->getTimeMap().end())
|
||||
{
|
||||
node.value().resetOutValue();
|
||||
Engine::getSong()->setModified();
|
||||
@@ -481,8 +481,8 @@ void AutomationEditor::mousePressEvent( QMouseEvent* mouseEvent )
|
||||
// Get tick in which the user clicked
|
||||
int posTicks = (x * TimePos::ticksPerBar() / m_ppb) + m_currentPosition;
|
||||
|
||||
// Get the time map of current pattern
|
||||
timeMap & tm = m_pattern->getTimeMap();
|
||||
// Get the time map of current clip
|
||||
timeMap & tm = m_clip->getTimeMap();
|
||||
|
||||
m_mouseDownLeft = (mouseEvent->button() == Qt::LeftButton);
|
||||
m_mouseDownRight = (mouseEvent->button() == Qt::RightButton);
|
||||
@@ -501,7 +501,7 @@ void AutomationEditor::mousePressEvent( QMouseEvent* mouseEvent )
|
||||
{
|
||||
case DRAW:
|
||||
{
|
||||
m_pattern->addJournalCheckPoint();
|
||||
m_clip->addJournalCheckPoint();
|
||||
|
||||
if (m_mouseDownLeft)
|
||||
{
|
||||
@@ -522,7 +522,7 @@ void AutomationEditor::mousePressEvent( QMouseEvent* mouseEvent )
|
||||
else // No shift, we are just creating/moving nodes
|
||||
{
|
||||
// Starts actually moving/draging the node
|
||||
TimePos newTime = m_pattern->setDragValue(
|
||||
TimePos newTime = m_clip->setDragValue(
|
||||
// The TimePos of either the clicked node or a new one
|
||||
TimePos(
|
||||
clickedNode == tm.end()
|
||||
@@ -573,7 +573,7 @@ void AutomationEditor::mousePressEvent( QMouseEvent* mouseEvent )
|
||||
}
|
||||
case ERASE:
|
||||
{
|
||||
m_pattern->addJournalCheckPoint();
|
||||
m_clip->addJournalCheckPoint();
|
||||
|
||||
// On erase mode, left click removes nodes
|
||||
if (m_mouseDownLeft)
|
||||
@@ -602,7 +602,7 @@ void AutomationEditor::mousePressEvent( QMouseEvent* mouseEvent )
|
||||
}
|
||||
case DRAW_OUTVALUES:
|
||||
{
|
||||
m_pattern->addJournalCheckPoint();
|
||||
m_clip->addJournalCheckPoint();
|
||||
|
||||
// On this mode, left click sets the outValue
|
||||
if (m_mouseDownLeft)
|
||||
@@ -624,7 +624,7 @@ void AutomationEditor::mousePressEvent( QMouseEvent* mouseEvent )
|
||||
// node and set its outValue
|
||||
TimePos quantizedPos = Note::quantized(
|
||||
TimePos(posTicks),
|
||||
m_pattern->quantization()
|
||||
m_clip->quantization()
|
||||
);
|
||||
|
||||
clickedNode = tm.find(quantizedPos);
|
||||
@@ -664,7 +664,7 @@ void AutomationEditor::mousePressEvent( QMouseEvent* mouseEvent )
|
||||
|
||||
void AutomationEditor::mouseDoubleClickEvent(QMouseEvent * mouseEvent)
|
||||
{
|
||||
if (!validPattern()) { return; }
|
||||
if (!validClip()) { return; }
|
||||
|
||||
// If we double clicked outside the AutomationEditor viewport return
|
||||
if (mouseEvent->y() <= TOP_MARGIN || mouseEvent->x() < VALUES_WIDTH) { return; }
|
||||
@@ -707,7 +707,7 @@ void AutomationEditor::mouseReleaseEvent(QMouseEvent * mouseEvent )
|
||||
if (m_action == MOVE_VALUE)
|
||||
{
|
||||
// Actually apply the value of the node being dragged
|
||||
m_pattern->applyDragValue();
|
||||
m_clip->applyDragValue();
|
||||
}
|
||||
|
||||
QApplication::restoreOverrideCursor();
|
||||
@@ -723,7 +723,7 @@ void AutomationEditor::mouseReleaseEvent(QMouseEvent * mouseEvent )
|
||||
|
||||
void AutomationEditor::mouseMoveEvent(QMouseEvent * mouseEvent )
|
||||
{
|
||||
if( !validPattern() )
|
||||
if( !validClip() )
|
||||
{
|
||||
update();
|
||||
return;
|
||||
@@ -760,7 +760,7 @@ void AutomationEditor::mouseMoveEvent(QMouseEvent * mouseEvent )
|
||||
m_drawLastLevel = level;
|
||||
|
||||
// Updates the drag value of the moved node
|
||||
m_pattern->setDragValue(
|
||||
m_clip->setDragValue(
|
||||
TimePos(posTicks),
|
||||
level,
|
||||
true,
|
||||
@@ -786,7 +786,7 @@ void AutomationEditor::mouseMoveEvent(QMouseEvent * mouseEvent )
|
||||
// Removing automation nodes
|
||||
|
||||
// Removes all values from the last clicked tick up to the current position tick
|
||||
m_pattern->removeNodes(m_drawLastTick, posTicks);
|
||||
m_clip->removeNodes(m_drawLastTick, posTicks);
|
||||
|
||||
Engine::getSong()->setModified();
|
||||
}
|
||||
@@ -806,7 +806,7 @@ void AutomationEditor::mouseMoveEvent(QMouseEvent * mouseEvent )
|
||||
// Removing automation nodes
|
||||
|
||||
// Removes all values from the last clicked tick up to the current position tick
|
||||
m_pattern->removeNodes(m_drawLastTick, posTicks);
|
||||
m_clip->removeNodes(m_drawLastTick, posTicks);
|
||||
|
||||
Engine::getSong()->setModified();
|
||||
}
|
||||
@@ -818,7 +818,7 @@ void AutomationEditor::mouseMoveEvent(QMouseEvent * mouseEvent )
|
||||
// Reseting outValues
|
||||
|
||||
// Resets all values from the last clicked tick up to the current position tick
|
||||
m_pattern->resetNodes(m_drawLastTick, posTicks);
|
||||
m_clip->resetNodes(m_drawLastTick, posTicks);
|
||||
|
||||
Engine::getSong()->setModified();
|
||||
}
|
||||
@@ -836,7 +836,7 @@ void AutomationEditor::mouseMoveEvent(QMouseEvent * mouseEvent )
|
||||
if (m_action == MOVE_OUTVALUE)
|
||||
{
|
||||
// We are moving the outValue of the node
|
||||
timeMap & tm = m_pattern->getTimeMap();
|
||||
timeMap & tm = m_clip->getTimeMap();
|
||||
|
||||
timeMap::iterator it = tm.find(m_draggedOutValueKey);
|
||||
// Safety check
|
||||
@@ -854,7 +854,7 @@ void AutomationEditor::mouseMoveEvent(QMouseEvent * mouseEvent )
|
||||
// Reseting outValues
|
||||
|
||||
// Resets all values from the last clicked tick up to the current position tick
|
||||
m_pattern->resetNodes(m_drawLastTick, posTicks);
|
||||
m_clip->resetNodes(m_drawLastTick, posTicks);
|
||||
|
||||
Engine::getSong()->setModified();
|
||||
}
|
||||
@@ -894,7 +894,7 @@ inline void AutomationEditor::drawCross( QPainter & p )
|
||||
tt_pos.ry() -= 51;
|
||||
tt_pos.rx() += 26;
|
||||
|
||||
float scaledLevel = m_pattern->firstObject()->scaledValue( level );
|
||||
float scaledLevel = m_clip->firstObject()->scaledValue( level );
|
||||
|
||||
// Limit the scaled-level tooltip to the grid
|
||||
if( mouse_pos.x() >= 0 &&
|
||||
@@ -913,12 +913,12 @@ inline void AutomationEditor::drawAutomationPoint(QPainter & p, timeMap::iterato
|
||||
{
|
||||
int x = xCoordOfTick(POS(it));
|
||||
int y;
|
||||
// Below (m_ppb * AutomationPattern::quantization() / 576) is used because:
|
||||
// Below (m_ppb * AutomationClip::quantization() / 576) is used because:
|
||||
// 1 bar equals to 192/quantization() notes. Hence, to calculate the number of pixels
|
||||
// per note we would have (m_ppb * 1 bar / (192/quantization()) notes per bar), or
|
||||
// (m_ppb * quantization / 192). If we want 1/3 of the number of pixels per note we
|
||||
// get (m_ppb * quantization() / 192*3) or (m_ppb * quantization() / 576)
|
||||
const int outerRadius = qBound(3, (m_ppb * AutomationPattern::quantization()) / 576, 5);
|
||||
const int outerRadius = qBound(3, (m_ppb * AutomationClip::quantization()) / 576, 5);
|
||||
|
||||
// Draw a circle for the outValue
|
||||
y = yCoordOfLevel(OUTVAL(it));
|
||||
@@ -964,7 +964,7 @@ void AutomationEditor::paintEvent(QPaintEvent * pe )
|
||||
Qt::Alignment text_flags =
|
||||
(Qt::Alignment)( Qt::AlignRight | Qt::AlignVCenter );
|
||||
|
||||
if( validPattern() )
|
||||
if( validClip() )
|
||||
{
|
||||
if( m_y_auto )
|
||||
{
|
||||
@@ -972,7 +972,7 @@ void AutomationEditor::paintEvent(QPaintEvent * pe )
|
||||
float level[] = { m_minLevel, m_maxLevel };
|
||||
for( int i = 0; i < 2; ++i )
|
||||
{
|
||||
const QString & label = m_pattern->firstObject()
|
||||
const QString & label = m_clip->firstObject()
|
||||
->displayValue( level[i] );
|
||||
p.setPen( QApplication::palette().color( QPalette::Active,
|
||||
QPalette::Shadow ) );
|
||||
@@ -1000,7 +1000,7 @@ void AutomationEditor::paintEvent(QPaintEvent * pe )
|
||||
}
|
||||
for( ; level <= m_topLevel; level += printable )
|
||||
{
|
||||
const QString & label = m_pattern->firstObject()
|
||||
const QString & label = m_clip->firstObject()
|
||||
->displayValue( level );
|
||||
y = yCoordOfLevel( level );
|
||||
p.setPen( QApplication::palette().color( QPalette::Active,
|
||||
@@ -1023,7 +1023,7 @@ void AutomationEditor::paintEvent(QPaintEvent * pe )
|
||||
|
||||
// draw vertical raster
|
||||
|
||||
if( m_pattern )
|
||||
if( m_clip )
|
||||
{
|
||||
int tick, x, q;
|
||||
int x_line_end = (int)( m_y_auto || m_topLevel < m_maxLevel ?
|
||||
@@ -1033,17 +1033,17 @@ void AutomationEditor::paintEvent(QPaintEvent * pe )
|
||||
if( m_zoomingXModel.value() > 3 )
|
||||
{
|
||||
// If we're over 100% zoom, we allow all quantization level grids
|
||||
q = AutomationPattern::quantization();
|
||||
q = AutomationClip::quantization();
|
||||
}
|
||||
else if( AutomationPattern::quantization() % 3 != 0 )
|
||||
else if( AutomationClip::quantization() % 3 != 0 )
|
||||
{
|
||||
// If we're under 100% zoom, we allow quantization grid up to 1/24 for triplets
|
||||
// to ensure a dense doesn't fill out the background
|
||||
q = AutomationPattern::quantization() < 8 ? 8 : AutomationPattern::quantization();
|
||||
q = AutomationClip::quantization() < 8 ? 8 : AutomationClip::quantization();
|
||||
}
|
||||
else {
|
||||
// If we're under 100% zoom, we allow quantization grid up to 1/32 for normal notes
|
||||
q = AutomationPattern::quantization() < 6 ? 6 : AutomationPattern::quantization();
|
||||
q = AutomationClip::quantization() < 6 ? 6 : AutomationClip::quantization();
|
||||
}
|
||||
|
||||
// 3 independent loops, because quantization might not divide evenly into
|
||||
@@ -1136,11 +1136,11 @@ void AutomationEditor::paintEvent(QPaintEvent * pe )
|
||||
|
||||
// following code draws all visible values
|
||||
|
||||
if( validPattern() )
|
||||
if( validClip() )
|
||||
{
|
||||
//NEEDS Change in CSS
|
||||
//int len_ticks = 4;
|
||||
timeMap & time_map = m_pattern->getTimeMap();
|
||||
timeMap & time_map = m_clip->getTimeMap();
|
||||
|
||||
//Don't bother doing/rendering anything if there is no automation points
|
||||
if( time_map.size() > 0 )
|
||||
@@ -1163,7 +1163,7 @@ void AutomationEditor::paintEvent(QPaintEvent * pe )
|
||||
break;
|
||||
}
|
||||
|
||||
float *values = m_pattern->valuesAfter(POS(it));
|
||||
float *values = m_clip->valuesAfter(POS(it));
|
||||
|
||||
// We are creating a path to draw a polygon representing the values between two
|
||||
// nodes. When we have two nodes with discrete progression, we will basically have
|
||||
@@ -1172,7 +1172,7 @@ void AutomationEditor::paintEvent(QPaintEvent * pe )
|
||||
// the value of the end of the shape between the two nodes will be the inValue of
|
||||
// the next node.
|
||||
float nextValue;
|
||||
if( m_pattern->progressionType() == AutomationPattern::DiscreteProgression )
|
||||
if( m_clip->progressionType() == AutomationClip::DiscreteProgression )
|
||||
{
|
||||
nextValue = OUTVAL(it);
|
||||
}
|
||||
@@ -1225,12 +1225,12 @@ void AutomationEditor::paintEvent(QPaintEvent * pe )
|
||||
p.drawText( VALUES_WIDTH + 20, TOP_MARGIN + 40,
|
||||
width() - VALUES_WIDTH - 20 - SCROLLBAR_SIZE,
|
||||
grid_height - 40, Qt::TextWordWrap,
|
||||
tr( "Please open an automation pattern with "
|
||||
tr( "Please open an automation clip with "
|
||||
"the context menu of a control!" ) );
|
||||
}
|
||||
|
||||
// TODO: Get this out of paint event
|
||||
int l = validPattern() ? (int) m_pattern->length() : 0;
|
||||
int l = validClip() ? (int) m_clip->length() : 0;
|
||||
|
||||
// reset scroll-range
|
||||
if( m_leftRightScroll->maximum() != l )
|
||||
@@ -1239,7 +1239,7 @@ void AutomationEditor::paintEvent(QPaintEvent * pe )
|
||||
m_leftRightScroll->setPageStep( l );
|
||||
}
|
||||
|
||||
if(validPattern() && GuiApplication::instance()->automationEditor()->m_editor->hasFocus())
|
||||
if(validClip() && GuiApplication::instance()->automationEditor()->m_editor->hasFocus())
|
||||
{
|
||||
drawCross( p );
|
||||
}
|
||||
@@ -1351,17 +1351,17 @@ void AutomationEditor::centerTopBottomScroll()
|
||||
{
|
||||
// default to the m_scrollLevel position
|
||||
int pos = static_cast<int>(m_scrollLevel);
|
||||
// If a pattern exists...
|
||||
if (m_pattern)
|
||||
// If a clip exists...
|
||||
if (m_clip)
|
||||
{
|
||||
// get time map of current pattern
|
||||
timeMap & time_map = m_pattern->getTimeMap();
|
||||
// get time map of current clip
|
||||
timeMap & time_map = m_clip->getTimeMap();
|
||||
// If time_map is not empty...
|
||||
if (!time_map.empty())
|
||||
{
|
||||
// set the position to the inverted value ((max + min) - value)
|
||||
// If we set just (max - value), we're off by m_pattern's minimum
|
||||
pos = m_pattern->getMax() + m_pattern->getMin() - static_cast<int>(INVAL(time_map.begin()));
|
||||
// If we set just (max - value), we're off by m_clip's minimum
|
||||
pos = m_clip->getMax() + m_clip->getMin() - static_cast<int>(INVAL(time_map.begin()));
|
||||
}
|
||||
}
|
||||
m_topBottomScroll->setValue(pos);
|
||||
@@ -1400,7 +1400,7 @@ void AutomationEditor::resizeEvent(QResizeEvent * re)
|
||||
|
||||
if( Engine::getSong() )
|
||||
{
|
||||
Engine::getSong()->getPlayPos( Song::Mode_PlayAutomationPattern
|
||||
Engine::getSong()->getPlayPos( Song::Mode_PlayAutomationClip
|
||||
).m_timeLine->setFixedWidth( width() );
|
||||
}
|
||||
|
||||
@@ -1510,8 +1510,8 @@ float AutomationEditor::getLevel(int y )
|
||||
|
||||
inline bool AutomationEditor::inBBEditor()
|
||||
{
|
||||
return( validPattern() &&
|
||||
m_pattern->getTrack()->trackContainer() == Engine::getBBTrackContainer() );
|
||||
return( validClip() &&
|
||||
m_clip->getTrack()->trackContainer() == Engine::getBBTrackContainer() );
|
||||
}
|
||||
|
||||
|
||||
@@ -1519,17 +1519,17 @@ inline bool AutomationEditor::inBBEditor()
|
||||
|
||||
void AutomationEditor::play()
|
||||
{
|
||||
if( !validPattern() )
|
||||
if( !validClip() )
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if( !m_pattern->getTrack() )
|
||||
if( !m_clip->getTrack() )
|
||||
{
|
||||
if( Engine::getSong()->playMode() != Song::Mode_PlayPattern )
|
||||
if( Engine::getSong()->playMode() != Song::Mode_PlayMidiClip )
|
||||
{
|
||||
Engine::getSong()->stop();
|
||||
Engine::getSong()->playPattern( getGUI()->pianoRoll()->currentPattern() );
|
||||
Engine::getSong()->playMidiClip( getGUI()->pianoRoll()->currentMidiClip() );
|
||||
}
|
||||
else if( Engine::getSong()->isStopped() == false )
|
||||
{
|
||||
@@ -1537,7 +1537,7 @@ void AutomationEditor::play()
|
||||
}
|
||||
else
|
||||
{
|
||||
Engine::getSong()->playPattern( getGUI()->pianoRoll()->currentPattern() );
|
||||
Engine::getSong()->playMidiClip( getGUI()->pianoRoll()->currentMidiClip() );
|
||||
}
|
||||
}
|
||||
else if( inBBEditor() )
|
||||
@@ -1562,11 +1562,11 @@ void AutomationEditor::play()
|
||||
|
||||
void AutomationEditor::stop()
|
||||
{
|
||||
if( !validPattern() )
|
||||
if( !validClip() )
|
||||
{
|
||||
return;
|
||||
}
|
||||
if( m_pattern->getTrack() && inBBEditor() )
|
||||
if( m_clip->getTrack() && inBBEditor() )
|
||||
{
|
||||
Engine::getBBTrackContainer()->stop();
|
||||
}
|
||||
@@ -1621,12 +1621,12 @@ void AutomationEditor::setEditMode(int mode)
|
||||
|
||||
|
||||
|
||||
void AutomationEditor::setProgressionType(AutomationPattern::ProgressionTypes type)
|
||||
void AutomationEditor::setProgressionType(AutomationClip::ProgressionTypes type)
|
||||
{
|
||||
if (validPattern())
|
||||
if (validClip())
|
||||
{
|
||||
m_pattern->addJournalCheckPoint();
|
||||
m_pattern->setProgressionType(type);
|
||||
m_clip->addJournalCheckPoint();
|
||||
m_clip->setProgressionType(type);
|
||||
Engine::getSong()->setModified();
|
||||
update();
|
||||
}
|
||||
@@ -1634,7 +1634,7 @@ void AutomationEditor::setProgressionType(AutomationPattern::ProgressionTypes ty
|
||||
|
||||
void AutomationEditor::setProgressionType(int type)
|
||||
{
|
||||
setProgressionType((AutomationPattern::ProgressionTypes) type);
|
||||
setProgressionType((AutomationClip::ProgressionTypes) type);
|
||||
}
|
||||
|
||||
|
||||
@@ -1642,9 +1642,9 @@ void AutomationEditor::setProgressionType(int type)
|
||||
|
||||
void AutomationEditor::setTension()
|
||||
{
|
||||
if ( m_pattern )
|
||||
if ( m_clip )
|
||||
{
|
||||
m_pattern->setTension( QString::number( m_tensionModel->value() ) );
|
||||
m_clip->setTension( QString::number( m_tensionModel->value() ) );
|
||||
update();
|
||||
}
|
||||
}
|
||||
@@ -1656,7 +1656,7 @@ void AutomationEditor::updatePosition(const TimePos & t )
|
||||
{
|
||||
if( ( Engine::getSong()->isPlaying() &&
|
||||
Engine::getSong()->playMode() ==
|
||||
Song::Mode_PlayAutomationPattern ) ||
|
||||
Song::Mode_PlayAutomationClip ) ||
|
||||
m_scrollBack == true )
|
||||
{
|
||||
const int w = width() - VALUES_WIDTH;
|
||||
@@ -1712,7 +1712,7 @@ void AutomationEditor::zoomingYChanged()
|
||||
|
||||
void AutomationEditor::setQuantization()
|
||||
{
|
||||
AutomationPattern::setQuantization(DefaultTicksPerBar / Quantizations[m_quantizeModel.value()]);
|
||||
AutomationClip::setQuantization(DefaultTicksPerBar / Quantizations[m_quantizeModel.value()]);
|
||||
|
||||
update();
|
||||
}
|
||||
@@ -1786,8 +1786,8 @@ AutomationEditor::timeMap::iterator AutomationEditor::getNodeAt(int x, int y, bo
|
||||
// Convert the x position to the position in ticks
|
||||
int posTicks = (x * TimePos::ticksPerBar() / m_ppb) + m_currentPosition;
|
||||
|
||||
// Get our pattern timeMap and create a iterator so we can check the nodes
|
||||
timeMap & tm = m_pattern->getTimeMap();
|
||||
// Get our clip timeMap and create a iterator so we can check the nodes
|
||||
timeMap & tm = m_clip->getTimeMap();
|
||||
timeMap::iterator it = tm.begin();
|
||||
|
||||
// ticksOffset is the number of ticks that match "r" pixels
|
||||
@@ -1832,9 +1832,9 @@ AutomationEditorWindow::AutomationEditorWindow() :
|
||||
|
||||
|
||||
// Play/stop buttons
|
||||
m_playAction->setToolTip(tr( "Play/pause current pattern (Space)" ));
|
||||
m_playAction->setToolTip(tr( "Play/pause current clip (Space)" ));
|
||||
|
||||
m_stopAction->setToolTip(tr("Stop playing of current pattern (Space)"));
|
||||
m_stopAction->setToolTip(tr("Stop playing of current clip (Space)"));
|
||||
|
||||
// Edit mode buttons
|
||||
DropToolBar *editActionsToolBar = addDropToolBarToTop(tr("Edit actions"));
|
||||
@@ -1972,62 +1972,62 @@ AutomationEditorWindow::~AutomationEditorWindow()
|
||||
}
|
||||
|
||||
|
||||
void AutomationEditorWindow::setCurrentPattern(AutomationPattern* pattern)
|
||||
void AutomationEditorWindow::setCurrentClip(AutomationClip* clip)
|
||||
{
|
||||
// Disconnect our old pattern
|
||||
if (currentPattern() != nullptr)
|
||||
// Disconnect our old clip
|
||||
if (currentClip() != nullptr)
|
||||
{
|
||||
m_editor->m_pattern->disconnect(this);
|
||||
m_editor->m_clip->disconnect(this);
|
||||
m_flipXAction->disconnect();
|
||||
m_flipYAction->disconnect();
|
||||
}
|
||||
|
||||
m_editor->setCurrentPattern(pattern);
|
||||
m_editor->setCurrentClip(clip);
|
||||
|
||||
// Set our window's title
|
||||
if (pattern == nullptr)
|
||||
if (clip == nullptr)
|
||||
{
|
||||
setWindowTitle( tr( "Automation Editor - no pattern" ) );
|
||||
setWindowTitle( tr( "Automation Editor - no clip" ) );
|
||||
return;
|
||||
}
|
||||
|
||||
setWindowTitle( tr( "Automation Editor - %1" ).arg( m_editor->m_pattern->name() ) );
|
||||
setWindowTitle( tr( "Automation Editor - %1" ).arg( m_editor->m_clip->name() ) );
|
||||
|
||||
|
||||
switch(m_editor->m_pattern->progressionType())
|
||||
switch(m_editor->m_clip->progressionType())
|
||||
{
|
||||
case AutomationPattern::DiscreteProgression:
|
||||
case AutomationClip::DiscreteProgression:
|
||||
m_discreteAction->setChecked(true);
|
||||
m_tensionKnob->setEnabled(false);
|
||||
break;
|
||||
case AutomationPattern::LinearProgression:
|
||||
case AutomationClip::LinearProgression:
|
||||
m_linearAction->setChecked(true);
|
||||
m_tensionKnob->setEnabled(false);
|
||||
break;
|
||||
case AutomationPattern::CubicHermiteProgression:
|
||||
case AutomationClip::CubicHermiteProgression:
|
||||
m_cubicHermiteAction->setChecked(true);
|
||||
m_tensionKnob->setEnabled(true);
|
||||
break;
|
||||
}
|
||||
|
||||
// Connect new pattern
|
||||
if (pattern)
|
||||
// Connect new clip
|
||||
if (clip)
|
||||
{
|
||||
connect(pattern, SIGNAL(dataChanged()), this, SLOT(update()));
|
||||
connect( pattern, SIGNAL( dataChanged() ), this, SLOT( updateWindowTitle() ) );
|
||||
connect(pattern, SIGNAL(destroyed()), this, SLOT(clearCurrentPattern()));
|
||||
connect(clip, SIGNAL(dataChanged()), this, SLOT(update()));
|
||||
connect( clip, SIGNAL( dataChanged() ), this, SLOT( updateWindowTitle() ) );
|
||||
connect(clip, SIGNAL(destroyed()), this, SLOT(clearCurrentClip()));
|
||||
|
||||
connect(m_flipXAction, SIGNAL(triggered()), pattern, SLOT(flipX()));
|
||||
connect(m_flipYAction, SIGNAL(triggered()), pattern, SLOT(flipY()));
|
||||
connect(m_flipXAction, SIGNAL(triggered()), clip, SLOT(flipX()));
|
||||
connect(m_flipYAction, SIGNAL(triggered()), clip, SLOT(flipY()));
|
||||
}
|
||||
|
||||
emit currentPatternChanged();
|
||||
emit currentClipChanged();
|
||||
}
|
||||
|
||||
|
||||
const AutomationPattern* AutomationEditorWindow::currentPattern()
|
||||
const AutomationClip* AutomationEditorWindow::currentClip()
|
||||
{
|
||||
return m_editor->currentPattern();
|
||||
return m_editor->currentClip();
|
||||
}
|
||||
|
||||
void AutomationEditorWindow::dropEvent( QDropEvent *_de )
|
||||
@@ -2041,16 +2041,16 @@ void AutomationEditorWindow::dropEvent( QDropEvent *_de )
|
||||
journallingObject( val.toInt() ) );
|
||||
if (mod != nullptr)
|
||||
{
|
||||
bool added = m_editor->m_pattern->addObject( mod );
|
||||
bool added = m_editor->m_clip->addObject( mod );
|
||||
if ( !added )
|
||||
{
|
||||
TextFloat::displayMessage( mod->displayName(),
|
||||
tr( "Model is already connected "
|
||||
"to this pattern." ),
|
||||
"to this clip." ),
|
||||
embed::getIconPixmap( "automation" ),
|
||||
2000 );
|
||||
}
|
||||
setCurrentPattern( m_editor->m_pattern );
|
||||
setCurrentClip( m_editor->m_clip );
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2059,15 +2059,15 @@ void AutomationEditorWindow::dropEvent( QDropEvent *_de )
|
||||
|
||||
void AutomationEditorWindow::dragEnterEvent( QDragEnterEvent *_dee )
|
||||
{
|
||||
if (! m_editor->validPattern() ) {
|
||||
if (! m_editor->validClip() ) {
|
||||
return;
|
||||
}
|
||||
StringPairDrag::processDragEnterEvent( _dee, "automatable_model" );
|
||||
}
|
||||
|
||||
void AutomationEditorWindow::open(AutomationPattern* pattern)
|
||||
void AutomationEditorWindow::open(AutomationClip* clip)
|
||||
{
|
||||
setCurrentPattern(pattern);
|
||||
setCurrentClip(clip);
|
||||
parentWidget()->show();
|
||||
show();
|
||||
setFocus();
|
||||
@@ -2078,10 +2078,10 @@ QSize AutomationEditorWindow::sizeHint() const
|
||||
return {INITIAL_WIDTH, INITIAL_HEIGHT};
|
||||
}
|
||||
|
||||
void AutomationEditorWindow::clearCurrentPattern()
|
||||
void AutomationEditorWindow::clearCurrentClip()
|
||||
{
|
||||
m_editor->m_pattern = nullptr;
|
||||
setCurrentPattern(nullptr);
|
||||
m_editor->m_clip = nullptr;
|
||||
setCurrentClip(nullptr);
|
||||
}
|
||||
|
||||
void AutomationEditorWindow::focusInEvent(QFocusEvent * event)
|
||||
@@ -2102,11 +2102,11 @@ void AutomationEditorWindow::stop()
|
||||
|
||||
void AutomationEditorWindow::updateWindowTitle()
|
||||
{
|
||||
if (m_editor->m_pattern == nullptr)
|
||||
if (m_editor->m_clip == nullptr)
|
||||
{
|
||||
setWindowTitle( tr( "Automation Editor - no pattern" ) );
|
||||
setWindowTitle( tr( "Automation Editor - no clip" ) );
|
||||
return;
|
||||
}
|
||||
|
||||
setWindowTitle( tr( "Automation Editor - %1" ).arg( m_editor->m_pattern->name() ) );
|
||||
setWindowTitle( tr( "Automation Editor - %1" ).arg( m_editor->m_clip->name() ) );
|
||||
}
|
||||
|
||||
@@ -37,7 +37,7 @@
|
||||
#include "Song.h"
|
||||
#include "StringPairDrag.h"
|
||||
|
||||
#include "Pattern.h"
|
||||
#include "MidiClip.h"
|
||||
|
||||
|
||||
|
||||
@@ -59,12 +59,12 @@ BBEditor::BBEditor( BBTrackContainer* tc ) :
|
||||
"compacttrackbuttons" ).toInt() )
|
||||
{
|
||||
setMinimumWidth( TRACK_OP_WIDTH_COMPACT + DEFAULT_SETTINGS_WIDGET_WIDTH_COMPACT
|
||||
+ 2 * TCO_BORDER_WIDTH + 384 );
|
||||
+ 2 * CLIP_BORDER_WIDTH + 384 );
|
||||
}
|
||||
else
|
||||
{
|
||||
setMinimumWidth( TRACK_OP_WIDTH + DEFAULT_SETTINGS_WIDGET_WIDTH
|
||||
+ 2 * TCO_BORDER_WIDTH + 384 );
|
||||
+ 2 * CLIP_BORDER_WIDTH + 384 );
|
||||
}
|
||||
|
||||
|
||||
@@ -88,8 +88,8 @@ BBEditor::BBEditor( BBTrackContainer* tc ) :
|
||||
|
||||
trackAndStepActionsToolBar->addAction(embed::getIconPixmap("add_bb_track"), tr("Add beat/bassline"),
|
||||
Engine::getSong(), SLOT(addBBTrack()));
|
||||
trackAndStepActionsToolBar->addAction(embed::getIconPixmap("clone_bb_track_pattern"), tr("Clone beat/bassline pattern"),
|
||||
m_trackContainerView, SLOT(clonePattern()));
|
||||
trackAndStepActionsToolBar->addAction(embed::getIconPixmap("clone_bb_track_clip"), tr("Clone beat/bassline clip"),
|
||||
m_trackContainerView, SLOT(cloneClip()));
|
||||
trackAndStepActionsToolBar->addAction(
|
||||
embed::getIconPixmap("add_sample_track"),
|
||||
tr("Add sample-track"), m_trackContainerView,
|
||||
@@ -196,7 +196,7 @@ void BBTrackContainerView::removeSteps()
|
||||
{
|
||||
if( ( *it )->type() == Track::InstrumentTrack )
|
||||
{
|
||||
Pattern* p = static_cast<Pattern *>( ( *it )->getTCO( m_bbtc->currentBB() ) );
|
||||
MidiClip* p = static_cast<MidiClip *>( ( *it )->getClip( m_bbtc->currentBB() ) );
|
||||
p->removeSteps();
|
||||
}
|
||||
}
|
||||
@@ -225,7 +225,7 @@ void BBTrackContainerView::removeBBView(int bb)
|
||||
{
|
||||
for( TrackView* view : trackViews() )
|
||||
{
|
||||
view->getTrackContentWidget()->removeTCOView( bb );
|
||||
view->getTrackContentWidget()->removeClipView( bb );
|
||||
}
|
||||
}
|
||||
|
||||
@@ -254,24 +254,24 @@ void BBTrackContainerView::dropEvent(QDropEvent* de)
|
||||
DataFile dataFile( value.toUtf8() );
|
||||
Track * t = Track::create( dataFile.content().firstChild().toElement(), model() );
|
||||
|
||||
// Ensure BB TCOs exist
|
||||
bool hasValidBBTCOs = false;
|
||||
if (t->getTCOs().size() == m_bbtc->numOfBBs())
|
||||
// Ensure BB Clips exist
|
||||
bool hasValidBBClips = false;
|
||||
if (t->getClips().size() == m_bbtc->numOfBBs())
|
||||
{
|
||||
hasValidBBTCOs = true;
|
||||
for (int i = 0; i < t->getTCOs().size(); ++i)
|
||||
hasValidBBClips = true;
|
||||
for (int i = 0; i < t->getClips().size(); ++i)
|
||||
{
|
||||
if (t->getTCOs()[i]->startPosition() != TimePos(i, 0))
|
||||
if (t->getClips()[i]->startPosition() != TimePos(i, 0))
|
||||
{
|
||||
hasValidBBTCOs = false;
|
||||
hasValidBBClips = false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (!hasValidBBTCOs)
|
||||
if (!hasValidBBClips)
|
||||
{
|
||||
t->deleteTCOs();
|
||||
t->createTCOsForBB(m_bbtc->numOfBBs() - 1);
|
||||
t->deleteClips();
|
||||
t->createClipsForBB(m_bbtc->numOfBBs() - 1);
|
||||
}
|
||||
m_bbtc->updateAfterTrackAdd();
|
||||
|
||||
@@ -304,7 +304,7 @@ void BBTrackContainerView::makeSteps( bool clone )
|
||||
{
|
||||
if( ( *it )->type() == Track::InstrumentTrack )
|
||||
{
|
||||
Pattern* p = static_cast<Pattern *>( ( *it )->getTCO( m_bbtc->currentBB() ) );
|
||||
MidiClip* p = static_cast<MidiClip *>( ( *it )->getClip( m_bbtc->currentBB() ) );
|
||||
if( clone )
|
||||
{
|
||||
p->cloneSteps();
|
||||
@@ -316,9 +316,9 @@ void BBTrackContainerView::makeSteps( bool clone )
|
||||
}
|
||||
}
|
||||
|
||||
// Creates a clone of the current BB track with the same pattern, but no TCOs in the song editor
|
||||
// Creates a clone of the current BB track with the same clip, but no Clips in the song editor
|
||||
// TODO: Avoid repeated code from cloneTrack and clearTrack in TrackOperationsWidget somehow
|
||||
void BBTrackContainerView::clonePattern()
|
||||
void BBTrackContainerView::cloneClip()
|
||||
{
|
||||
// Get the current BBTrack id
|
||||
BBTrackContainer *bbtc = static_cast<BBTrackContainer*>(model());
|
||||
@@ -332,9 +332,9 @@ void BBTrackContainerView::clonePattern()
|
||||
Track *newTrack = bbt->clone();
|
||||
bbtc->setCurrentBB( static_cast<BBTrack *>( newTrack )->index() );
|
||||
|
||||
// Track still have the TCOs which is undesirable in this case, clear the track
|
||||
// Track still have the clips which is undesirable in this case, clear the track
|
||||
newTrack->lock();
|
||||
newTrack->deleteTCOs();
|
||||
newTrack->deleteClips();
|
||||
newTrack->unlock();
|
||||
}
|
||||
}
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -352,7 +352,7 @@ void SongEditor::selectRegionFromPixels(int xStart, int xEnd)
|
||||
{
|
||||
m_selectRegion = true;
|
||||
|
||||
//deselect all tcos
|
||||
//deselect all clips
|
||||
for (auto &it : findChildren<selectableObject *>()) { it->setSelected(false); }
|
||||
|
||||
rubberBand()->setEnabled(true);
|
||||
@@ -419,17 +419,17 @@ void SongEditor::updateRubberband()
|
||||
/ pixelsPerBar() * TimePos::ticksPerBar())
|
||||
+ m_currentPosition;
|
||||
|
||||
//are tcos in the rect of selection?
|
||||
//are clips in the rect of selection?
|
||||
for (auto &it : findChildren<selectableObject *>())
|
||||
{
|
||||
TrackContentObjectView * tco = dynamic_cast<TrackContentObjectView*>(it);
|
||||
if (tco)
|
||||
ClipView * clip = dynamic_cast<ClipView*>(it);
|
||||
if (clip)
|
||||
{
|
||||
auto indexOfTrackView = trackViews().indexOf(tco->getTrackView());
|
||||
auto indexOfTrackView = trackViews().indexOf(clip->getTrackView());
|
||||
bool isBeetweenRubberbandViews = indexOfTrackView >= qMin(m_rubberBandStartTrackview, rubberBandTrackview)
|
||||
&& indexOfTrackView <= qMax(m_rubberBandStartTrackview, rubberBandTrackview);
|
||||
bool isBeetweenRubberbandTimePos = tco->getTrackContentObject()->endPosition() >= qMin(m_rubberbandStartTimePos, rubberbandTimePos)
|
||||
&& tco->getTrackContentObject()->startPosition() <= qMax(m_rubberbandStartTimePos, rubberbandTimePos);
|
||||
bool isBeetweenRubberbandTimePos = clip->getClip()->endPosition() >= qMin(m_rubberbandStartTimePos, rubberbandTimePos)
|
||||
&& clip->getClip()->startPosition() <= qMax(m_rubberbandStartTimePos, rubberbandTimePos);
|
||||
it->setSelected(isBeetweenRubberbandViews && isBeetweenRubberbandTimePos);
|
||||
}
|
||||
}
|
||||
@@ -506,18 +506,18 @@ void SongEditor::keyPressEvent( QKeyEvent * ke )
|
||||
for( QVector<selectableObject *>::iterator it = so.begin();
|
||||
it != so.end(); ++it )
|
||||
{
|
||||
TrackContentObjectView * tcov =
|
||||
dynamic_cast<TrackContentObjectView *>( *it );
|
||||
tcov->remove();
|
||||
ClipView * clipv =
|
||||
dynamic_cast<ClipView *>( *it );
|
||||
clipv->remove();
|
||||
}
|
||||
}
|
||||
else if( ke->key() == Qt::Key_A && ke->modifiers() & Qt::ControlModifier )
|
||||
{
|
||||
selectAllTcos( !isShiftPressed );
|
||||
selectAllClips( !isShiftPressed );
|
||||
}
|
||||
else if( ke->key() == Qt::Key_Escape )
|
||||
{
|
||||
selectAllTcos( false );
|
||||
selectAllClips( false );
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -559,7 +559,7 @@ void SongEditor::wheelEvent( QWheelEvent * we )
|
||||
// update timeline
|
||||
m_song->m_playPos[Song::Mode_PlaySong].m_timeLine->
|
||||
setPixelsPerBar( pixelsPerBar() );
|
||||
// and make sure, all TCO's are resized and relocated
|
||||
// and make sure, all Clip's are resized and relocated
|
||||
realignTracks();
|
||||
}
|
||||
|
||||
@@ -845,7 +845,7 @@ void SongEditor::zoomingChanged()
|
||||
}
|
||||
|
||||
|
||||
void SongEditor::selectAllTcos( bool select )
|
||||
void SongEditor::selectAllClips( bool select )
|
||||
{
|
||||
QVector<selectableObject *> so = select ? rubberBand()->selectableObjects() : rubberBand()->selectedObjects();
|
||||
for( int i = 0; i < so.count(); ++i )
|
||||
|
||||
@@ -305,7 +305,7 @@ void EnvelopeAndLfoView::mousePressEvent( QMouseEvent * _me )
|
||||
void EnvelopeAndLfoView::dragEnterEvent( QDragEnterEvent * _dee )
|
||||
{
|
||||
StringPairDrag::processDragEnterEvent( _dee,
|
||||
QString( "samplefile,tco_%1" ).arg(
|
||||
QString( "samplefile,clip_%1" ).arg(
|
||||
Track::SampleTrack ) );
|
||||
}
|
||||
|
||||
@@ -325,7 +325,7 @@ void EnvelopeAndLfoView::dropEvent( QDropEvent * _de )
|
||||
_de->accept();
|
||||
update();
|
||||
}
|
||||
else if( type == QString( "tco_%1" ).arg( Track::SampleTrack ) )
|
||||
else if( type == QString( "clip_%1" ).arg( Track::SampleTrack ) )
|
||||
{
|
||||
DataFile dataFile( value.toUtf8() );
|
||||
m_params->m_userWave.setAudioFile( dataFile.content().
|
||||
|
||||
@@ -64,8 +64,7 @@ InstrumentMidiIOView::InstrumentMidiIOView( QWidget* parent ) :
|
||||
midiInputLayout->addWidget( m_inputChannelSpinBox );
|
||||
|
||||
m_fixedInputVelocitySpinBox = new LcdSpinBox( 3, m_midiInputGroupBox );
|
||||
m_fixedInputVelocitySpinBox->setDisplayOffset( 1 );
|
||||
m_fixedInputVelocitySpinBox->addTextForValue( 0, "---" );
|
||||
m_fixedInputVelocitySpinBox->addTextForValue( -1, "---" );
|
||||
/*: This string must be be short, its width must be less than
|
||||
* width of LCD spin-box of three digits */
|
||||
m_fixedInputVelocitySpinBox->setLabel( tr( "VELOC" ) );
|
||||
@@ -95,8 +94,7 @@ InstrumentMidiIOView::InstrumentMidiIOView( QWidget* parent ) :
|
||||
midiOutputLayout->addWidget( m_outputChannelSpinBox );
|
||||
|
||||
m_fixedOutputVelocitySpinBox = new LcdSpinBox( 3, m_midiOutputGroupBox );
|
||||
m_fixedOutputVelocitySpinBox->setDisplayOffset( 1 );
|
||||
m_fixedOutputVelocitySpinBox->addTextForValue( 0, "---" );
|
||||
m_fixedOutputVelocitySpinBox->addTextForValue( -1, "---" );
|
||||
/*: This string must be be short, its width must be less than
|
||||
* width of LCD spin-box of three digits */
|
||||
m_fixedOutputVelocitySpinBox->setLabel( tr( "VELOC" ) );
|
||||
@@ -111,8 +109,7 @@ InstrumentMidiIOView::InstrumentMidiIOView( QWidget* parent ) :
|
||||
midiOutputLayout->addWidget( m_outputProgramSpinBox );
|
||||
|
||||
m_fixedOutputNoteSpinBox = new LcdSpinBox( 3, m_midiOutputGroupBox );
|
||||
m_fixedOutputNoteSpinBox->setDisplayOffset( 1 );
|
||||
m_fixedOutputNoteSpinBox->addTextForValue( 0, "---" );
|
||||
m_fixedOutputNoteSpinBox->addTextForValue( -1, "---" );
|
||||
/*: This string must be be short, its width must be less than
|
||||
* width of LCD spin-box of three digits */
|
||||
m_fixedOutputNoteSpinBox->setLabel( tr( "NOTE" ) );
|
||||
|
||||
@@ -120,7 +120,7 @@ void LcdSpinBox::mouseMoveEvent( QMouseEvent* event )
|
||||
model()->value() + m_remainder - fdy / 2.f * model()->step<int>();
|
||||
float floatValRounded = roundf( floatValNotRounded );
|
||||
m_remainder = floatValNotRounded - floatValRounded;
|
||||
model()->setInitValue( floatValRounded );
|
||||
model()->setValue( floatValRounded );
|
||||
emit manualChange();
|
||||
m_lastMousePos = event->globalPos();
|
||||
}
|
||||
@@ -145,7 +145,7 @@ void LcdSpinBox::mouseReleaseEvent(QMouseEvent*)
|
||||
void LcdSpinBox::wheelEvent(QWheelEvent * we)
|
||||
{
|
||||
we->accept();
|
||||
model()->setInitValue(model()->value() + ((we->angleDelta().y() > 0) ? 1 : -1) * model()->step<int>());
|
||||
model()->setValue(model()->value() + ((we->angleDelta().y() > 0) ? 1 : -1) * model()->step<int>());
|
||||
emit manualChange();
|
||||
}
|
||||
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* FxLine.cpp - FX line widget
|
||||
* MixerLine.cpp - Mixer line widget
|
||||
*
|
||||
* Copyright (c) 2009 Andrew Kelley <superjoe30/at/gmail/dot/com>
|
||||
* Copyright (c) 2014 Tobias Doerffel <tobydox/at/users.sourceforge.net>
|
||||
@@ -23,19 +23,19 @@
|
||||
*
|
||||
*/
|
||||
|
||||
#include "FxLine.h"
|
||||
#include "MixerLine.h"
|
||||
|
||||
#include <cstdlib>
|
||||
|
||||
#include <QGraphicsProxyWidget>
|
||||
|
||||
#include "CaptionMenu.h"
|
||||
#include "FxMixer.h"
|
||||
#include "Mixer.h"
|
||||
#include "gui_templates.h"
|
||||
#include "GuiApplication.h"
|
||||
#include "Song.h"
|
||||
|
||||
bool FxLine::eventFilter( QObject *dist, QEvent *event )
|
||||
bool MixerLine::eventFilter( QObject *dist, QEvent *event )
|
||||
{
|
||||
// If we are in a rename, capture the enter/return events and handle them
|
||||
if ( event->type() == QEvent::KeyPress )
|
||||
@@ -54,11 +54,11 @@ bool FxLine::eventFilter( QObject *dist, QEvent *event )
|
||||
return false;
|
||||
}
|
||||
|
||||
const int FxLine::FxLineHeight = 287;
|
||||
QPixmap * FxLine::s_sendBgArrow = nullptr;
|
||||
QPixmap * FxLine::s_receiveBgArrow = nullptr;
|
||||
const int MixerLine::MixerLineHeight = 287;
|
||||
QPixmap * MixerLine::s_sendBgArrow = nullptr;
|
||||
QPixmap * MixerLine::s_receiveBgArrow = nullptr;
|
||||
|
||||
FxLine::FxLine( QWidget * _parent, FxMixerView * _mv, int _channelIndex ) :
|
||||
MixerLine::MixerLine( QWidget * _parent, MixerView * _mv, int _channelIndex ) :
|
||||
QWidget( _parent ),
|
||||
m_mv( _mv ),
|
||||
m_channelIndex( _channelIndex ),
|
||||
@@ -78,7 +78,7 @@ FxLine::FxLine( QWidget * _parent, FxMixerView * _mv, int _channelIndex ) :
|
||||
s_receiveBgArrow = new QPixmap( embed::getIconPixmap( "receive_bg_arrow", 29, 56 ) );
|
||||
}
|
||||
|
||||
setFixedSize( 33, FxLineHeight );
|
||||
setFixedSize( 33, MixerLineHeight );
|
||||
setAttribute( Qt::WA_OpaquePaintEvent, true );
|
||||
setCursor( QCursor( embed::getIconPixmap( "hand" ), 3, 3 ) );
|
||||
|
||||
@@ -97,7 +97,7 @@ FxLine::FxLine( QWidget * _parent, FxMixerView * _mv, int _channelIndex ) :
|
||||
m_lcd->move( 4, 58 );
|
||||
m_lcd->setMarginWidth( 1 );
|
||||
|
||||
QString name = Engine::fxMixer()->effectChannel( m_channelIndex )->m_name;
|
||||
QString name = Engine::mixer()->mixerChannel( m_channelIndex )->m_name;
|
||||
setToolTip( name );
|
||||
|
||||
m_renameLineEdit = new QLineEdit();
|
||||
@@ -108,7 +108,7 @@ FxLine::FxLine( QWidget * _parent, FxMixerView * _mv, int _channelIndex ) :
|
||||
m_renameLineEdit->installEventFilter( this );
|
||||
|
||||
QGraphicsScene * scene = new QGraphicsScene();
|
||||
scene->setSceneRect( 0, 0, 33, FxLineHeight );
|
||||
scene->setSceneRect( 0, 0, 33, MixerLineHeight );
|
||||
|
||||
m_view = new QGraphicsView( this );
|
||||
m_view->setStyleSheet( "border-style: none; background: transparent;" );
|
||||
@@ -122,14 +122,13 @@ FxLine::FxLine( QWidget * _parent, FxMixerView * _mv, int _channelIndex ) :
|
||||
proxyWidget->setPos( 8, 145 );
|
||||
|
||||
connect( m_renameLineEdit, SIGNAL( editingFinished() ), this, SLOT( renameFinished() ) );
|
||||
connect( &Engine::fxMixer()->effectChannel( m_channelIndex )->m_muteModel, SIGNAL( dataChanged() ), this, SLOT( update() ) );
|
||||
|
||||
connect( &Engine::mixer()->mixerChannel( m_channelIndex )->m_muteModel, SIGNAL( dataChanged() ), this, SLOT( update() ) );
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
FxLine::~FxLine()
|
||||
MixerLine::~MixerLine()
|
||||
{
|
||||
delete m_sendKnob;
|
||||
delete m_sendBtn;
|
||||
@@ -139,7 +138,7 @@ FxLine::~FxLine()
|
||||
|
||||
|
||||
|
||||
void FxLine::setChannelIndex( int index )
|
||||
void MixerLine::setChannelIndex( int index )
|
||||
{
|
||||
m_channelIndex = index;
|
||||
m_lcd->setValue( m_channelIndex );
|
||||
@@ -148,9 +147,9 @@ void FxLine::setChannelIndex( int index )
|
||||
|
||||
|
||||
|
||||
void FxLine::drawFxLine( QPainter* p, const FxLine *fxLine, bool isActive, bool sendToThis, bool receiveFromThis )
|
||||
void MixerLine::drawMixerLine( QPainter* p, const MixerLine *mixerLine, bool isActive, bool sendToThis, bool receiveFromThis )
|
||||
{
|
||||
auto channel = Engine::fxMixer()->effectChannel( m_channelIndex );
|
||||
auto channel = Engine::mixer()->mixerChannel( m_channelIndex );
|
||||
bool muted = channel->m_muteModel.value();
|
||||
QString name = channel->m_name;
|
||||
QString elidedName = elideName( name );
|
||||
@@ -159,25 +158,25 @@ void FxLine::drawFxLine( QPainter* p, const FxLine *fxLine, bool isActive, bool
|
||||
m_renameLineEdit->setText( elidedName );
|
||||
}
|
||||
|
||||
int width = fxLine->rect().width();
|
||||
int height = fxLine->rect().height();
|
||||
int width = mixerLine->rect().width();
|
||||
int height = mixerLine->rect().height();
|
||||
|
||||
if( channel->m_hasColor && !muted )
|
||||
{
|
||||
p->fillRect( fxLine->rect(), channel->m_color.darker( isActive ? 120 : 150 ) );
|
||||
p->fillRect( mixerLine->rect(), channel->m_color.darker( isActive ? 120 : 150 ) );
|
||||
}
|
||||
else
|
||||
{
|
||||
p->fillRect( fxLine->rect(),
|
||||
isActive ? fxLine->backgroundActive().color() : p->background().color() );
|
||||
p->fillRect( mixerLine->rect(),
|
||||
isActive ? mixerLine->backgroundActive().color() : p->background().color() );
|
||||
}
|
||||
|
||||
// inner border
|
||||
p->setPen( isActive ? fxLine->strokeInnerActive() : fxLine->strokeInnerInactive() );
|
||||
p->setPen( isActive ? mixerLine->strokeInnerActive() : mixerLine->strokeInnerInactive() );
|
||||
p->drawRect( 1, 1, width-3, height-3 );
|
||||
|
||||
// outer border
|
||||
p->setPen( isActive ? fxLine->strokeOuterActive() : fxLine->strokeOuterInactive() );
|
||||
p->setPen( isActive ? mixerLine->strokeOuterActive() : mixerLine->strokeOuterInactive() );
|
||||
p->drawRect( 0, 0, width-1, height-1 );
|
||||
|
||||
// draw the mixer send background
|
||||
@@ -194,7 +193,7 @@ void FxLine::drawFxLine( QPainter* p, const FxLine *fxLine, bool isActive, bool
|
||||
|
||||
|
||||
|
||||
QString FxLine::elideName( const QString & name )
|
||||
QString MixerLine::elideName( const QString & name )
|
||||
{
|
||||
const int maxTextHeight = 60;
|
||||
QFontMetrics metrics( m_renameLineEdit->font() );
|
||||
@@ -205,28 +204,28 @@ QString FxLine::elideName( const QString & name )
|
||||
|
||||
|
||||
|
||||
void FxLine::paintEvent( QPaintEvent * )
|
||||
void MixerLine::paintEvent( QPaintEvent * )
|
||||
{
|
||||
bool sendToThis = Engine::fxMixer()->channelSendModel( m_mv->currentFxLine()->m_channelIndex, m_channelIndex ) != nullptr;
|
||||
bool receiveFromThis = Engine::fxMixer()->channelSendModel( m_channelIndex, m_mv->currentFxLine()->m_channelIndex ) != nullptr;
|
||||
bool sendToThis = Engine::mixer()->channelSendModel( m_mv->currentMixerLine()->m_channelIndex, m_channelIndex ) != nullptr;
|
||||
bool receiveFromThis = Engine::mixer()->channelSendModel( m_channelIndex, m_mv->currentMixerLine()->m_channelIndex ) != nullptr;
|
||||
QPainter painter;
|
||||
painter.begin( this );
|
||||
drawFxLine( &painter, this, m_mv->currentFxLine() == this, sendToThis, receiveFromThis );
|
||||
drawMixerLine( &painter, this, m_mv->currentMixerLine() == this, sendToThis, receiveFromThis );
|
||||
painter.end();
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
void FxLine::mousePressEvent( QMouseEvent * )
|
||||
void MixerLine::mousePressEvent( QMouseEvent * )
|
||||
{
|
||||
m_mv->setCurrentFxLine( this );
|
||||
m_mv->setCurrentMixerLine( this );
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
void FxLine::mouseDoubleClickEvent( QMouseEvent * )
|
||||
void MixerLine::mouseDoubleClickEvent( QMouseEvent * )
|
||||
{
|
||||
renameChannel();
|
||||
}
|
||||
@@ -234,9 +233,9 @@ void FxLine::mouseDoubleClickEvent( QMouseEvent * )
|
||||
|
||||
|
||||
|
||||
void FxLine::contextMenuEvent( QContextMenuEvent * )
|
||||
void MixerLine::contextMenuEvent( QContextMenuEvent * )
|
||||
{
|
||||
QPointer<CaptionMenu> contextMenu = new CaptionMenu( Engine::fxMixer()->effectChannel( m_channelIndex )->m_name, this );
|
||||
QPointer<CaptionMenu> contextMenu = new CaptionMenu( Engine::mixer()->mixerChannel( m_channelIndex )->m_name, this );
|
||||
if( m_channelIndex != 0 ) // no move-options in master
|
||||
{
|
||||
contextMenu->addAction( tr( "Move &left" ), this, SLOT( moveChannelLeft() ) );
|
||||
@@ -267,14 +266,14 @@ void FxLine::contextMenuEvent( QContextMenuEvent * )
|
||||
|
||||
|
||||
|
||||
void FxLine::renameChannel()
|
||||
void MixerLine::renameChannel()
|
||||
{
|
||||
m_inRename = true;
|
||||
setToolTip( "" );
|
||||
m_renameLineEdit->setReadOnly( false );
|
||||
m_lcd->hide();
|
||||
m_renameLineEdit->setFixedWidth( 135 );
|
||||
m_renameLineEdit->setText( Engine::fxMixer()->effectChannel( m_channelIndex )->m_name );
|
||||
m_renameLineEdit->setText( Engine::mixer()->mixerChannel( m_channelIndex )->m_name );
|
||||
m_view->setFocus();
|
||||
m_renameLineEdit->selectAll();
|
||||
m_renameLineEdit->setFocus();
|
||||
@@ -283,7 +282,7 @@ void FxLine::renameChannel()
|
||||
|
||||
|
||||
|
||||
void FxLine::renameFinished()
|
||||
void MixerLine::renameFinished()
|
||||
{
|
||||
m_inRename = false;
|
||||
m_renameLineEdit->deselect();
|
||||
@@ -292,56 +291,56 @@ void FxLine::renameFinished()
|
||||
m_lcd->show();
|
||||
QString newName = m_renameLineEdit->text();
|
||||
setFocus();
|
||||
if( !newName.isEmpty() && Engine::fxMixer()->effectChannel( m_channelIndex )->m_name != newName )
|
||||
if( !newName.isEmpty() && Engine::mixer()->mixerChannel( m_channelIndex )->m_name != newName )
|
||||
{
|
||||
Engine::fxMixer()->effectChannel( m_channelIndex )->m_name = newName;
|
||||
Engine::mixer()->mixerChannel( m_channelIndex )->m_name = newName;
|
||||
m_renameLineEdit->setText( elideName( newName ) );
|
||||
Engine::getSong()->setModified();
|
||||
}
|
||||
QString name = Engine::fxMixer()->effectChannel( m_channelIndex )->m_name;
|
||||
QString name = Engine::mixer()->mixerChannel( m_channelIndex )->m_name;
|
||||
setToolTip( name );
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
void FxLine::removeChannel()
|
||||
void MixerLine::removeChannel()
|
||||
{
|
||||
FxMixerView * mix = getGUI()->fxMixerView();
|
||||
MixerView * mix = getGUI()->mixerView();
|
||||
mix->deleteChannel( m_channelIndex );
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
void FxLine::removeUnusedChannels()
|
||||
void MixerLine::removeUnusedChannels()
|
||||
{
|
||||
FxMixerView * mix = getGUI()->fxMixerView();
|
||||
MixerView * mix = getGUI()->mixerView();
|
||||
mix->deleteUnusedChannels();
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
void FxLine::moveChannelLeft()
|
||||
void MixerLine::moveChannelLeft()
|
||||
{
|
||||
FxMixerView * mix = getGUI()->fxMixerView();
|
||||
MixerView * mix = getGUI()->mixerView();
|
||||
mix->moveChannelLeft( m_channelIndex );
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
void FxLine::moveChannelRight()
|
||||
void MixerLine::moveChannelRight()
|
||||
{
|
||||
FxMixerView * mix = getGUI()->fxMixerView();
|
||||
MixerView * mix = getGUI()->mixerView();
|
||||
mix->moveChannelRight( m_channelIndex );
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
QBrush FxLine::backgroundActive() const
|
||||
QBrush MixerLine::backgroundActive() const
|
||||
{
|
||||
return m_backgroundActive;
|
||||
}
|
||||
@@ -349,7 +348,7 @@ QBrush FxLine::backgroundActive() const
|
||||
|
||||
|
||||
|
||||
void FxLine::setBackgroundActive( const QBrush & c )
|
||||
void MixerLine::setBackgroundActive( const QBrush & c )
|
||||
{
|
||||
m_backgroundActive = c;
|
||||
}
|
||||
@@ -357,7 +356,7 @@ void FxLine::setBackgroundActive( const QBrush & c )
|
||||
|
||||
|
||||
|
||||
QColor FxLine::strokeOuterActive() const
|
||||
QColor MixerLine::strokeOuterActive() const
|
||||
{
|
||||
return m_strokeOuterActive;
|
||||
}
|
||||
@@ -365,7 +364,7 @@ QColor FxLine::strokeOuterActive() const
|
||||
|
||||
|
||||
|
||||
void FxLine::setStrokeOuterActive( const QColor & c )
|
||||
void MixerLine::setStrokeOuterActive( const QColor & c )
|
||||
{
|
||||
m_strokeOuterActive = c;
|
||||
}
|
||||
@@ -373,7 +372,7 @@ void FxLine::setStrokeOuterActive( const QColor & c )
|
||||
|
||||
|
||||
|
||||
QColor FxLine::strokeOuterInactive() const
|
||||
QColor MixerLine::strokeOuterInactive() const
|
||||
{
|
||||
return m_strokeOuterInactive;
|
||||
}
|
||||
@@ -381,7 +380,7 @@ QColor FxLine::strokeOuterInactive() const
|
||||
|
||||
|
||||
|
||||
void FxLine::setStrokeOuterInactive( const QColor & c )
|
||||
void MixerLine::setStrokeOuterInactive( const QColor & c )
|
||||
{
|
||||
m_strokeOuterInactive = c;
|
||||
}
|
||||
@@ -389,7 +388,7 @@ void FxLine::setStrokeOuterInactive( const QColor & c )
|
||||
|
||||
|
||||
|
||||
QColor FxLine::strokeInnerActive() const
|
||||
QColor MixerLine::strokeInnerActive() const
|
||||
{
|
||||
return m_strokeInnerActive;
|
||||
}
|
||||
@@ -397,7 +396,7 @@ QColor FxLine::strokeInnerActive() const
|
||||
|
||||
|
||||
|
||||
void FxLine::setStrokeInnerActive( const QColor & c )
|
||||
void MixerLine::setStrokeInnerActive( const QColor & c )
|
||||
{
|
||||
m_strokeInnerActive = c;
|
||||
}
|
||||
@@ -405,7 +404,7 @@ void FxLine::setStrokeInnerActive( const QColor & c )
|
||||
|
||||
|
||||
|
||||
QColor FxLine::strokeInnerInactive() const
|
||||
QColor MixerLine::strokeInnerInactive() const
|
||||
{
|
||||
return m_strokeInnerInactive;
|
||||
}
|
||||
@@ -413,16 +412,16 @@ QColor FxLine::strokeInnerInactive() const
|
||||
|
||||
|
||||
|
||||
void FxLine::setStrokeInnerInactive( const QColor & c )
|
||||
void MixerLine::setStrokeInnerInactive( const QColor & c )
|
||||
{
|
||||
m_strokeInnerInactive = c;
|
||||
}
|
||||
|
||||
|
||||
// Ask user for a color, and set it as the mixer line color
|
||||
void FxLine::selectColor()
|
||||
void MixerLine::selectColor()
|
||||
{
|
||||
auto channel = Engine::fxMixer()->effectChannel( m_channelIndex );
|
||||
auto channel = Engine::mixer()->mixerChannel( m_channelIndex );
|
||||
auto new_color = ColorChooser(this).withPalette(ColorChooser::Palette::Mixer)->getColor(channel->m_color);
|
||||
if(!new_color.isValid()) { return; }
|
||||
channel->setColor (new_color);
|
||||
@@ -432,18 +431,18 @@ void FxLine::selectColor()
|
||||
|
||||
|
||||
// Disable the usage of color on this mixer line
|
||||
void FxLine::resetColor()
|
||||
void MixerLine::resetColor()
|
||||
{
|
||||
Engine::fxMixer()->effectChannel( m_channelIndex )->m_hasColor = false;
|
||||
Engine::mixer()->mixerChannel( m_channelIndex )->m_hasColor = false;
|
||||
Engine::getSong()->setModified();
|
||||
update();
|
||||
}
|
||||
|
||||
|
||||
// Pick a random color from the mixer palette and set it as our color
|
||||
void FxLine::randomizeColor()
|
||||
void MixerLine::randomizeColor()
|
||||
{
|
||||
auto channel = Engine::fxMixer()->effectChannel( m_channelIndex );
|
||||
auto channel = Engine::mixer()->mixerChannel( m_channelIndex );
|
||||
channel->setColor (ColorChooser::getPalette(ColorChooser::Palette::Mixer)[rand() % 48]);
|
||||
Engine::getSong()->setModified();
|
||||
update();
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* FxLineLcdSpinBox.cpp - a specialization of LcdSpnBox for setting FX channels
|
||||
* MixerLineLcdSpinBox.cpp - a specialization of LcdSpnBox for setting mixer channels
|
||||
*
|
||||
* Copyright (c) 2004-2014 Tobias Doerffel <tobydox/at/users.sourceforge.net>
|
||||
*
|
||||
@@ -22,29 +22,29 @@
|
||||
*
|
||||
*/
|
||||
|
||||
#include "FxLineLcdSpinBox.h"
|
||||
#include "MixerLineLcdSpinBox.h"
|
||||
|
||||
#include "CaptionMenu.h"
|
||||
#include "FxMixerView.h"
|
||||
#include "MixerView.h"
|
||||
#include "GuiApplication.h"
|
||||
#include "TrackView.h"
|
||||
|
||||
void FxLineLcdSpinBox::setTrackView(TrackView * tv)
|
||||
void MixerLineLcdSpinBox::setTrackView(TrackView * tv)
|
||||
{
|
||||
m_tv = tv;
|
||||
}
|
||||
|
||||
void FxLineLcdSpinBox::mouseDoubleClickEvent(QMouseEvent* event)
|
||||
void MixerLineLcdSpinBox::mouseDoubleClickEvent(QMouseEvent* event)
|
||||
{
|
||||
getGUI()->fxMixerView()->setCurrentFxLine(model()->value());
|
||||
getGUI()->mixerView()->setCurrentMixerLine(model()->value());
|
||||
|
||||
getGUI()->fxMixerView()->parentWidget()->show();
|
||||
getGUI()->fxMixerView()->show();// show fxMixer window
|
||||
getGUI()->fxMixerView()->setFocus();// set focus to fxMixer window
|
||||
//engine::getFxMixerView()->raise();
|
||||
getGUI()->mixerView()->parentWidget()->show();
|
||||
getGUI()->mixerView()->show();// show Mixer window
|
||||
getGUI()->mixerView()->setFocus();// set focus to Mixer window
|
||||
//engine::getMixerView()->raise();
|
||||
}
|
||||
|
||||
void FxLineLcdSpinBox::contextMenuEvent(QContextMenuEvent* event)
|
||||
void MixerLineLcdSpinBox::contextMenuEvent(QContextMenuEvent* event)
|
||||
{
|
||||
// for the case, the user clicked right while pressing left mouse-
|
||||
// button, the context-menu appears while mouse-cursor is still hidden
|
||||
@@ -54,10 +54,10 @@ void FxLineLcdSpinBox::contextMenuEvent(QContextMenuEvent* event)
|
||||
|
||||
QPointer<CaptionMenu> contextMenu = new CaptionMenu(model()->displayName(), this);
|
||||
|
||||
if (QMenu *fxMenu = m_tv->createFxMenu(
|
||||
tr("Assign to:"), tr("New FX Channel")))
|
||||
if (QMenu *mixerMenu = m_tv->createMixerMenu(
|
||||
tr("Assign to:"), tr("New Mixer Channel")))
|
||||
{
|
||||
contextMenu->addMenu(fxMenu);
|
||||
contextMenu->addMenu(mixerMenu);
|
||||
|
||||
contextMenu->addSeparator();
|
||||
}
|
||||
@@ -63,7 +63,7 @@ void PositionLine::paintEvent(QPaintEvent* pe)
|
||||
if (m_hasTailGradient &&
|
||||
Engine::getSong()->isPlaying() &&
|
||||
(Engine::getSong()->playMode() == Song::Mode_PlaySong ||
|
||||
Engine::getSong()->playMode() == Song::Mode_PlayPattern))
|
||||
Engine::getSong()->playMode() == Song::Mode_PlayMidiClip))
|
||||
{
|
||||
c.setAlpha(60);
|
||||
gradient.setColorAt(w, c);
|
||||
|
||||
@@ -1,12 +1,12 @@
|
||||
#include "SendButtonIndicator.h"
|
||||
|
||||
#include "FxMixer.h"
|
||||
#include "Mixer.h"
|
||||
|
||||
QPixmap * SendButtonIndicator::s_qpmOff = nullptr;
|
||||
QPixmap * SendButtonIndicator::s_qpmOn = nullptr;
|
||||
|
||||
SendButtonIndicator:: SendButtonIndicator( QWidget * _parent, FxLine * _owner,
|
||||
FxMixerView * _mv) :
|
||||
SendButtonIndicator:: SendButtonIndicator( QWidget * _parent, MixerLine * _owner,
|
||||
MixerView * _mv) :
|
||||
QLabel( _parent ),
|
||||
m_parent( _owner ),
|
||||
m_mv( _mv )
|
||||
@@ -21,7 +21,7 @@ SendButtonIndicator:: SendButtonIndicator( QWidget * _parent, FxLine * _owner,
|
||||
s_qpmOn = new QPixmap( embed::getIconPixmap( "mixer_send_on", 29, 20 ) );
|
||||
}
|
||||
|
||||
// don't do any initializing yet, because the FxMixerView and FxLine
|
||||
// don't do any initializing yet, because the MixerView and MixerLine
|
||||
// that were passed to this constructor are not done with their constructors
|
||||
// yet.
|
||||
setPixmap( *s_qpmOff );
|
||||
@@ -29,8 +29,8 @@ SendButtonIndicator:: SendButtonIndicator( QWidget * _parent, FxLine * _owner,
|
||||
|
||||
void SendButtonIndicator::mousePressEvent( QMouseEvent * e )
|
||||
{
|
||||
FxMixer * mix = Engine::fxMixer();
|
||||
int from = m_mv->currentFxLine()->channelIndex();
|
||||
Mixer * mix = Engine::mixer();
|
||||
int from = m_mv->currentMixerLine()->channelIndex();
|
||||
int to = m_parent->channelIndex();
|
||||
FloatModel * sendModel = mix->channelSendModel(from, to);
|
||||
if( sendModel == nullptr )
|
||||
@@ -44,15 +44,15 @@ void SendButtonIndicator::mousePressEvent( QMouseEvent * e )
|
||||
mix->deleteChannelSend( from, to );
|
||||
}
|
||||
|
||||
m_mv->updateFxLine(m_parent->channelIndex());
|
||||
m_mv->updateMixerLine(m_parent->channelIndex());
|
||||
updateLightStatus();
|
||||
}
|
||||
|
||||
FloatModel * SendButtonIndicator::getSendModel()
|
||||
{
|
||||
FxMixer * mix = Engine::fxMixer();
|
||||
Mixer * mix = Engine::mixer();
|
||||
return mix->channelSendModel(
|
||||
m_mv->currentFxLine()->channelIndex(), m_parent->channelIndex());
|
||||
m_mv->currentMixerLine()->channelIndex(), m_parent->channelIndex());
|
||||
}
|
||||
|
||||
void SendButtonIndicator::updateLightStatus()
|
||||
|
||||
@@ -29,7 +29,7 @@
|
||||
#include <QMenu>
|
||||
#include <QPainter>
|
||||
|
||||
#include "AutomationPattern.h"
|
||||
#include "AutomationClip.h"
|
||||
#include "BBEditor.h"
|
||||
#include "BBTrackContainer.h"
|
||||
#include "Clipboard.h"
|
||||
@@ -40,7 +40,7 @@
|
||||
#include "SongEditor.h"
|
||||
#include "StringPairDrag.h"
|
||||
#include "TrackContainerView.h"
|
||||
#include "TrackContentObjectView.h"
|
||||
#include "ClipView.h"
|
||||
#include "TrackView.h"
|
||||
|
||||
|
||||
@@ -132,41 +132,41 @@ void TrackContentWidget::updateBackground()
|
||||
|
||||
|
||||
|
||||
/*! \brief Adds a trackContentObjectView to this widget.
|
||||
/*! \brief Adds a ClipView to this widget.
|
||||
*
|
||||
* Adds a(nother) trackContentObjectView to our list of views. We also
|
||||
* Adds a(nother) ClipView to our list of views. We also
|
||||
* check that our position is up-to-date.
|
||||
*
|
||||
* \param tcov The trackContentObjectView to add.
|
||||
* \param clipv The ClipView to add.
|
||||
*/
|
||||
void TrackContentWidget::addTCOView( TrackContentObjectView * tcov )
|
||||
void TrackContentWidget::addClipView( ClipView * clipv )
|
||||
{
|
||||
TrackContentObject * tco = tcov->getTrackContentObject();
|
||||
Clip * clip = clipv->getClip();
|
||||
|
||||
m_tcoViews.push_back( tcov );
|
||||
m_clipViews.push_back( clipv );
|
||||
|
||||
tco->saveJournallingState( false );
|
||||
clip->saveJournallingState( false );
|
||||
changePosition();
|
||||
tco->restoreJournallingState();
|
||||
clip->restoreJournallingState();
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
/*! \brief Removes the given trackContentObjectView to this widget.
|
||||
/*! \brief Removes the given ClipView from this widget.
|
||||
*
|
||||
* Removes the given trackContentObjectView from our list of views.
|
||||
* Removes the given ClipView from our list of views.
|
||||
*
|
||||
* \param tcov The trackContentObjectView to add.
|
||||
* \param clipv The ClipView to add.
|
||||
*/
|
||||
void TrackContentWidget::removeTCOView( TrackContentObjectView * tcov )
|
||||
void TrackContentWidget::removeClipView( ClipView * clipv )
|
||||
{
|
||||
tcoViewVector::iterator it = std::find( m_tcoViews.begin(),
|
||||
m_tcoViews.end(),
|
||||
tcov );
|
||||
if( it != m_tcoViews.end() )
|
||||
clipViewVector::iterator it = std::find( m_clipViews.begin(),
|
||||
m_clipViews.end(),
|
||||
clipv );
|
||||
if( it != m_clipViews.end() )
|
||||
{
|
||||
m_tcoViews.erase( it );
|
||||
m_clipViews.erase( it );
|
||||
Engine::getSong()->setModified();
|
||||
}
|
||||
}
|
||||
@@ -174,13 +174,13 @@ void TrackContentWidget::removeTCOView( TrackContentObjectView * tcov )
|
||||
|
||||
|
||||
|
||||
/*! \brief Update ourselves by updating all the tCOViews attached.
|
||||
/*! \brief Update ourselves by updating all the ClipViews attached.
|
||||
*
|
||||
*/
|
||||
void TrackContentWidget::update()
|
||||
{
|
||||
for( tcoViewVector::iterator it = m_tcoViews.begin();
|
||||
it != m_tcoViews.end(); ++it )
|
||||
for( clipViewVector::iterator it = m_clipViews.begin();
|
||||
it != m_clipViews.end(); ++it )
|
||||
{
|
||||
( *it )->setFixedHeight( height() - 1 );
|
||||
( *it )->update();
|
||||
@@ -204,11 +204,11 @@ void TrackContentWidget::changePosition( const TimePos & newPos )
|
||||
const int curBB = Engine::getBBTrackContainer()->currentBB();
|
||||
setUpdatesEnabled( false );
|
||||
|
||||
// first show TCO for current BB...
|
||||
for( tcoViewVector::iterator it = m_tcoViews.begin();
|
||||
it != m_tcoViews.end(); ++it )
|
||||
// first show Clip for current BB...
|
||||
for( clipViewVector::iterator it = m_clipViews.begin();
|
||||
it != m_clipViews.end(); ++it )
|
||||
{
|
||||
if( ( *it )->getTrackContentObject()->
|
||||
if( ( *it )->getClip()->
|
||||
startPosition().getBar() == curBB )
|
||||
{
|
||||
( *it )->move( 0, ( *it )->y() );
|
||||
@@ -221,10 +221,10 @@ void TrackContentWidget::changePosition( const TimePos & newPos )
|
||||
}
|
||||
}
|
||||
// ...then hide others to avoid flickering
|
||||
for( tcoViewVector::iterator it = m_tcoViews.begin();
|
||||
it != m_tcoViews.end(); ++it )
|
||||
for( clipViewVector::iterator it = m_clipViews.begin();
|
||||
it != m_clipViews.end(); ++it )
|
||||
{
|
||||
if( ( *it )->getTrackContentObject()->
|
||||
if( ( *it )->getClip()->
|
||||
startPosition().getBar() != curBB )
|
||||
{
|
||||
( *it )->hide();
|
||||
@@ -245,31 +245,31 @@ void TrackContentWidget::changePosition( const TimePos & newPos )
|
||||
const float ppb = m_trackView->trackContainerView()->pixelsPerBar();
|
||||
|
||||
setUpdatesEnabled( false );
|
||||
for( tcoViewVector::iterator it = m_tcoViews.begin();
|
||||
it != m_tcoViews.end(); ++it )
|
||||
for( clipViewVector::iterator it = m_clipViews.begin();
|
||||
it != m_clipViews.end(); ++it )
|
||||
{
|
||||
TrackContentObjectView * tcov = *it;
|
||||
TrackContentObject * tco = tcov->getTrackContentObject();
|
||||
ClipView * clipv = *it;
|
||||
Clip * clip = clipv->getClip();
|
||||
|
||||
tco->changeLength( tco->length() );
|
||||
clip->changeLength( clip->length() );
|
||||
|
||||
const int ts = tco->startPosition();
|
||||
const int te = tco->endPosition()-3;
|
||||
const int ts = clip->startPosition();
|
||||
const int te = clip->endPosition()-3;
|
||||
if( ( ts >= begin && ts <= end ) ||
|
||||
( te >= begin && te <= end ) ||
|
||||
( ts <= begin && te >= end ) )
|
||||
{
|
||||
tcov->move( static_cast<int>( ( ts - begin ) * ppb /
|
||||
clipv->move( static_cast<int>( ( ts - begin ) * ppb /
|
||||
TimePos::ticksPerBar() ),
|
||||
tcov->y() );
|
||||
if( !tcov->isVisible() )
|
||||
clipv->y() );
|
||||
if( !clipv->isVisible() )
|
||||
{
|
||||
tcov->show();
|
||||
clipv->show();
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
tcov->move( -tcov->width()-10, tcov->y() );
|
||||
clipv->move( -clipv->width()-10, clipv->y() );
|
||||
}
|
||||
}
|
||||
setUpdatesEnabled( true );
|
||||
@@ -303,14 +303,14 @@ TimePos TrackContentWidget::getPosition( int mouseX )
|
||||
*/
|
||||
void TrackContentWidget::dragEnterEvent( QDragEnterEvent * dee )
|
||||
{
|
||||
TimePos tcoPos = getPosition( dee->pos().x() );
|
||||
if( canPasteSelection( tcoPos, dee ) == false )
|
||||
TimePos clipPos = getPosition( dee->pos().x() );
|
||||
if( canPasteSelection( clipPos, dee ) == false )
|
||||
{
|
||||
dee->ignore();
|
||||
}
|
||||
else
|
||||
{
|
||||
StringPairDrag::processDragEnterEvent( dee, "tco_" +
|
||||
StringPairDrag::processDragEnterEvent( dee, "clip_" +
|
||||
QString::number( getTrack()->type() ) );
|
||||
}
|
||||
}
|
||||
@@ -318,24 +318,24 @@ void TrackContentWidget::dragEnterEvent( QDragEnterEvent * dee )
|
||||
|
||||
|
||||
|
||||
/*! \brief Returns whether a selection of TCOs can be pasted into this
|
||||
/*! \brief Returns whether a selection of Clips can be pasted into this
|
||||
*
|
||||
* \param tcoPos the position of the TCO slot being pasted on
|
||||
* \param clipPos the position of the Clip slot being pasted on
|
||||
* \param de the DropEvent generated
|
||||
*/
|
||||
bool TrackContentWidget::canPasteSelection( TimePos tcoPos, const QDropEvent* de )
|
||||
bool TrackContentWidget::canPasteSelection( TimePos clipPos, const QDropEvent* de )
|
||||
{
|
||||
const QMimeData * mimeData = de->mimeData();
|
||||
|
||||
// If the source of the DropEvent is the current instance of LMMS we don't allow pasting in the same bar
|
||||
// if it's another instance of LMMS we allow it
|
||||
return de->source()
|
||||
? canPasteSelection( tcoPos, mimeData )
|
||||
: canPasteSelection( tcoPos, mimeData, true );
|
||||
? canPasteSelection( clipPos, mimeData )
|
||||
: canPasteSelection( clipPos, mimeData, true );
|
||||
}
|
||||
|
||||
// Overloaded method to make it possible to call this method without a Drag&Drop event
|
||||
bool TrackContentWidget::canPasteSelection( TimePos tcoPos, const QMimeData* md , bool allowSameBar )
|
||||
bool TrackContentWidget::canPasteSelection( TimePos clipPos, const QMimeData* md , bool allowSameBar )
|
||||
{
|
||||
// For decodeKey() and decodeValue()
|
||||
using namespace Clipboard;
|
||||
@@ -345,20 +345,20 @@ bool TrackContentWidget::canPasteSelection( TimePos tcoPos, const QMimeData* md
|
||||
QString value = decodeValue( md );
|
||||
|
||||
// We can only paste into tracks of the same type
|
||||
if( type != ( "tco_" + QString::number( t->type() ) ) ||
|
||||
m_trackView->trackContainerView()->fixedTCOs() == true )
|
||||
if( type != ( "clip_" + QString::number( t->type() ) ) ||
|
||||
m_trackView->trackContainerView()->fixedClips() == true )
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
// value contains XML needed to reconstruct TCOs and place them
|
||||
// value contains XML needed to reconstruct Clips and place them
|
||||
DataFile dataFile( value.toUtf8() );
|
||||
|
||||
// Extract the metadata and which TCO was grabbed
|
||||
// Extract the metadata and which Clip was grabbed
|
||||
QDomElement metadata = dataFile.content().firstChildElement( "copyMetadata" );
|
||||
QDomAttr tcoPosAttr = metadata.attributeNode( "grabbedTCOPos" );
|
||||
TimePos grabbedTCOPos = tcoPosAttr.value().toInt();
|
||||
TimePos grabbedTCOBar = TimePos( grabbedTCOPos.getBar(), 0 );
|
||||
QDomAttr clipPosAttr = metadata.attributeNode( "grabbedClipPos" );
|
||||
TimePos grabbedClipPos = clipPosAttr.value().toInt();
|
||||
TimePos grabbedClipBar = TimePos( grabbedClipPos.getBar(), 0 );
|
||||
|
||||
// Extract the track index that was originally clicked
|
||||
QDomAttr tiAttr = metadata.attributeNode( "initialTrackIndex" );
|
||||
@@ -371,20 +371,20 @@ bool TrackContentWidget::canPasteSelection( TimePos tcoPos, const QMimeData* md
|
||||
// Don't paste if we're on the same bar and allowSameBar is false
|
||||
auto sourceTrackContainerId = metadata.attributeNode( "trackContainerId" ).value().toUInt();
|
||||
if( !allowSameBar && sourceTrackContainerId == t->trackContainer()->id() &&
|
||||
tcoPos == grabbedTCOBar && currentTrackIndex == initialTrackIndex )
|
||||
clipPos == grabbedClipBar && currentTrackIndex == initialTrackIndex )
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
// Extract the tco data
|
||||
QDomElement tcoParent = dataFile.content().firstChildElement( "tcos" );
|
||||
QDomNodeList tcoNodes = tcoParent.childNodes();
|
||||
// Extract the clip data
|
||||
QDomElement clipParent = dataFile.content().firstChildElement("clips");
|
||||
QDomNodeList clipNodes = clipParent.childNodes();
|
||||
|
||||
// Determine if all the TCOs will land on a valid track
|
||||
for( int i = 0; i < tcoNodes.length(); i++ )
|
||||
// Determine if all the Clips will land on a valid track
|
||||
for( int i = 0; i < clipNodes.length(); i++ )
|
||||
{
|
||||
QDomElement tcoElement = tcoNodes.item( i ).toElement();
|
||||
int trackIndex = tcoElement.attributeNode( "trackIndex" ).value().toInt();
|
||||
QDomElement clipElement = clipNodes.item( i ).toElement();
|
||||
int trackIndex = clipElement.attributeNode( "trackIndex" ).value().toInt();
|
||||
int finalTrackIndex = trackIndex + currentTrackIndex - initialTrackIndex;
|
||||
|
||||
// Track must be in TrackContainer's tracks
|
||||
@@ -394,7 +394,7 @@ bool TrackContentWidget::canPasteSelection( TimePos tcoPos, const QMimeData* md
|
||||
}
|
||||
|
||||
// Track must be of the same type
|
||||
auto startTrackType = tcoElement.attributeNode("trackType").value().toInt();
|
||||
auto startTrackType = clipElement.attributeNode("trackType").value().toInt();
|
||||
Track * endTrack = tracks.at( finalTrackIndex );
|
||||
if( startTrackType != endTrack->type() )
|
||||
{
|
||||
@@ -405,32 +405,32 @@ bool TrackContentWidget::canPasteSelection( TimePos tcoPos, const QMimeData* md
|
||||
return true;
|
||||
}
|
||||
|
||||
/*! \brief Pastes a selection of TCOs onto the track
|
||||
/*! \brief Pastes a selection of Clips onto the track
|
||||
*
|
||||
* \param tcoPos the position of the TCO slot being pasted on
|
||||
* \param clipPos the position of the Clip slot being pasted on
|
||||
* \param de the DropEvent generated
|
||||
*/
|
||||
bool TrackContentWidget::pasteSelection( TimePos tcoPos, QDropEvent * de )
|
||||
bool TrackContentWidget::pasteSelection( TimePos clipPos, QDropEvent * de )
|
||||
{
|
||||
const QMimeData * mimeData = de->mimeData();
|
||||
|
||||
if( canPasteSelection( tcoPos, de ) == false )
|
||||
if( canPasteSelection( clipPos, de ) == false )
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
// We set skipSafetyCheck to true because we already called canPasteSelection
|
||||
return pasteSelection( tcoPos, mimeData, true );
|
||||
return pasteSelection( clipPos, mimeData, true );
|
||||
}
|
||||
|
||||
// Overloaded method so we can call it without a Drag&Drop event
|
||||
bool TrackContentWidget::pasteSelection( TimePos tcoPos, const QMimeData * md, bool skipSafetyCheck )
|
||||
bool TrackContentWidget::pasteSelection( TimePos clipPos, const QMimeData * md, bool skipSafetyCheck )
|
||||
{
|
||||
// For decodeKey() and decodeValue()
|
||||
using namespace Clipboard;
|
||||
|
||||
// When canPasteSelection was already called before, skipSafetyCheck will skip this
|
||||
if( !skipSafetyCheck && canPasteSelection( tcoPos, md ) == false )
|
||||
if( !skipSafetyCheck && canPasteSelection( clipPos, md ) == false )
|
||||
{
|
||||
return false;
|
||||
}
|
||||
@@ -440,19 +440,19 @@ bool TrackContentWidget::pasteSelection( TimePos tcoPos, const QMimeData * md, b
|
||||
|
||||
getTrack()->addJournalCheckPoint();
|
||||
|
||||
// value contains XML needed to reconstruct TCOs and place them
|
||||
// value contains XML needed to reconstruct Clips and place them
|
||||
DataFile dataFile( value.toUtf8() );
|
||||
|
||||
// Extract the tco data
|
||||
QDomElement tcoParent = dataFile.content().firstChildElement( "tcos" );
|
||||
QDomNodeList tcoNodes = tcoParent.childNodes();
|
||||
// Extract the clip data
|
||||
QDomElement clipParent = dataFile.content().firstChildElement("clips");
|
||||
QDomNodeList clipNodes = clipParent.childNodes();
|
||||
|
||||
// Extract the track index that was originally clicked
|
||||
QDomElement metadata = dataFile.content().firstChildElement( "copyMetadata" );
|
||||
QDomAttr tiAttr = metadata.attributeNode( "initialTrackIndex" );
|
||||
int initialTrackIndex = tiAttr.value().toInt();
|
||||
QDomAttr tcoPosAttr = metadata.attributeNode( "grabbedTCOPos" );
|
||||
TimePos grabbedTCOPos = tcoPosAttr.value().toInt();
|
||||
QDomAttr clipPosAttr = metadata.attributeNode( "grabbedClipPos" );
|
||||
TimePos grabbedClipPos = clipPosAttr.value().toInt();
|
||||
|
||||
// Snap the mouse position to the beginning of the dropped bar, in ticks
|
||||
const TrackContainer::TrackList tracks = getTrack()->trackContainer()->tracks();
|
||||
@@ -470,56 +470,56 @@ bool TrackContentWidget::pasteSelection( TimePos tcoPos, const QMimeData * md, b
|
||||
}
|
||||
|
||||
|
||||
// TODO -- Need to draw the hovericon either way, or ghost the TCOs
|
||||
// TODO -- Need to draw the hovericon either way, or ghost the Clips
|
||||
// onto their final position.
|
||||
|
||||
float snapSize = getGUI()->songEditor()->m_editor->getSnapSize();
|
||||
// All patterns should be offset the same amount as the grabbed pattern
|
||||
TimePos offset = TimePos(tcoPos - grabbedTCOPos);
|
||||
// All clips should be offset the same amount as the grabbed clip
|
||||
TimePos offset = TimePos(clipPos - grabbedClipPos);
|
||||
// Users expect clips to "fall" backwards, so bias the offset
|
||||
offset -= TimePos::ticksPerBar() * snapSize / 2;
|
||||
// The offset is quantized (rather than the positions) to preserve fine adjustments
|
||||
offset = offset.quantize(snapSize);
|
||||
|
||||
// Get the leftmost TCO and fix the offset if it reaches below bar 0
|
||||
TimePos leftmostPos = grabbedTCOPos;
|
||||
for(int i = 0; i < tcoNodes.length(); ++i)
|
||||
// Get the leftmost Clip and fix the offset if it reaches below bar 0
|
||||
TimePos leftmostPos = grabbedClipPos;
|
||||
for(int i = 0; i < clipNodes.length(); ++i)
|
||||
{
|
||||
QDomElement outerTCOElement = tcoNodes.item(i).toElement();
|
||||
QDomElement tcoElement = outerTCOElement.firstChildElement();
|
||||
QDomElement outerClipElement = clipNodes.item(i).toElement();
|
||||
QDomElement clipElement = outerClipElement.firstChildElement();
|
||||
|
||||
TimePos pos = tcoElement.attributeNode("pos").value().toInt();
|
||||
TimePos pos = clipElement.attributeNode("pos").value().toInt();
|
||||
|
||||
if(pos < leftmostPos) { leftmostPos = pos; }
|
||||
}
|
||||
// Fix offset if it sets the left most TCO to a negative position
|
||||
// Fix offset if it sets the left most Clip to a negative position
|
||||
offset = std::max(offset.getTicks(), -leftmostPos.getTicks());
|
||||
|
||||
for( int i = 0; i<tcoNodes.length(); i++ )
|
||||
for( int i = 0; i<clipNodes.length(); i++ )
|
||||
{
|
||||
QDomElement outerTCOElement = tcoNodes.item( i ).toElement();
|
||||
QDomElement tcoElement = outerTCOElement.firstChildElement();
|
||||
QDomElement outerClipElement = clipNodes.item( i ).toElement();
|
||||
QDomElement clipElement = outerClipElement.firstChildElement();
|
||||
|
||||
int trackIndex = outerTCOElement.attributeNode( "trackIndex" ).value().toInt();
|
||||
int trackIndex = outerClipElement.attributeNode( "trackIndex" ).value().toInt();
|
||||
int finalTrackIndex = trackIndex + ( currentTrackIndex - initialTrackIndex );
|
||||
Track * t = tracks.at( finalTrackIndex );
|
||||
|
||||
// The new position is the old position plus the offset.
|
||||
TimePos pos = tcoElement.attributeNode( "pos" ).value().toInt() + offset;
|
||||
TimePos pos = clipElement.attributeNode( "pos" ).value().toInt() + offset;
|
||||
// If we land on ourselves, offset by one snap
|
||||
TimePos shift = TimePos::ticksPerBar() * getGUI()->songEditor()->m_editor->getSnapSize();
|
||||
if (offset == 0 && initialTrackIndex == currentTrackIndex) { pos += shift; }
|
||||
|
||||
TrackContentObject * tco = t->createTCO( pos );
|
||||
tco->restoreState( tcoElement );
|
||||
tco->movePosition(pos); // Because we restored the state, we need to move the TCO again.
|
||||
Clip * clip = t->createClip( pos );
|
||||
clip->restoreState( clipElement );
|
||||
clip->movePosition(pos); // Because we restored the state, we need to move the Clip again.
|
||||
if( wasSelection )
|
||||
{
|
||||
tco->selectViewOnCreate( true );
|
||||
clip->selectViewOnCreate( true );
|
||||
}
|
||||
}
|
||||
|
||||
AutomationPattern::resolveAllIDs();
|
||||
AutomationClip::resolveAllIDs();
|
||||
|
||||
return true;
|
||||
}
|
||||
@@ -531,8 +531,8 @@ bool TrackContentWidget::pasteSelection( TimePos tcoPos, const QMimeData * md, b
|
||||
*/
|
||||
void TrackContentWidget::dropEvent( QDropEvent * de )
|
||||
{
|
||||
TimePos tcoPos = TimePos( getPosition( de->pos().x() ) );
|
||||
if( pasteSelection( tcoPos, de ) == true )
|
||||
TimePos clipPos = TimePos( getPosition( de->pos().x() ) );
|
||||
if( pasteSelection( clipPos, de ) == true )
|
||||
{
|
||||
de->accept();
|
||||
}
|
||||
@@ -548,7 +548,7 @@ void TrackContentWidget::dropEvent( QDropEvent * de )
|
||||
void TrackContentWidget::mousePressEvent( QMouseEvent * me )
|
||||
{
|
||||
// Enable box select if control is held when clicking an empty space
|
||||
// (If we had clicked a TCO it would have intercepted the mouse event)
|
||||
// (If we had clicked a Clip it would have intercepted the mouse event)
|
||||
if( me->modifiers() & Qt::ControlModifier ){
|
||||
getGUI()->songEditor()->m_editor->setEditMode(SongEditor::EditMode::SelectMode);
|
||||
}
|
||||
@@ -562,9 +562,9 @@ void TrackContentWidget::mousePressEvent( QMouseEvent * me )
|
||||
{
|
||||
QWidget::mousePressEvent( me );
|
||||
}
|
||||
// For an unmodified click, create a new TCO
|
||||
// For an unmodified click, create a new Clip
|
||||
else if( me->button() == Qt::LeftButton &&
|
||||
!m_trackView->trackContainerView()->fixedTCOs() )
|
||||
!m_trackView->trackContainerView()->fixedClips() )
|
||||
{
|
||||
QVector<selectableObject*> so = m_trackView->trackContainerView()->rubberBand()->selectedObjects();
|
||||
for( int i = 0; i < so.count(); ++i )
|
||||
@@ -574,7 +574,7 @@ void TrackContentWidget::mousePressEvent( QMouseEvent * me )
|
||||
getTrack()->addJournalCheckPoint();
|
||||
const TimePos pos = getPosition( me->x() ).getBar() *
|
||||
TimePos::ticksPerBar();
|
||||
getTrack()->createTCO(pos);
|
||||
getTrack()->createClip(pos);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -658,7 +658,7 @@ void TrackContentWidget::contextMenuEvent( QContextMenuEvent * cme )
|
||||
return;
|
||||
}
|
||||
|
||||
// If we don't have TCO data in the clipboard there's no need to create this menu
|
||||
// If we don't have Clip data in the clipboard there's no need to create this menu
|
||||
// since "paste" is the only action at the moment.
|
||||
if( ! hasFormat( MimeType::StringPair ) )
|
||||
{
|
||||
@@ -683,9 +683,9 @@ void TrackContentWidget::contextMenuAction( QContextMenuEvent * cme, ContextMenu
|
||||
{
|
||||
case Paste:
|
||||
// Paste the selection on the TimePos of the context menu event
|
||||
TimePos tcoPos = getPosition( cme->x() );
|
||||
TimePos clipPos = getPosition( cme->x() );
|
||||
|
||||
pasteSelection( tcoPos, getMimeData() );
|
||||
pasteSelection( clipPos, getMimeData() );
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -31,7 +31,7 @@
|
||||
#include <QPushButton>
|
||||
#include <QCheckBox>
|
||||
|
||||
#include "AutomationPattern.h"
|
||||
#include "AutomationClip.h"
|
||||
#include "AutomationTrackView.h"
|
||||
#include "ColorChooser.h"
|
||||
#include "ConfigManager.h"
|
||||
@@ -246,13 +246,13 @@ void TrackOperationsWidget::cloneTrack()
|
||||
}
|
||||
|
||||
|
||||
/*! \brief Clear this track - clears all TCOs from the track */
|
||||
/*! \brief Clear this track - clears all Clips from the track */
|
||||
void TrackOperationsWidget::clearTrack()
|
||||
{
|
||||
Track * t = m_trackView->getTrack();
|
||||
t->addJournalCheckPoint();
|
||||
t->lock();
|
||||
t->deleteTCOs();
|
||||
t->deleteClips();
|
||||
t->unlock();
|
||||
}
|
||||
|
||||
@@ -300,13 +300,13 @@ void TrackOperationsWidget::randomizeTrackColor()
|
||||
Engine::getSong()->setModified();
|
||||
}
|
||||
|
||||
void TrackOperationsWidget::resetTCOColors()
|
||||
void TrackOperationsWidget::resetClipColors()
|
||||
{
|
||||
auto track = m_trackView->getTrack();
|
||||
track->addJournalCheckPoint();
|
||||
for (auto tco: track->getTCOs())
|
||||
for (auto clip: track->getClips())
|
||||
{
|
||||
tco->useCustomClipColor(false);
|
||||
clip->useCustomClipColor(false);
|
||||
}
|
||||
Engine::getSong()->setModified();
|
||||
}
|
||||
@@ -319,7 +319,7 @@ void TrackOperationsWidget::resetTCOColors()
|
||||
* For all track types, we have the Clone and Remove options.
|
||||
* For instrument-tracks we also offer the MIDI-control-menu
|
||||
* For automation tracks, extra options: turn on/off recording
|
||||
* on all TCOs (same should be added for sample tracks when
|
||||
* on all Clips (same should be added for sample tracks when
|
||||
* sampletrack recording is implemented)
|
||||
*/
|
||||
void TrackOperationsWidget::updateMenu()
|
||||
@@ -333,13 +333,13 @@ void TrackOperationsWidget::updateMenu()
|
||||
tr( "Remove this track" ),
|
||||
this, SLOT( removeTrack() ) );
|
||||
|
||||
if( ! m_trackView->trackContainerView()->fixedTCOs() )
|
||||
if( ! m_trackView->trackContainerView()->fixedClips() )
|
||||
{
|
||||
toMenu->addAction( tr( "Clear this track" ), this, SLOT( clearTrack() ) );
|
||||
}
|
||||
if (QMenu *fxMenu = m_trackView->createFxMenu(tr("FX %1: %2"), tr("Assign to new FX Channel")))
|
||||
if (QMenu *mixerMenu = m_trackView->createMixerMenu(tr("Channel %1: %2"), tr("Assign to new Mixer Channel")))
|
||||
{
|
||||
toMenu->addMenu(fxMenu);
|
||||
toMenu->addMenu(mixerMenu);
|
||||
}
|
||||
|
||||
if (InstrumentTrackView * trackView = dynamic_cast<InstrumentTrackView *>(m_trackView))
|
||||
@@ -361,7 +361,7 @@ void TrackOperationsWidget::updateMenu()
|
||||
colorMenu->addAction(tr("Reset"), this, SLOT(resetTrackColor()));
|
||||
colorMenu->addAction(tr("Pick random"), this, SLOT(randomizeTrackColor()));
|
||||
colorMenu->addSeparator();
|
||||
colorMenu->addAction(tr("Reset clip colors"), this, SLOT(resetTCOColors()));
|
||||
colorMenu->addAction(tr("Reset clip colors"), this, SLOT(resetClipColors()));
|
||||
}
|
||||
|
||||
|
||||
@@ -370,9 +370,9 @@ void TrackOperationsWidget::toggleRecording( bool on )
|
||||
AutomationTrackView * atv = dynamic_cast<AutomationTrackView *>( m_trackView );
|
||||
if( atv )
|
||||
{
|
||||
for( TrackContentObject * tco : atv->getTrack()->getTCOs() )
|
||||
for( Clip * clip : atv->getTrack()->getClips() )
|
||||
{
|
||||
AutomationPattern * ap = dynamic_cast<AutomationPattern *>( tco );
|
||||
AutomationClip * ap = dynamic_cast<AutomationClip *>( clip );
|
||||
if( ap ) { ap->setRecording( on ); }
|
||||
}
|
||||
atv->update();
|
||||
|
||||
@@ -25,7 +25,7 @@
|
||||
*/
|
||||
|
||||
#include "AutomationTrackView.h"
|
||||
#include "AutomationPattern.h"
|
||||
#include "AutomationClip.h"
|
||||
|
||||
|
||||
AutomationTrack::AutomationTrack( TrackContainer* tc, bool _hidden ) :
|
||||
@@ -35,7 +35,7 @@ AutomationTrack::AutomationTrack( TrackContainer* tc, bool _hidden ) :
|
||||
}
|
||||
|
||||
bool AutomationTrack::play( const TimePos & time_start, const fpp_t _frames,
|
||||
const f_cnt_t _frame_base, int _tco_num )
|
||||
const f_cnt_t _frame_base, int _clip_num )
|
||||
{
|
||||
return false;
|
||||
}
|
||||
@@ -51,9 +51,9 @@ TrackView * AutomationTrack::createView( TrackContainerView* tcv )
|
||||
|
||||
|
||||
|
||||
TrackContentObject* AutomationTrack::createTCO(const TimePos & pos)
|
||||
Clip* AutomationTrack::createClip(const TimePos & pos)
|
||||
{
|
||||
AutomationPattern* p = new AutomationPattern(this);
|
||||
AutomationClip* p = new AutomationClip(this);
|
||||
p->movePosition(pos);
|
||||
return p;
|
||||
}
|
||||
|
||||
@@ -43,7 +43,7 @@ BBTrack::BBTrack( TrackContainer* tc ) :
|
||||
s_infoMap[this] = bbNum;
|
||||
|
||||
setName( tr( "Beat/Bassline %1" ).arg( bbNum ) );
|
||||
Engine::getBBTrackContainer()->createTCOsForBB( bbNum );
|
||||
Engine::getBBTrackContainer()->createClipsForBB( bbNum );
|
||||
Engine::getBBTrackContainer()->setCurrentBB( bbNum );
|
||||
Engine::getBBTrackContainer()->updateComboBox();
|
||||
|
||||
@@ -82,31 +82,31 @@ BBTrack::~BBTrack()
|
||||
|
||||
|
||||
|
||||
// play _frames frames of given TCO within starting with _start
|
||||
// play _frames frames of given Clip within starting with _start
|
||||
bool BBTrack::play( const TimePos & _start, const fpp_t _frames,
|
||||
const f_cnt_t _offset, int _tco_num )
|
||||
const f_cnt_t _offset, int _clip_num )
|
||||
{
|
||||
if( isMuted() )
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
if( _tco_num >= 0 )
|
||||
if( _clip_num >= 0 )
|
||||
{
|
||||
return Engine::getBBTrackContainer()->play( _start, _frames, _offset, s_infoMap[this] );
|
||||
}
|
||||
|
||||
tcoVector tcos;
|
||||
getTCOsInRange( tcos, _start, _start + static_cast<int>( _frames / Engine::framesPerTick() ) );
|
||||
clipVector clips;
|
||||
getClipsInRange( clips, _start, _start + static_cast<int>( _frames / Engine::framesPerTick() ) );
|
||||
|
||||
if( tcos.size() == 0 )
|
||||
if( clips.size() == 0 )
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
TimePos lastPosition;
|
||||
TimePos lastLen;
|
||||
for( tcoVector::iterator it = tcos.begin(); it != tcos.end(); ++it )
|
||||
for( clipVector::iterator it = clips.begin(); it != clips.end(); ++it )
|
||||
{
|
||||
if( !( *it )->isMuted() &&
|
||||
( *it )->startPosition() >= lastPosition )
|
||||
@@ -134,11 +134,11 @@ TrackView * BBTrack::createView( TrackContainerView* tcv )
|
||||
|
||||
|
||||
|
||||
TrackContentObject* BBTrack::createTCO(const TimePos & pos)
|
||||
Clip* BBTrack::createClip(const TimePos & pos)
|
||||
{
|
||||
BBTCO* bbtco = new BBTCO(this);
|
||||
bbtco->movePosition(pos);
|
||||
return bbtco;
|
||||
BBClip* bbclip = new BBClip(this);
|
||||
bbclip->movePosition(pos);
|
||||
return bbclip;
|
||||
}
|
||||
|
||||
|
||||
@@ -179,13 +179,13 @@ void BBTrack::loadTrackSpecificSettings( const QDomElement & _this )
|
||||
const int dst = s_infoMap[this];
|
||||
TrackContainer::TrackList tl =
|
||||
Engine::getBBTrackContainer()->tracks();
|
||||
// copy TCOs of all tracks from source BB (at bar "src") to destination
|
||||
// TCOs (which are created if they do not exist yet)
|
||||
// copy Clips of all tracks from source BB (at bar "src") to destination
|
||||
// Clips (which are created if they do not exist yet)
|
||||
for( TrackContainer::TrackList::iterator it = tl.begin();
|
||||
it != tl.end(); ++it )
|
||||
{
|
||||
TrackContentObject::copyStateTo( ( *it )->getTCO( src ),
|
||||
( *it )->getTCO( dst ) );
|
||||
Clip::copyStateTo( ( *it )->getClip( src ),
|
||||
( *it )->getClip( dst ) );
|
||||
}
|
||||
setName( tr( "Clone of %1" ).arg(
|
||||
_this.parentNode().toElement().attribute( "name" ) ) );
|
||||
|
||||
@@ -3,7 +3,7 @@ set(LMMS_SRCS
|
||||
tracks/AutomationTrack.cpp
|
||||
tracks/BBTrack.cpp
|
||||
tracks/InstrumentTrack.cpp
|
||||
tracks/Pattern.cpp
|
||||
tracks/MidiClip.cpp
|
||||
tracks/SampleTrack.cpp
|
||||
|
||||
PARENT_SCOPE
|
||||
|
||||
@@ -24,17 +24,17 @@
|
||||
#include "InstrumentTrack.h"
|
||||
|
||||
#include "AudioEngine.h"
|
||||
#include "AutomationPattern.h"
|
||||
#include "AutomationClip.h"
|
||||
#include "BBTrack.h"
|
||||
#include "ConfigManager.h"
|
||||
#include "ControllerConnection.h"
|
||||
#include "DataFile.h"
|
||||
#include "FxMixer.h"
|
||||
#include "Mixer.h"
|
||||
#include "InstrumentTrackView.h"
|
||||
#include "Instrument.h"
|
||||
#include "MidiClient.h"
|
||||
#include "MidiClip.h"
|
||||
#include "MixHelpers.h"
|
||||
#include "Pattern.h"
|
||||
#include "Song.h"
|
||||
|
||||
|
||||
@@ -56,7 +56,7 @@ InstrumentTrack::InstrumentTrack( TrackContainer* tc ) :
|
||||
m_audioPort( tr( "unnamed_track" ), true, &m_volumeModel, &m_panningModel, &m_mutedModel ),
|
||||
m_pitchModel( 0, MinPitchDefault, MaxPitchDefault, 1, this, tr( "Pitch" ) ),
|
||||
m_pitchRangeModel( 1, 1, 60, this, tr( "Pitch range" ) ),
|
||||
m_effectChannelModel( 0, 0, 0, this, tr( "FX channel" ) ),
|
||||
m_mixerChannelModel( 0, 0, 0, this, tr( "Mixer channel" ) ),
|
||||
m_useMasterPitchModel( true, this, tr( "Master pitch") ),
|
||||
m_instrument( nullptr ),
|
||||
m_soundShaping( this ),
|
||||
@@ -71,7 +71,7 @@ InstrumentTrack::InstrumentTrack( TrackContainer* tc ) :
|
||||
m_firstKeyModel.setInitValue(0);
|
||||
m_lastKeyModel.setInitValue(NumKeys - 1);
|
||||
|
||||
m_effectChannelModel.setRange( 0, Engine::fxMixer()->numChannels()-1, 1);
|
||||
m_mixerChannelModel.setRange( 0, Engine::mixer()->numChannels()-1, 1);
|
||||
|
||||
for( int i = 0; i < NumKeys; ++i )
|
||||
{
|
||||
@@ -100,7 +100,7 @@ InstrumentTrack::InstrumentTrack( TrackContainer* tc ) :
|
||||
connect(&m_baseNoteModel, SIGNAL(dataChanged()), this, SLOT(updateBaseNote()), Qt::DirectConnection);
|
||||
connect(&m_pitchModel, SIGNAL(dataChanged()), this, SLOT(updatePitch()), Qt::DirectConnection);
|
||||
connect(&m_pitchRangeModel, SIGNAL(dataChanged()), this, SLOT(updatePitchRange()), Qt::DirectConnection);
|
||||
connect(&m_effectChannelModel, SIGNAL(dataChanged()), this, SLOT(updateEffectChannel()), Qt::DirectConnection);
|
||||
connect(&m_mixerChannelModel, SIGNAL(dataChanged()), this, SLOT(updateMixerChannel()), Qt::DirectConnection);
|
||||
}
|
||||
|
||||
|
||||
@@ -214,7 +214,7 @@ InstrumentTrack::~InstrumentTrack()
|
||||
void InstrumentTrack::processAudioBuffer( sampleFrame* buf, const fpp_t frames, NotePlayHandle* n )
|
||||
{
|
||||
// we must not play the sound if this InstrumentTrack is muted...
|
||||
if( isMuted() || ( Engine::getSong()->playMode() != Song::Mode_PlayPattern &&
|
||||
if( isMuted() || ( Engine::getSong()->playMode() != Song::Mode_PlayMidiClip &&
|
||||
n && n->isBbTrackMuted() ) || ! m_instrument )
|
||||
{
|
||||
return;
|
||||
@@ -651,9 +651,9 @@ void InstrumentTrack::updatePitchRange()
|
||||
|
||||
|
||||
|
||||
void InstrumentTrack::updateEffectChannel()
|
||||
void InstrumentTrack::updateMixerChannel()
|
||||
{
|
||||
m_audioPort.setNextFxChannel( m_effectChannelModel.value() );
|
||||
m_audioPort.setNextMixerChannel( m_mixerChannelModel.value() );
|
||||
}
|
||||
|
||||
|
||||
@@ -679,7 +679,7 @@ void InstrumentTrack::removeMidiPortNode( DataFile & _dataFile )
|
||||
|
||||
|
||||
bool InstrumentTrack::play( const TimePos & _start, const fpp_t _frames,
|
||||
const f_cnt_t _offset, int _tco_num )
|
||||
const f_cnt_t _offset, int _clip_num )
|
||||
{
|
||||
if( ! m_instrument || ! tryLock() )
|
||||
{
|
||||
@@ -687,20 +687,20 @@ bool InstrumentTrack::play( const TimePos & _start, const fpp_t _frames,
|
||||
}
|
||||
const float frames_per_tick = Engine::framesPerTick();
|
||||
|
||||
tcoVector tcos;
|
||||
clipVector clips;
|
||||
::BBTrack * bb_track = nullptr;
|
||||
if( _tco_num >= 0 )
|
||||
if( _clip_num >= 0 )
|
||||
{
|
||||
TrackContentObject * tco = getTCO( _tco_num );
|
||||
tcos.push_back( tco );
|
||||
Clip * clip = getClip( _clip_num );
|
||||
clips.push_back( clip );
|
||||
if (trackContainer() == (TrackContainer*)Engine::getBBTrackContainer())
|
||||
{
|
||||
bb_track = BBTrack::findBBTrack( _tco_num );
|
||||
bb_track = BBTrack::findBBTrack( _clip_num );
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
getTCOsInRange( tcos, _start, _start + static_cast<int>(
|
||||
getClipsInRange( clips, _start, _start + static_cast<int>(
|
||||
_frames / frames_per_tick ) );
|
||||
}
|
||||
|
||||
@@ -711,7 +711,7 @@ bool InstrumentTrack::play( const TimePos & _start, const fpp_t _frames,
|
||||
( *it )->processTimePos( _start );
|
||||
}
|
||||
|
||||
if ( tcos.size() == 0 )
|
||||
if ( clips.size() == 0 )
|
||||
{
|
||||
unlock();
|
||||
return false;
|
||||
@@ -719,25 +719,25 @@ bool InstrumentTrack::play( const TimePos & _start, const fpp_t _frames,
|
||||
|
||||
bool played_a_note = false; // will be return variable
|
||||
|
||||
for( tcoVector::Iterator it = tcos.begin(); it != tcos.end(); ++it )
|
||||
for( clipVector::Iterator it = clips.begin(); it != clips.end(); ++it )
|
||||
{
|
||||
Pattern* p = dynamic_cast<Pattern*>( *it );
|
||||
// everything which is not a pattern won't be played
|
||||
// A pattern playing in the Piano Roll window will always play
|
||||
if(p == nullptr ||
|
||||
(Engine::getSong()->playMode() != Song::Mode_PlayPattern
|
||||
MidiClip* c = dynamic_cast<MidiClip*>( *it );
|
||||
// everything which is not a MIDI clip won't be played
|
||||
// A MIDI clip playing in the Piano Roll window will always play
|
||||
if(c == nullptr ||
|
||||
(Engine::getSong()->playMode() != Song::Mode_PlayMidiClip
|
||||
&& (*it)->isMuted()))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
TimePos cur_start = _start;
|
||||
if( _tco_num < 0 )
|
||||
if( _clip_num < 0 )
|
||||
{
|
||||
cur_start -= p->startPosition();
|
||||
cur_start -= c->startPosition();
|
||||
}
|
||||
|
||||
// get all notes from the given pattern...
|
||||
const NoteVector & notes = p->notes();
|
||||
// get all notes from the given clip...
|
||||
const NoteVector & notes = c->notes();
|
||||
// ...and set our index to zero
|
||||
NoteVector::ConstIterator nit = notes.begin();
|
||||
|
||||
@@ -764,11 +764,11 @@ bool InstrumentTrack::play( const TimePos & _start, const fpp_t _frames,
|
||||
NotePlayHandle* notePlayHandle = NotePlayHandleManager::acquire( this, _offset, note_frames, *cur_note );
|
||||
notePlayHandle->setBBTrack( bb_track );
|
||||
// are we playing global song?
|
||||
if( _tco_num < 0 )
|
||||
if( _clip_num < 0 )
|
||||
{
|
||||
// then set song-global offset of pattern in order to
|
||||
// then set song-global offset of clip in order to
|
||||
// properly perform the note detuning
|
||||
notePlayHandle->setSongGlobalParentOffset( p->startPosition() );
|
||||
notePlayHandle->setSongGlobalParentOffset( c->startPosition() );
|
||||
}
|
||||
|
||||
Engine::audioEngine()->addPlayHandle( notePlayHandle );
|
||||
@@ -783,9 +783,9 @@ bool InstrumentTrack::play( const TimePos & _start, const fpp_t _frames,
|
||||
|
||||
|
||||
|
||||
TrackContentObject* InstrumentTrack::createTCO(const TimePos & pos)
|
||||
Clip* InstrumentTrack::createClip(const TimePos & pos)
|
||||
{
|
||||
Pattern* p = new Pattern(this);
|
||||
MidiClip* p = new MidiClip(this);
|
||||
p->movePosition(pos);
|
||||
return p;
|
||||
}
|
||||
@@ -808,7 +808,7 @@ void InstrumentTrack::saveTrackSpecificSettings( QDomDocument& doc, QDomElement
|
||||
m_pitchModel.saveSettings( doc, thisElement, "pitch" );
|
||||
m_pitchRangeModel.saveSettings( doc, thisElement, "pitchrange" );
|
||||
|
||||
m_effectChannelModel.saveSettings( doc, thisElement, "fxch" );
|
||||
m_mixerChannelModel.saveSettings( doc, thisElement, "mixch" );
|
||||
m_baseNoteModel.saveSettings( doc, thisElement, "basenote" );
|
||||
m_firstKeyModel.saveSettings(doc, thisElement, "firstkey");
|
||||
m_lastKeyModel.saveSettings(doc, thisElement, "lastkey");
|
||||
@@ -871,10 +871,10 @@ void InstrumentTrack::loadTrackSpecificSettings( const QDomElement & thisElement
|
||||
m_panningModel.loadSettings( thisElement, "pan" );
|
||||
m_pitchRangeModel.loadSettings( thisElement, "pitchrange" );
|
||||
m_pitchModel.loadSettings( thisElement, "pitch" );
|
||||
m_effectChannelModel.setRange( 0, Engine::fxMixer()->numChannels()-1 );
|
||||
m_mixerChannelModel.setRange( 0, Engine::mixer()->numChannels()-1 );
|
||||
if ( !m_previewMode )
|
||||
{
|
||||
m_effectChannelModel.loadSettings( thisElement, "fxch" );
|
||||
m_mixerChannelModel.loadSettings( thisElement, "mixch" );
|
||||
}
|
||||
m_baseNoteModel.loadSettings( thisElement, "basenote" );
|
||||
m_firstKeyModel.loadSettings(thisElement, "firstkey");
|
||||
@@ -943,7 +943,7 @@ void InstrumentTrack::loadTrackSpecificSettings( const QDomElement & thisElement
|
||||
// compat code - if node-name doesn't match any known
|
||||
// one, we assume that it is an instrument-plugin
|
||||
// which we'll try to load
|
||||
else if(AutomationPattern::classNodeName() != node.nodeName() &&
|
||||
else if(AutomationClip::classNodeName() != node.nodeName() &&
|
||||
ControllerConnection::classNodeName() != node.nodeName() &&
|
||||
!node.toElement().hasAttribute( "id" ))
|
||||
{
|
||||
@@ -981,14 +981,24 @@ void InstrumentTrack::setPreviewMode( const bool value )
|
||||
|
||||
void InstrumentTrack::replaceInstrument(DataFile dataFile)
|
||||
{
|
||||
// loadSettings clears the FX channel, so we save it here and set it back later
|
||||
int effectChannel = effectChannelModel()->value();
|
||||
// loadSettings clears the mixer channel, so we save it here and set it back later
|
||||
int mixerChannel = mixerChannelModel()->value();
|
||||
|
||||
InstrumentTrack::removeMidiPortNode(dataFile);
|
||||
setSimpleSerializing();
|
||||
|
||||
//Replacing an instrument shouldn't change the solo/mute state.
|
||||
bool oldMute = isMuted();
|
||||
bool oldSolo = isSolo();
|
||||
bool oldMutedBeforeSolo = isMutedBeforeSolo();
|
||||
|
||||
loadSettings(dataFile.content().toElement());
|
||||
|
||||
m_effectChannelModel.setValue(effectChannel);
|
||||
setMuted(oldMute);
|
||||
setSolo(oldSolo);
|
||||
setMutedBeforeSolo(oldMutedBeforeSolo);
|
||||
|
||||
m_mixerChannelModel.setValue(mixerChannel);
|
||||
Engine::getSong()->setModified();
|
||||
}
|
||||
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Pattern.cpp - implementation of class pattern which holds notes
|
||||
* MidiClip.cpp - implementation of class MidiClip, which holds notes
|
||||
*
|
||||
* Copyright (c) 2004-2014 Tobias Doerffel <tobydox/at/users.sourceforge.net>
|
||||
* Copyright (c) 2005-2007 Danny McRae <khjklujn/at/yahoo.com>
|
||||
@@ -23,7 +23,7 @@
|
||||
*
|
||||
*/
|
||||
|
||||
#include "Pattern.h"
|
||||
#include "MidiClip.h"
|
||||
|
||||
#include "BBTrackContainer.h"
|
||||
#include "GuiApplication.h"
|
||||
@@ -33,17 +33,17 @@
|
||||
#include <limits>
|
||||
|
||||
|
||||
QPixmap * PatternView::s_stepBtnOn0 = nullptr;
|
||||
QPixmap * PatternView::s_stepBtnOn200 = nullptr;
|
||||
QPixmap * PatternView::s_stepBtnOff = nullptr;
|
||||
QPixmap * PatternView::s_stepBtnOffLight = nullptr;
|
||||
QPixmap * MidiClipView::s_stepBtnOn0 = nullptr;
|
||||
QPixmap * MidiClipView::s_stepBtnOn200 = nullptr;
|
||||
QPixmap * MidiClipView::s_stepBtnOff = nullptr;
|
||||
QPixmap * MidiClipView::s_stepBtnOffLight = nullptr;
|
||||
|
||||
|
||||
|
||||
Pattern::Pattern( InstrumentTrack * _instrument_track ) :
|
||||
TrackContentObject( _instrument_track ),
|
||||
MidiClip::MidiClip( InstrumentTrack * _instrument_track ) :
|
||||
Clip( _instrument_track ),
|
||||
m_instrumentTrack( _instrument_track ),
|
||||
m_patternType( BeatPattern ),
|
||||
m_clipType( BeatClip ),
|
||||
m_steps( TimePos::stepsPerBar() )
|
||||
{
|
||||
if( _instrument_track->trackContainer()
|
||||
@@ -58,10 +58,10 @@ Pattern::Pattern( InstrumentTrack * _instrument_track ) :
|
||||
|
||||
|
||||
|
||||
Pattern::Pattern( const Pattern& other ) :
|
||||
TrackContentObject( other.m_instrumentTrack ),
|
||||
MidiClip::MidiClip( const MidiClip& other ) :
|
||||
Clip( other.m_instrumentTrack ),
|
||||
m_instrumentTrack( other.m_instrumentTrack ),
|
||||
m_patternType( other.m_patternType ),
|
||||
m_clipType( other.m_clipType ),
|
||||
m_steps( other.m_steps )
|
||||
{
|
||||
for( NoteVector::ConstIterator it = other.m_notes.begin(); it != other.m_notes.end(); ++it )
|
||||
@@ -85,9 +85,9 @@ Pattern::Pattern( const Pattern& other ) :
|
||||
}
|
||||
|
||||
|
||||
Pattern::~Pattern()
|
||||
MidiClip::~MidiClip()
|
||||
{
|
||||
emit destroyedPattern( this );
|
||||
emit destroyedMidiClip( this );
|
||||
|
||||
for( NoteVector::Iterator it = m_notes.begin();
|
||||
it != m_notes.end(); ++it )
|
||||
@@ -101,7 +101,7 @@ Pattern::~Pattern()
|
||||
|
||||
|
||||
|
||||
void Pattern::resizeToFirstTrack()
|
||||
void MidiClip::resizeToFirstTrack()
|
||||
{
|
||||
// Resize this track to be the same as existing tracks in the BB
|
||||
const TrackContainer::TrackList & tracks =
|
||||
@@ -112,10 +112,10 @@ void Pattern::resizeToFirstTrack()
|
||||
{
|
||||
if(tracks.at(trackID) != m_instrumentTrack)
|
||||
{
|
||||
unsigned int currentTCO = m_instrumentTrack->
|
||||
getTCOs().indexOf(this);
|
||||
m_steps = static_cast<Pattern *>
|
||||
(tracks.at(trackID)->getTCO(currentTCO))
|
||||
unsigned int currentClip = m_instrumentTrack->
|
||||
getClips().indexOf(this);
|
||||
m_steps = static_cast<MidiClip *>
|
||||
(tracks.at(trackID)->getClip(currentClip))
|
||||
->m_steps;
|
||||
}
|
||||
break;
|
||||
@@ -126,7 +126,7 @@ void Pattern::resizeToFirstTrack()
|
||||
|
||||
|
||||
|
||||
void Pattern::init()
|
||||
void MidiClip::init()
|
||||
{
|
||||
connect( Engine::getSong(), SIGNAL( timeSignatureChanged( int, int ) ),
|
||||
this, SLOT( changeTimeSignature() ) );
|
||||
@@ -139,11 +139,11 @@ void Pattern::init()
|
||||
|
||||
|
||||
|
||||
void Pattern::updateLength()
|
||||
void MidiClip::updateLength()
|
||||
{
|
||||
if( m_patternType == BeatPattern )
|
||||
if( m_clipType == BeatClip )
|
||||
{
|
||||
changeLength( beatPatternLength() );
|
||||
changeLength( beatClipLength() );
|
||||
updateBBTrack();
|
||||
return;
|
||||
}
|
||||
@@ -167,7 +167,7 @@ void Pattern::updateLength()
|
||||
|
||||
|
||||
|
||||
TimePos Pattern::beatPatternLength() const
|
||||
TimePos MidiClip::beatClipLength() const
|
||||
{
|
||||
tick_t max_length = TimePos::ticksPerBar();
|
||||
|
||||
@@ -193,7 +193,7 @@ TimePos Pattern::beatPatternLength() const
|
||||
|
||||
|
||||
|
||||
Note * Pattern::addNote( const Note & _new_note, const bool _quant_pos )
|
||||
Note * MidiClip::addNote( const Note & _new_note, const bool _quant_pos )
|
||||
{
|
||||
Note * new_note = new Note( _new_note );
|
||||
if( _quant_pos && getGUI()->pianoRoll() )
|
||||
@@ -216,7 +216,7 @@ Note * Pattern::addNote( const Note & _new_note, const bool _quant_pos )
|
||||
|
||||
|
||||
|
||||
void Pattern::removeNote( Note * _note_to_del )
|
||||
void MidiClip::removeNote( Note * _note_to_del )
|
||||
{
|
||||
instrumentTrack()->lock();
|
||||
NoteVector::Iterator it = m_notes.begin();
|
||||
@@ -241,7 +241,7 @@ void Pattern::removeNote( Note * _note_to_del )
|
||||
|
||||
// returns a pointer to the note at specified step, or NULL if note doesn't exist
|
||||
|
||||
Note * Pattern::noteAtStep( int _step )
|
||||
Note * MidiClip::noteAtStep( int _step )
|
||||
{
|
||||
for( NoteVector::Iterator it = m_notes.begin(); it != m_notes.end();
|
||||
++it )
|
||||
@@ -257,7 +257,7 @@ Note * Pattern::noteAtStep( int _step )
|
||||
|
||||
|
||||
|
||||
void Pattern::rearrangeAllNotes()
|
||||
void MidiClip::rearrangeAllNotes()
|
||||
{
|
||||
// sort notes by start time
|
||||
std::sort(m_notes.begin(), m_notes.end(), Note::lessThan);
|
||||
@@ -265,7 +265,7 @@ void Pattern::rearrangeAllNotes()
|
||||
|
||||
|
||||
|
||||
void Pattern::clearNotes()
|
||||
void MidiClip::clearNotes()
|
||||
{
|
||||
instrumentTrack()->lock();
|
||||
for( NoteVector::Iterator it = m_notes.begin(); it != m_notes.end();
|
||||
@@ -283,7 +283,7 @@ void Pattern::clearNotes()
|
||||
|
||||
|
||||
|
||||
Note * Pattern::addStepNote( int step )
|
||||
Note * MidiClip::addStepNote( int step )
|
||||
{
|
||||
return addNote( Note( TimePos( -DefaultTicksPerBar ),
|
||||
TimePos::stepPosition( step ) ), false );
|
||||
@@ -292,7 +292,7 @@ Note * Pattern::addStepNote( int step )
|
||||
|
||||
|
||||
|
||||
void Pattern::setStep( int step, bool enabled )
|
||||
void MidiClip::setStep( int step, bool enabled )
|
||||
{
|
||||
if( enabled )
|
||||
{
|
||||
@@ -312,7 +312,7 @@ void Pattern::setStep( int step, bool enabled )
|
||||
|
||||
|
||||
|
||||
void Pattern::splitNotes(NoteVector notes, TimePos pos)
|
||||
void MidiClip::splitNotes(NoteVector notes, TimePos pos)
|
||||
{
|
||||
if (notes.empty()) { return; }
|
||||
|
||||
@@ -346,47 +346,47 @@ void Pattern::splitNotes(NoteVector notes, TimePos pos)
|
||||
|
||||
|
||||
|
||||
void Pattern::setType( PatternTypes _new_pattern_type )
|
||||
void MidiClip::setType( MidiClipTypes _new_clip_type )
|
||||
{
|
||||
if( _new_pattern_type == BeatPattern ||
|
||||
_new_pattern_type == MelodyPattern )
|
||||
if( _new_clip_type == BeatClip ||
|
||||
_new_clip_type == MelodyClip )
|
||||
{
|
||||
m_patternType = _new_pattern_type;
|
||||
m_clipType = _new_clip_type;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
void Pattern::checkType()
|
||||
void MidiClip::checkType()
|
||||
{
|
||||
NoteVector::Iterator it = m_notes.begin();
|
||||
while( it != m_notes.end() )
|
||||
{
|
||||
if( ( *it )->length() > 0 )
|
||||
{
|
||||
setType( MelodyPattern );
|
||||
setType( MelodyClip );
|
||||
return;
|
||||
}
|
||||
++it;
|
||||
}
|
||||
setType( BeatPattern );
|
||||
setType( BeatClip );
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
void Pattern::saveSettings( QDomDocument & _doc, QDomElement & _this )
|
||||
void MidiClip::saveSettings( QDomDocument & _doc, QDomElement & _this )
|
||||
{
|
||||
_this.setAttribute( "type", m_patternType );
|
||||
_this.setAttribute( "type", m_clipType );
|
||||
_this.setAttribute( "name", name() );
|
||||
|
||||
if( usesCustomClipColor() )
|
||||
{
|
||||
_this.setAttribute( "color", color().name() );
|
||||
}
|
||||
// as the target of copied/dragged pattern is always an existing
|
||||
// pattern, we must not store actual position, instead we store -1
|
||||
// as the target of copied/dragged MIDI clip is always an existing
|
||||
// MIDI clip, we must not store actual position, instead we store -1
|
||||
// which tells loadSettings() not to mess around with position
|
||||
if( _this.parentNode().nodeName() == "clipboard" ||
|
||||
_this.parentNode().nodeName() == "dnddata" )
|
||||
@@ -411,9 +411,9 @@ void Pattern::saveSettings( QDomDocument & _doc, QDomElement & _this )
|
||||
|
||||
|
||||
|
||||
void Pattern::loadSettings( const QDomElement & _this )
|
||||
void MidiClip::loadSettings( const QDomElement & _this )
|
||||
{
|
||||
m_patternType = static_cast<PatternTypes>( _this.attribute( "type"
|
||||
m_clipType = static_cast<MidiClipTypes>( _this.attribute( "type"
|
||||
).toInt() );
|
||||
setName( _this.attribute( "name" ) );
|
||||
|
||||
@@ -466,33 +466,33 @@ void Pattern::loadSettings( const QDomElement & _this )
|
||||
|
||||
|
||||
|
||||
Pattern * Pattern::previousPattern() const
|
||||
MidiClip * MidiClip::previousMidiClip() const
|
||||
{
|
||||
return adjacentPatternByOffset(-1);
|
||||
return adjacentMidiClipByOffset(-1);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
Pattern * Pattern::nextPattern() const
|
||||
MidiClip * MidiClip::nextMidiClip() const
|
||||
{
|
||||
return adjacentPatternByOffset(1);
|
||||
return adjacentMidiClipByOffset(1);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
Pattern * Pattern::adjacentPatternByOffset(int offset) const
|
||||
MidiClip * MidiClip::adjacentMidiClipByOffset(int offset) const
|
||||
{
|
||||
QVector<TrackContentObject *> tcos = m_instrumentTrack->getTCOs();
|
||||
int tcoNum = m_instrumentTrack->getTCONum(this);
|
||||
return dynamic_cast<Pattern*>(tcos.value(tcoNum + offset, nullptr));
|
||||
QVector<Clip *> clips = m_instrumentTrack->getClips();
|
||||
int clipNum = m_instrumentTrack->getClipNum(this);
|
||||
return dynamic_cast<MidiClip*>(clips.value(clipNum + offset, nullptr));
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
void Pattern::clear()
|
||||
void MidiClip::clear()
|
||||
{
|
||||
addJournalCheckPoint();
|
||||
clearNotes();
|
||||
@@ -501,14 +501,14 @@ void Pattern::clear()
|
||||
|
||||
|
||||
|
||||
void Pattern::addSteps()
|
||||
void MidiClip::addSteps()
|
||||
{
|
||||
m_steps += TimePos::stepsPerBar();
|
||||
updateLength();
|
||||
emit dataChanged();
|
||||
}
|
||||
|
||||
void Pattern::cloneSteps()
|
||||
void MidiClip::cloneSteps()
|
||||
{
|
||||
int oldLength = m_steps;
|
||||
m_steps *= 2; // cloning doubles the track
|
||||
@@ -532,7 +532,7 @@ void Pattern::cloneSteps()
|
||||
|
||||
|
||||
|
||||
void Pattern::removeSteps()
|
||||
void MidiClip::removeSteps()
|
||||
{
|
||||
int n = TimePos::stepsPerBar();
|
||||
if( n < m_steps )
|
||||
@@ -550,15 +550,15 @@ void Pattern::removeSteps()
|
||||
|
||||
|
||||
|
||||
TrackContentObjectView * Pattern::createView( TrackView * _tv )
|
||||
ClipView * MidiClip::createView( TrackView * _tv )
|
||||
{
|
||||
return new PatternView( this, _tv );
|
||||
return new MidiClipView( this, _tv );
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
void Pattern::updateBBTrack()
|
||||
void MidiClip::updateBBTrack()
|
||||
{
|
||||
if( getTrack()->trackContainer() == Engine::getBBTrackContainer() )
|
||||
{
|
||||
@@ -567,7 +567,7 @@ void Pattern::updateBBTrack()
|
||||
|
||||
if( getGUI() != nullptr
|
||||
&& getGUI()->pianoRoll()
|
||||
&& getGUI()->pianoRoll()->currentPattern() == this )
|
||||
&& getGUI()->pianoRoll()->currentMidiClip() == this )
|
||||
{
|
||||
getGUI()->pianoRoll()->update();
|
||||
}
|
||||
@@ -576,7 +576,7 @@ void Pattern::updateBBTrack()
|
||||
|
||||
|
||||
|
||||
bool Pattern::empty()
|
||||
bool MidiClip::empty()
|
||||
{
|
||||
for( NoteVector::ConstIterator it = m_notes.begin();
|
||||
it != m_notes.end(); ++it )
|
||||
@@ -592,7 +592,7 @@ bool Pattern::empty()
|
||||
|
||||
|
||||
|
||||
void Pattern::changeTimeSignature()
|
||||
void MidiClip::changeTimeSignature()
|
||||
{
|
||||
TimePos last_pos = TimePos::ticksPerBar() - 1;
|
||||
for( NoteVector::ConstIterator cit = m_notes.begin();
|
||||
@@ -608,4 +608,4 @@ void Pattern::changeTimeSignature()
|
||||
m_steps = qMax<tick_t>( TimePos::stepsPerBar(),
|
||||
last_pos.getBar() * TimePos::stepsPerBar() );
|
||||
updateLength();
|
||||
}
|
||||
}
|
||||
@@ -38,15 +38,15 @@ SampleTrack::SampleTrack(TrackContainer* tc) :
|
||||
Track(Track::SampleTrack, tc),
|
||||
m_volumeModel(DefaultVolume, MinVolume, MaxVolume, 0.1f, this, tr("Volume")),
|
||||
m_panningModel(DefaultPanning, PanningLeft, PanningRight, 0.1f, this, tr("Panning")),
|
||||
m_effectChannelModel(0, 0, 0, this, tr("FX channel")),
|
||||
m_mixerChannelModel(0, 0, 0, this, tr("Mixer channel")),
|
||||
m_audioPort(tr("Sample track"), true, &m_volumeModel, &m_panningModel, &m_mutedModel),
|
||||
m_isPlaying(false)
|
||||
{
|
||||
setName(tr("Sample track"));
|
||||
m_panningModel.setCenterValue(DefaultPanning);
|
||||
m_effectChannelModel.setRange(0, Engine::fxMixer()->numChannels()-1, 1);
|
||||
m_mixerChannelModel.setRange(0, Engine::mixer()->numChannels()-1, 1);
|
||||
|
||||
connect(&m_effectChannelModel, SIGNAL(dataChanged()), this, SLOT(updateEffectChannel()));
|
||||
connect(&m_mixerChannelModel, SIGNAL(dataChanged()), this, SLOT(updateMixerChannel()));
|
||||
}
|
||||
|
||||
|
||||
@@ -61,16 +61,16 @@ SampleTrack::~SampleTrack()
|
||||
|
||||
|
||||
bool SampleTrack::play( const TimePos & _start, const fpp_t _frames,
|
||||
const f_cnt_t _offset, int _tco_num )
|
||||
const f_cnt_t _offset, int _clip_num )
|
||||
{
|
||||
m_audioPort.effects()->startRunning();
|
||||
bool played_a_note = false; // will be return variable
|
||||
bool played_a_note = false; // will be return variable
|
||||
|
||||
tcoVector tcos;
|
||||
clipVector clips;
|
||||
::BBTrack * bb_track = nullptr;
|
||||
if( _tco_num >= 0 )
|
||||
if( _clip_num >= 0 )
|
||||
{
|
||||
if (_start > getTCO(_tco_num)->length())
|
||||
if (_start > getClip(_clip_num)->length())
|
||||
{
|
||||
setPlaying(false);
|
||||
}
|
||||
@@ -78,63 +78,63 @@ bool SampleTrack::play( const TimePos & _start, const fpp_t _frames,
|
||||
{
|
||||
return false;
|
||||
}
|
||||
tcos.push_back( getTCO( _tco_num ) );
|
||||
clips.push_back( getClip( _clip_num ) );
|
||||
if (trackContainer() == (TrackContainer*)Engine::getBBTrackContainer())
|
||||
{
|
||||
bb_track = BBTrack::findBBTrack( _tco_num );
|
||||
bb_track = BBTrack::findBBTrack( _clip_num );
|
||||
setPlaying(true);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
bool nowPlaying = false;
|
||||
for( int i = 0; i < numOfTCOs(); ++i )
|
||||
for( int i = 0; i < numOfClips(); ++i )
|
||||
{
|
||||
TrackContentObject * tco = getTCO( i );
|
||||
SampleTCO * sTco = dynamic_cast<SampleTCO*>( tco );
|
||||
Clip * clip = getClip( i );
|
||||
SampleClip * sClip = dynamic_cast<SampleClip*>( clip );
|
||||
|
||||
if( _start >= sTco->startPosition() && _start < sTco->endPosition() )
|
||||
if( _start >= sClip->startPosition() && _start < sClip->endPosition() )
|
||||
{
|
||||
if(!sTco->isPlaying() && (_start >= (sTco->startPosition() + sTco->startTimeOffset())
|
||||
|| sTco->isRecord()))
|
||||
if(!sClip->isPlaying() && (_start >= (sClip->startPosition() + sClip->startTimeOffset())
|
||||
|| sClip->isRecord()))
|
||||
{
|
||||
auto bufferFramesPerTick = Engine::framesPerTick (sTco->sampleBuffer ()->sampleRate ());
|
||||
f_cnt_t sampleStart = bufferFramesPerTick * ( _start - sTco->startPosition() - sTco->startTimeOffset() );
|
||||
f_cnt_t tcoFrameLength = bufferFramesPerTick * ( sTco->endPosition() - sTco->startPosition() - sTco->startTimeOffset() );
|
||||
f_cnt_t sampleBufferLength = sTco->sampleBuffer()->frames();
|
||||
//if the Tco smaller than the sample length we play only until Tco end
|
||||
auto bufferFramesPerTick = Engine::framesPerTick (sClip->sampleBuffer ()->sampleRate ());
|
||||
f_cnt_t sampleStart = bufferFramesPerTick * ( _start - sClip->startPosition() - sClip->startTimeOffset() );
|
||||
f_cnt_t clipFrameLength = bufferFramesPerTick * ( sClip->endPosition() - sClip->startPosition() - sClip->startTimeOffset() );
|
||||
f_cnt_t sampleBufferLength = sClip->sampleBuffer()->frames();
|
||||
//if the Clip smaller than the sample length we play only until Clip end
|
||||
//else we play the sample to the end but nothing more
|
||||
f_cnt_t samplePlayLength = tcoFrameLength > sampleBufferLength ? sampleBufferLength : tcoFrameLength;
|
||||
f_cnt_t samplePlayLength = clipFrameLength > sampleBufferLength ? sampleBufferLength : clipFrameLength;
|
||||
|
||||
// In case we are recoding, "play" the whole TCO.
|
||||
if(sTco->isRecord()) {
|
||||
samplePlayLength = tcoFrameLength;
|
||||
if(sClip->isRecord()) {
|
||||
samplePlayLength = clipFrameLength;
|
||||
}
|
||||
|
||||
//we only play within the sampleBuffer limits
|
||||
//Ignore that in case of recoding.
|
||||
if(sampleStart < sampleBufferLength || sTco->isRecord ())
|
||||
if(sampleStart < sampleBufferLength || sClip->isRecord ())
|
||||
{
|
||||
sTco->setSampleStartFrame(sampleStart);
|
||||
sTco->setSamplePlayLength(samplePlayLength);
|
||||
tcos.push_back(sTco);
|
||||
sTco->setIsPlaying(true);
|
||||
sClip->setSampleStartFrame(sampleStart);
|
||||
sClip->setSamplePlayLength(samplePlayLength);
|
||||
clips.push_back(sClip);
|
||||
sClip->setIsPlaying(true);
|
||||
nowPlaying = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
sTco->setIsPlaying( false );
|
||||
sClip->setIsPlaying( false );
|
||||
}
|
||||
nowPlaying = nowPlaying || sTco->isPlaying();
|
||||
nowPlaying = nowPlaying || sClip->isPlaying();
|
||||
}
|
||||
setPlaying(nowPlaying);
|
||||
}
|
||||
|
||||
for( tcoVector::Iterator it = tcos.begin(); it != tcos.end(); ++it )
|
||||
for( clipVector::Iterator it = clips.begin(); it != clips.end(); ++it )
|
||||
{
|
||||
SampleTCO * st = dynamic_cast<SampleTCO *>( *it );
|
||||
SampleClip * st = dynamic_cast<SampleClip *>( *it );
|
||||
if( !st->isMuted() )
|
||||
{
|
||||
PlayHandle* handle;
|
||||
@@ -174,11 +174,11 @@ TrackView * SampleTrack::createView( TrackContainerView* tcv )
|
||||
|
||||
|
||||
|
||||
TrackContentObject * SampleTrack::createTCO(const TimePos & pos)
|
||||
Clip * SampleTrack::createClip(const TimePos & pos)
|
||||
{
|
||||
SampleTCO * sTco = new SampleTCO(this);
|
||||
sTco->movePosition(pos);
|
||||
return sTco;
|
||||
SampleClip * sClip = new SampleClip(this);
|
||||
sClip->movePosition(pos);
|
||||
return sClip;
|
||||
}
|
||||
|
||||
|
||||
@@ -193,7 +193,7 @@ void SampleTrack::saveTrackSpecificSettings( QDomDocument & _doc,
|
||||
#endif
|
||||
m_volumeModel.saveSettings( _doc, _this, "vol" );
|
||||
m_panningModel.saveSettings( _doc, _this, "pan" );
|
||||
m_effectChannelModel.saveSettings( _doc, _this, "fxch" );
|
||||
m_mixerChannelModel.saveSettings( _doc, _this, "mixch" );
|
||||
}
|
||||
|
||||
|
||||
@@ -216,36 +216,36 @@ void SampleTrack::loadTrackSpecificSettings( const QDomElement & _this )
|
||||
}
|
||||
m_volumeModel.loadSettings( _this, "vol" );
|
||||
m_panningModel.loadSettings( _this, "pan" );
|
||||
m_effectChannelModel.setRange( 0, Engine::fxMixer()->numChannels() - 1 );
|
||||
m_effectChannelModel.loadSettings( _this, "fxch" );
|
||||
m_mixerChannelModel.setRange( 0, Engine::mixer()->numChannels() - 1 );
|
||||
m_mixerChannelModel.loadSettings( _this, "mixch" );
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
void SampleTrack::updateTcos()
|
||||
void SampleTrack::updateClips()
|
||||
{
|
||||
Engine::audioEngine()->removePlayHandlesOfTypes( this, PlayHandle::TypeSamplePlayHandle );
|
||||
setPlayingTcos( false );
|
||||
setPlayingClips( false );
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
void SampleTrack::setPlayingTcos( bool isPlaying )
|
||||
void SampleTrack::setPlayingClips( bool isPlaying )
|
||||
{
|
||||
for( int i = 0; i < numOfTCOs(); ++i )
|
||||
for( int i = 0; i < numOfClips(); ++i )
|
||||
{
|
||||
TrackContentObject * tco = getTCO( i );
|
||||
SampleTCO * sTco = dynamic_cast<SampleTCO*>( tco );
|
||||
sTco->setIsPlaying( isPlaying );
|
||||
Clip * clip = getClip( i );
|
||||
SampleClip * sClip = dynamic_cast<SampleClip*>( clip );
|
||||
sClip->setIsPlaying( isPlaying );
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
void SampleTrack::updateEffectChannel()
|
||||
void SampleTrack::updateMixerChannel()
|
||||
{
|
||||
m_audioPort.setNextFxChannel( m_effectChannelModel.value() );
|
||||
}
|
||||
m_audioPort.setNextMixerChannel( m_mixerChannelModel.value() );
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user