Pattern: removed freeze functionality

Since addition of automation, controllers etc. the freeze functionality
has been rather broken and thus adds no value anymore. In order to not
confuse users with broken functionality, remove it at all.

Closes #345.
This commit is contained in:
Tobias Doerffel
2014-02-19 19:07:47 +01:00
parent 7d965e251c
commit 8b84526dc5
9 changed files with 25 additions and 466 deletions

View File

@@ -30,7 +30,6 @@
#include "AutomatableModel.h"
class bbTrack;
class pattern;
class SampleTCO;
class track;
class AudioPort;
@@ -42,7 +41,6 @@ public:
SamplePlayHandle( const QString& sampleFile );
SamplePlayHandle( SampleBuffer* sampleBuffer );
SamplePlayHandle( SampleTCO* tco );
SamplePlayHandle( pattern * _pattern );
virtual ~SamplePlayHandle();
virtual inline bool affinityMatters() const

View File

@@ -42,7 +42,6 @@ class QProgressBar;
class QPushButton;
class InstrumentTrack;
class patternFreezeThread;
class SampleBuffer;
@@ -93,22 +92,6 @@ public:
void checkType();
// functions which are part of freezing-feature
inline bool isFreezing() const
{
return m_freezing;
}
inline bool isFrozen() const
{
return m_frozenPattern != NULL;
}
SampleBuffer *frozenPattern()
{
return m_frozenPattern;
}
// settings-management
virtual void saveSettings( QDomDocument & _doc, QDomElement & _parent );
virtual void loadSettings( const QDomElement & _this );
@@ -140,9 +123,6 @@ protected slots:
void addSteps();
void removeSteps();
void clear();
void freeze();
void unfreeze();
void abortFreeze();
void changeTimeSignature();
@@ -155,14 +135,7 @@ private:
NoteVector m_notes;
int m_steps;
// pattern freezing
SampleBuffer* m_frozenPattern;
bool m_freezing;
volatile bool m_freezeAborted;
friend class patternView;
friend class patternFreezeThread;
friend class bbEditor;
} ;
@@ -206,7 +179,6 @@ private:
static QPixmap * s_stepBtnOverlay;
static QPixmap * s_stepBtnOff;
static QPixmap * s_stepBtnOffLight;
static QPixmap * s_frozen;
pattern * m_pat;
QPixmap m_paintPixmap;
@@ -216,64 +188,4 @@ private:
// TODO: move to own header-files
//
class patternFreezeStatusDialog : public QDialog
{
Q_OBJECT
public:
patternFreezeStatusDialog( QThread * _thread );
virtual ~patternFreezeStatusDialog();
void setProgress( int _p );
protected:
void closeEvent( QCloseEvent * _ce );
protected slots:
void cancelBtnClicked();
void updateProgress();
private:
QProgressBar * m_progressBar;
QPushButton * m_cancelBtn;
QThread * m_freezeThread;
int m_progress;
signals:
void aborted();
} ;
class patternFreezeThread : public QThread
{
public:
patternFreezeThread( pattern * _pattern );
virtual ~patternFreezeThread();
protected:
virtual void run();
private:
pattern * m_pattern;
patternFreezeStatusDialog * m_statusDlg;
} ;
#endif

View File

@@ -150,8 +150,6 @@ public:
return m_playing == false && m_paused == false;
}
bool isFreezingPattern() const;
inline bool isExporting() const
{
return m_exporting;
@@ -167,8 +165,6 @@ public:
return m_recording;
}
bool realTimeTask() const;
inline bool isExportDone() const
{
if ( m_exportLoop )

View File

@@ -114,35 +114,33 @@ void FxMixer::processChannel( fx_ch_t _ch, sampleFrame * _buf )
_buf = m_fxChannels[_ch]->m_buffer;
}
const fpp_t f = engine::mixer()->framesPerPeriod();
if( !engine::getSong()->isFreezingPattern() )
// only start effects if sound was mixed to this FX channel before
if( m_fxChannels[_ch]->m_used )
{
// only start effects if sound was mixed to this FX channel before
if( m_fxChannels[_ch]->m_used )
{
m_fxChannels[_ch]->m_fxChain.startRunning();
}
// process FX chain
m_fxChannels[_ch]->m_stillRunning = m_fxChannels[_ch]->m_fxChain.processAudioBuffer( _buf, f, m_fxChannels[_ch]->m_used );
float peakLeft = engine::mixer()->peakValueLeft( _buf, f ) * m_fxChannels[_ch]->m_volumeModel.value();
float peakRight = engine::mixer()->peakValueRight( _buf, f ) * m_fxChannels[_ch]->m_volumeModel.value();
if( peakLeft > m_fxChannels[_ch]->m_peakLeft )
{
m_fxChannels[_ch]->m_peakLeft = peakLeft;
}
if( peakRight > m_fxChannels[_ch]->m_peakRight )
{
m_fxChannels[_ch]->m_peakRight = peakRight;
}
m_fxChannels[_ch]->m_fxChain.startRunning();
}
// process FX chain
m_fxChannels[_ch]->m_stillRunning = m_fxChannels[_ch]->m_fxChain.processAudioBuffer( _buf, f, m_fxChannels[_ch]->m_used );
float peakLeft = engine::mixer()->peakValueLeft( _buf, f ) * m_fxChannels[_ch]->m_volumeModel.value();
float peakRight = engine::mixer()->peakValueRight( _buf, f ) * m_fxChannels[_ch]->m_volumeModel.value();
if( peakLeft > m_fxChannels[_ch]->m_peakLeft )
{
m_fxChannels[_ch]->m_peakLeft = peakLeft;
}
if( peakRight > m_fxChannels[_ch]->m_peakRight )
{
m_fxChannels[_ch]->m_peakRight = peakRight;
}
m_fxChannels[_ch]->m_used = true;
}
else
{
m_fxChannels[_ch]->m_peakLeft =
m_fxChannels[_ch]->m_peakRight = 0.0f;
m_fxChannels[_ch]->m_peakLeft = m_fxChannels[_ch]->m_peakRight = 0.0f;
}
}

View File

@@ -512,7 +512,7 @@ sample_rate_t Mixer::processingSampleRate() const
bool Mixer::criticalXRuns() const
{
return m_cpuLoad >= 99 && engine::getSong()->realTimeTask() == true;
return m_cpuLoad >= 99 && engine::getSong()->isExporting() == false;
}

View File

@@ -84,23 +84,6 @@ SamplePlayHandle::SamplePlayHandle( SampleTCO* tco ) :
SamplePlayHandle::SamplePlayHandle( pattern * _pattern ) :
PlayHandle( TypeSamplePlayHandle ),
m_sampleBuffer( sharedObject::ref( _pattern->frozenPattern() ) ),
m_doneMayReturnTrue( true ),
m_frame( 0 ),
m_audioPort( _pattern->instrumentTrack()->audioPort() ),
m_ownAudioPort( false ),
m_defaultVolumeModel( DefaultVolume, MinVolume, MaxVolume, 1 ),
m_volumeModel( &m_defaultVolumeModel ),
m_track( _pattern->instrumentTrack() ),
m_bbTrack( NULL )
{
}
SamplePlayHandle::~SamplePlayHandle()
{
sharedObject::unref( m_sampleBuffer );

View File

@@ -246,9 +246,7 @@ void song::processNextBuffer()
// check for looping-mode and act if necessary
timeLine * tl = m_playPos[m_playMode].m_timeLine;
bool check_loop = tl != NULL && m_exporting == false &&
tl->loopPointsEnabled() &&
!( m_playMode == Mode_PlayPattern &&
m_patternToPlay->isFreezing() == true );
tl->loopPointsEnabled();
if( check_loop )
{
if( m_playPos[m_playMode] < tl->loopBegin() ||
@@ -386,27 +384,6 @@ void song::processNextBuffer()
bool song::isFreezingPattern() const
{
return isPlaying() &&
m_playMode == Mode_PlayPattern &&
m_patternToPlay != NULL &&
m_patternToPlay->isFreezing();
}
bool song::realTimeTask() const
{
return !( m_exporting == true || ( m_playMode == Mode_PlayPattern &&
m_patternToPlay != NULL &&
m_patternToPlay->isFreezing() == true ) );
}
void song::playSong()
{
m_recording = false;

View File

@@ -602,21 +602,6 @@ bool InstrumentTrack::play( const MidiTime & _start, const fpp_t _frames,
{
cur_start -= p->startPosition();
}
if( p->isFrozen() && !engine::getSong()->isExporting() )
{
if( cur_start > 0 )
{
continue;
}
SamplePlayHandle* handle = new SamplePlayHandle( p );
handle->setBBTrack( bb_track );
handle->setOffset( _offset );
// send it to the mixer
engine::mixer()->addPlayHandle( handle );
played_a_note = true;
continue;
}
// get all notes from the given pattern...
const NoteVector & notes = p->notes();

View File

@@ -55,7 +55,6 @@ QPixmap * patternView::s_stepBtnOn = NULL;
QPixmap * patternView::s_stepBtnOverlay = NULL;
QPixmap * patternView::s_stepBtnOff = NULL;
QPixmap * patternView::s_stepBtnOffLight = NULL;
QPixmap * patternView::s_frozen = NULL;
@@ -63,10 +62,7 @@ pattern::pattern( InstrumentTrack * _instrument_track ) :
trackContentObject( _instrument_track ),
m_instrumentTrack( _instrument_track ),
m_patternType( BeatPattern ),
m_steps( MidiTime::stepsPerTact() ),
m_frozenPattern( NULL ),
m_freezing( false ),
m_freezeAborted( false )
m_steps( MidiTime::stepsPerTact() )
{
setName( _instrument_track->name() );
init();
@@ -79,9 +75,7 @@ pattern::pattern( const pattern & _pat_to_copy ) :
trackContentObject( _pat_to_copy.m_instrumentTrack ),
m_instrumentTrack( _pat_to_copy.m_instrumentTrack ),
m_patternType( _pat_to_copy.m_patternType ),
m_steps( _pat_to_copy.m_steps ),
m_frozenPattern( NULL ),
m_freezeAborted( false )
m_steps( _pat_to_copy.m_steps )
{
for( NoteVector::ConstIterator it = _pat_to_copy.m_notes.begin();
it != _pat_to_copy.m_notes.end(); ++it )
@@ -102,11 +96,6 @@ pattern::~pattern()
}
m_notes.clear();
if( m_frozenPattern )
{
sharedObject::unref( m_frozenPattern );
}
}
@@ -358,7 +347,6 @@ void pattern::saveSettings( QDomDocument & _doc, QDomElement & _this )
_this.setAttribute( "len", length() );
_this.setAttribute( "muted", isMuted() );
_this.setAttribute( "steps", m_steps );
_this.setAttribute( "frozen", m_frozenPattern != NULL );
// now save settings of all notes
for( NoteVector::Iterator it = m_notes.begin();
@@ -376,8 +364,6 @@ void pattern::saveSettings( QDomDocument & _doc, QDomElement & _this )
void pattern::loadSettings( const QDomElement & _this )
{
unfreeze();
m_patternType = static_cast<PatternTypes>( _this.attribute( "type"
).toInt() );
setName( _this.attribute( "name" ) );
@@ -414,10 +400,6 @@ void pattern::loadSettings( const QDomElement & _this )
ensureBeatNotes();
checkType();
/* if( _this.attribute( "frozen" ).toInt() )
{
freeze();
}*/
emit dataChanged();
@@ -436,55 +418,6 @@ void pattern::clear()
void pattern::freeze()
{
if( engine::getSong()->isPlaying() )
{
QMessageBox::information( 0, tr( "Cannot freeze pattern" ),
tr( "The pattern currently "
"cannot be freezed "
"because you're in "
"play-mode. Please "
"stop and try again!" ),
QMessageBox::Ok );
return;
}
// already frozen?
if( m_frozenPattern != NULL )
{
// then unfreeze, before freezing it again
unfreeze();
}
new patternFreezeThread( this );
}
void pattern::unfreeze()
{
if( m_frozenPattern != NULL )
{
sharedObject::unref( m_frozenPattern );
m_frozenPattern = NULL;
emit dataChanged();
}
}
void pattern::abortFreeze()
{
m_freezeAborted = true;
}
void pattern::addSteps()
{
m_steps += MidiTime::stepsPerTact();
@@ -624,183 +557,6 @@ void pattern::changeTimeSignature()
patternFreezeStatusDialog::patternFreezeStatusDialog( QThread * _thread ) :
QDialog(),
m_freezeThread( _thread ),
m_progress( 0 )
{
setWindowTitle( tr( "Freezing pattern..." ) );
setModal( true );
m_progressBar = new QProgressBar( this );
m_progressBar->setGeometry( 10, 10, 200, 24 );
m_progressBar->setMaximum( 100 );
m_progressBar->setTextVisible( false );
m_progressBar->show();
m_cancelBtn = new QPushButton( embed::getIconPixmap( "cancel" ),
tr( "Cancel" ), this );
m_cancelBtn->setGeometry( 50, 38, 120, 28 );
m_cancelBtn->show();
connect( m_cancelBtn, SIGNAL( clicked() ), this,
SLOT( cancelBtnClicked() ) );
show();
QTimer * update_timer = new QTimer( this );
connect( update_timer, SIGNAL( timeout() ),
this, SLOT( updateProgress() ) );
update_timer->start( 100 );
setAttribute( Qt::WA_DeleteOnClose, true );
connect( this, SIGNAL( aborted() ), this, SLOT( reject() ) );
}
patternFreezeStatusDialog::~patternFreezeStatusDialog()
{
m_freezeThread->wait();
delete m_freezeThread;
}
void patternFreezeStatusDialog::setProgress( int _p )
{
m_progress = _p;
}
void patternFreezeStatusDialog::closeEvent( QCloseEvent * _ce )
{
_ce->ignore();
cancelBtnClicked();
}
void patternFreezeStatusDialog::cancelBtnClicked()
{
emit( aborted() );
done( -1 );
}
void patternFreezeStatusDialog::updateProgress()
{
if( m_progress < 0 )
{
done( 0 );
}
else
{
m_progressBar->setValue( m_progress );
}
}
patternFreezeThread::patternFreezeThread( pattern * _pattern ) :
m_pattern( _pattern )
{
// create status-dialog
m_statusDlg = new patternFreezeStatusDialog( this );
QObject::connect( m_statusDlg, SIGNAL( aborted() ),
m_pattern, SLOT( abortFreeze() ) );
start();
}
patternFreezeThread::~patternFreezeThread()
{
m_pattern->dataChanged();
}
void patternFreezeThread::run()
{
// create and install audio-sample-recorder
bool b;
// we cannot create local copy, because at a later stage
// Mixer::restoreAudioDevice(...) deletes old audio-dev and thus
// AudioSampleRecorder would be destroyed two times...
AudioSampleRecorder * freeze_recorder = new AudioSampleRecorder(
DEFAULT_CHANNELS, b,
engine::mixer() );
engine::mixer()->setAudioDevice( freeze_recorder );
// prepare stuff for playing correct things later
engine::getSong()->playPattern( m_pattern, false );
song::playPos & ppp = engine::getSong()->getPlayPos(
song::Mode_PlayPattern );
ppp.setTicks( 0 );
ppp.setCurrentFrame( 0 );
ppp.m_timeLineUpdate = false;
m_pattern->m_freezeAborted = false;
m_pattern->m_freezing = true;
// now render everything
while( ppp < m_pattern->length() &&
m_pattern->m_freezeAborted == false )
{
freeze_recorder->processNextBuffer();
m_statusDlg->setProgress( ppp * 100 / m_pattern->length() );
}
m_statusDlg->setProgress( 100 );
// render tails
int count = 0;
while( engine::mixer()->hasNotePlayHandles() &&
m_pattern->m_freezeAborted == false &&
++count < 2000 )
{
freeze_recorder->processNextBuffer();
}
m_pattern->m_freezing = false;
// reset song-editor settings
engine::getSong()->stop();
ppp.m_timeLineUpdate = true;
// create final sample-buffer if freezing was successful
if( m_pattern->m_freezeAborted == false )
{
freeze_recorder->createSampleBuffer(
&m_pattern->m_frozenPattern );
}
// restore original audio-device
engine::mixer()->restoreAudioDevice();
m_statusDlg->setProgress( -1 ); // we're finished
}
patternView::patternView( pattern * _pattern, trackView * _parent ) :
trackContentObjectView( _pattern, _parent ),
@@ -832,11 +588,6 @@ patternView::patternView( pattern * _pattern, trackView * _parent ) :
"step_btn_off_light" ) );
}
if( s_frozen == NULL )
{
s_frozen = new QPixmap( embed::getIconPixmap( "frozen" ) );
}
setFixedHeight( parentWidget()->height() - 2 );
setAutoResizeEnabled( false );
@@ -931,26 +682,6 @@ void patternView::constructContextMenu( QMenu * _cm )
this, SLOT( changeName() ) );
_cm->addSeparator();
bool freeze_separator = false;
if( !( m_pat->m_instrumentTrack->isMuted() || m_pat->isMuted() ) )
{
_cm->addAction( embed::getIconPixmap( "freeze" ),
m_pat->m_frozenPattern ? tr( "Refreeze" ) :
tr( "Freeze" ),
m_pat, SLOT( freeze() ) );
freeze_separator = true;
}
if( m_pat->m_frozenPattern )
{
_cm->addAction( embed::getIconPixmap( "unfreeze" ),
tr( "Unfreeze" ), m_pat, SLOT( unfreeze() ) );
freeze_separator = true;
}
if( freeze_separator )
{
_cm->addSeparator();
}
_cm->addAction( embed::getIconPixmap( "step_btn_add" ),
tr( "Add steps" ), m_pat, SLOT( addSteps() ) );
_cm->addAction( embed::getIconPixmap( "step_btn_remove" ),
@@ -1010,16 +741,6 @@ void patternView::mousePressEvent( QMouseEvent * _me )
engine::getPianoRoll()->update();
}
}
else if( m_pat->m_frozenPattern != NULL &&
_me->button() == Qt::LeftButton &&
_me->modifiers() & Qt::ShiftModifier )
{
QString s;
new stringPairDrag( "sampledata",
m_pat->m_frozenPattern->toBase64( s ),
embed::getIconPixmap( "freeze" ),
this );
}
else
{
trackContentObjectView::mousePressEvent( _me );
@@ -1170,10 +891,6 @@ void patternView::paintEvent( QPaintEvent * )
{
p.setPen( QColor( 160, 160, 160 ) );
}
else if( m_pat->m_frozenPattern != NULL )
{
p.setPen( QColor( 0x70, 0xFF, 0xFF ) );
}
else
{
p.setPen( QColor( 0x77, 0xC7, 0xD8 ) );
@@ -1284,13 +1001,6 @@ void patternView::paintEvent( QPaintEvent * )
p.drawPixmap( 3, p.fontMetrics().height() + 1,
embed::getIconPixmap( "muted", 16, 16 ) );
}
else if( m_pat->m_frozenPattern != NULL )
{
p.setBrush( QBrush() );
p.setPen( QColor( 0x70, 255, 255 ) );
p.drawRect( 0, 0, width()-1, height() - 1 );
p.drawPixmap( 3, height() - s_frozen->height() - 4, *s_frozen );
}
p.end();