committed by
Oskar Wallgren
parent
5126070bb1
commit
b68c5ee5b5
@@ -103,8 +103,6 @@ public:
|
||||
|
||||
} ;
|
||||
|
||||
|
||||
|
||||
void processNextBuffer();
|
||||
|
||||
inline int getLoadingTrackCount() const
|
||||
@@ -203,9 +201,23 @@ public:
|
||||
{
|
||||
return m_recording;
|
||||
}
|
||||
|
||||
inline void setLoopRenderCount(int count)
|
||||
{
|
||||
if (count < 1)
|
||||
m_loopRenderCount = 1;
|
||||
else
|
||||
m_loopRenderCount = count;
|
||||
m_loopRenderRemaining = m_loopRenderCount;
|
||||
}
|
||||
|
||||
inline int getLoopRenderCount() const
|
||||
{
|
||||
return m_loopRenderCount;
|
||||
}
|
||||
|
||||
bool isExportDone() const;
|
||||
std::pair<MidiTime, MidiTime> getExportEndpoints() const;
|
||||
int getExportProgress() const;
|
||||
|
||||
inline void setRenderBetweenMarkers( bool renderBetweenMarkers )
|
||||
{
|
||||
@@ -424,7 +436,14 @@ private:
|
||||
tact_t m_elapsedTacts;
|
||||
|
||||
VstSyncController m_vstSyncController;
|
||||
|
||||
|
||||
int m_loopRenderCount;
|
||||
int m_loopRenderRemaining;
|
||||
MidiTime m_exportSongBegin;
|
||||
MidiTime m_exportLoopBegin;
|
||||
MidiTime m_exportLoopEnd;
|
||||
MidiTime m_exportSongEnd;
|
||||
MidiTime m_exportEffectiveLength;
|
||||
|
||||
friend class LmmsCore;
|
||||
friend class SongEditor;
|
||||
|
||||
@@ -185,25 +185,17 @@ void ProjectRenderer::run()
|
||||
// Skip first empty buffer.
|
||||
Engine::mixer()->nextBuffer();
|
||||
|
||||
const Song::PlayPos & exportPos = Engine::getSong()->getPlayPos(
|
||||
Song::Mode_PlaySong );
|
||||
m_progress = 0;
|
||||
std::pair<MidiTime, MidiTime> exportEndpoints = Engine::getSong()->getExportEndpoints();
|
||||
tick_t startTick = exportEndpoints.first.getTicks();
|
||||
tick_t endTick = exportEndpoints.second.getTicks();
|
||||
tick_t lengthTicks = endTick - startTick;
|
||||
|
||||
// Now start processing
|
||||
Engine::mixer()->startProcessing(false);
|
||||
|
||||
// Continually track and emit progress percentage to listeners.
|
||||
while( exportPos.getTicks() < endTick &&
|
||||
Engine::getSong()->isExporting() == true
|
||||
&& !m_abort )
|
||||
while (!Engine::getSong()->isExportDone() && !m_abort)
|
||||
{
|
||||
m_fileDev->processNextBuffer();
|
||||
const int nprog = lengthTicks == 0 ? 100 : (exportPos.getTicks()-startTick) * 100 / lengthTicks;
|
||||
if( m_progress != nprog )
|
||||
const int nprog = Engine::getSong()->getExportProgress();
|
||||
if (m_progress != nprog)
|
||||
{
|
||||
m_progress = nprog;
|
||||
emit progressChanged( m_progress );
|
||||
|
||||
@@ -86,7 +86,9 @@ Song::Song() :
|
||||
m_patternToPlay( NULL ),
|
||||
m_loopPattern( false ),
|
||||
m_elapsedTicks( 0 ),
|
||||
m_elapsedTacts( 0 )
|
||||
m_elapsedTacts( 0 ),
|
||||
m_loopRenderCount(1),
|
||||
m_loopRenderRemaining(1)
|
||||
{
|
||||
for(int i = 0; i < Mode_Count; ++i) m_elapsedMilliSeconds[i] = 0;
|
||||
connect( &m_tempoModel, SIGNAL( dataChanged() ),
|
||||
@@ -330,7 +332,7 @@ void Song::processNextBuffer()
|
||||
}
|
||||
m_playPos[m_playMode].setTicks( ticks );
|
||||
|
||||
if( checkLoop )
|
||||
if (checkLoop || m_loopRenderRemaining > 1)
|
||||
{
|
||||
m_vstSyncController.startCycle(
|
||||
tl->loopBegin().getTicks(), tl->loopEnd().getTicks() );
|
||||
@@ -340,6 +342,8 @@ void Song::processNextBuffer()
|
||||
// beginning of the range
|
||||
if( m_playPos[m_playMode] >= tl->loopEnd() )
|
||||
{
|
||||
if (m_loopRenderRemaining > 1)
|
||||
m_loopRenderRemaining--;
|
||||
ticks = tl->loopBegin().getTicks();
|
||||
m_playPos[m_playMode].setTicks( ticks );
|
||||
setToTime(tl->loopBegin());
|
||||
@@ -476,29 +480,41 @@ void Song::setModified(bool value)
|
||||
}
|
||||
}
|
||||
|
||||
std::pair<MidiTime, MidiTime> Song::getExportEndpoints() const
|
||||
bool Song::isExportDone() const
|
||||
{
|
||||
if ( m_renderBetweenMarkers )
|
||||
return !isExporting() || m_playPos[m_playMode] >= m_exportSongEnd;
|
||||
}
|
||||
|
||||
int Song::getExportProgress() const
|
||||
{
|
||||
MidiTime pos = m_playPos[m_playMode];
|
||||
|
||||
if (pos >= m_exportSongEnd)
|
||||
{
|
||||
return std::pair<MidiTime, MidiTime>(
|
||||
m_playPos[Mode_PlaySong].m_timeLine->loopBegin(),
|
||||
m_playPos[Mode_PlaySong].m_timeLine->loopEnd()
|
||||
);
|
||||
return 100;
|
||||
}
|
||||
else if ( m_exportLoop )
|
||||
else if (pos <= m_exportSongBegin)
|
||||
{
|
||||
return std::pair<MidiTime, MidiTime>( MidiTime(0, 0), MidiTime(m_length, 0) );
|
||||
return 0;
|
||||
}
|
||||
else if (pos >= m_exportLoopEnd)
|
||||
{
|
||||
pos = (m_exportLoopBegin-m_exportSongBegin) + (m_exportLoopEnd - m_exportLoopBegin) *
|
||||
m_loopRenderCount + (pos - m_exportLoopEnd);
|
||||
}
|
||||
else if ( pos >= m_exportLoopBegin )
|
||||
{
|
||||
pos = (m_exportLoopBegin-m_exportSongBegin) + ((m_exportLoopEnd - m_exportLoopBegin) *
|
||||
(m_loopRenderCount - m_loopRenderRemaining)) + (pos - m_exportLoopBegin);
|
||||
}
|
||||
else
|
||||
{
|
||||
// if not exporting as a loop, we leave one bar of padding at the end of the song to accomodate reverb, etc.
|
||||
return std::pair<MidiTime, MidiTime>( MidiTime(0, 0), MidiTime(m_length+1, 0) );
|
||||
pos = (pos - m_exportSongBegin);
|
||||
}
|
||||
|
||||
return (float)pos/(float)m_exportEffectiveLength*100.0f;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
void Song::playSong()
|
||||
{
|
||||
m_recording = false;
|
||||
@@ -719,15 +735,41 @@ void Song::stop()
|
||||
void Song::startExport()
|
||||
{
|
||||
stop();
|
||||
if(m_renderBetweenMarkers)
|
||||
if (m_renderBetweenMarkers)
|
||||
{
|
||||
m_exportSongBegin = m_exportLoopBegin = m_playPos[Mode_PlaySong].m_timeLine->loopBegin();
|
||||
m_exportSongEnd = m_exportLoopEnd = m_playPos[Mode_PlaySong].m_timeLine->loopEnd();
|
||||
|
||||
m_playPos[Mode_PlaySong].setTicks( m_playPos[Mode_PlaySong].m_timeLine->loopBegin().getTicks() );
|
||||
}
|
||||
else
|
||||
{
|
||||
m_exportSongEnd = MidiTime(m_length, 0);
|
||||
|
||||
// Handle potentially ridiculous loop points gracefully.
|
||||
if (m_loopRenderCount > 1 && m_playPos[Mode_PlaySong].m_timeLine->loopEnd() > m_exportSongEnd)
|
||||
{
|
||||
m_exportSongEnd = m_playPos[Mode_PlaySong].m_timeLine->loopEnd();
|
||||
}
|
||||
|
||||
if (!m_exportLoop)
|
||||
m_exportSongEnd += MidiTime(1,0);
|
||||
|
||||
m_exportSongBegin = MidiTime(0,0);
|
||||
m_exportLoopBegin = m_playPos[Mode_PlaySong].m_timeLine->loopBegin() < m_exportSongEnd &&
|
||||
m_playPos[Mode_PlaySong].m_timeLine->loopEnd() <= m_exportSongEnd ?
|
||||
m_playPos[Mode_PlaySong].m_timeLine->loopBegin() : MidiTime(0,0);
|
||||
m_exportLoopEnd = m_playPos[Mode_PlaySong].m_timeLine->loopBegin() < m_exportSongEnd &&
|
||||
m_playPos[Mode_PlaySong].m_timeLine->loopEnd() <= m_exportSongEnd ?
|
||||
m_playPos[Mode_PlaySong].m_timeLine->loopEnd() : MidiTime(0,0);
|
||||
|
||||
m_playPos[Mode_PlaySong].setTicks( 0 );
|
||||
}
|
||||
|
||||
m_exportEffectiveLength = (m_exportLoopBegin - m_exportSongBegin) + (m_exportLoopEnd - m_exportLoopBegin)
|
||||
* m_loopRenderCount + (m_exportSongEnd - m_exportLoopEnd);
|
||||
m_loopRenderRemaining = m_loopRenderCount;
|
||||
|
||||
playSong();
|
||||
|
||||
m_exporting = true;
|
||||
|
||||
@@ -128,6 +128,7 @@ void ExportProjectDialog::accept()
|
||||
|
||||
void ExportProjectDialog::closeEvent( QCloseEvent * _ce )
|
||||
{
|
||||
Engine::getSong()->setLoopRenderCount(1);
|
||||
if( m_renderManager ) {
|
||||
m_renderManager->abortProcessing();
|
||||
}
|
||||
@@ -187,6 +188,7 @@ void ExportProjectDialog::startExport()
|
||||
|
||||
Engine::getSong()->setExportLoop( exportLoopCB->isChecked() );
|
||||
Engine::getSong()->setRenderBetweenMarkers( renderMarkersCB->isChecked() );
|
||||
Engine::getSong()->setLoopRenderCount(loopCountSB->value());
|
||||
|
||||
connect( m_renderManager.get(), SIGNAL( progressChanged( int ) ),
|
||||
progressBar, SLOT( setValue( int ) ) );
|
||||
|
||||
@@ -7,19 +7,19 @@
|
||||
<x>0</x>
|
||||
<y>0</y>
|
||||
<width>379</width>
|
||||
<height>374</height>
|
||||
<height>400</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="minimumSize">
|
||||
<size>
|
||||
<width>379</width>
|
||||
<height>374</height>
|
||||
<height>400</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="maximumSize">
|
||||
<size>
|
||||
<width>379</width>
|
||||
<height>374</height>
|
||||
<height>400</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="windowTitle">
|
||||
@@ -40,6 +40,47 @@
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QWidget" name="loopRepeatWidget" native="true">
|
||||
<layout class="QHBoxLayout" name="loopRepeatHL">
|
||||
<property name="leftMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="topMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="rightMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="bottomMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<item>
|
||||
<widget class="QLabel" name="labelLoopRepeat">
|
||||
<property name="text">
|
||||
<string>Render Looped Section:</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QSpinBox" name="loopCountSB">
|
||||
<property name="suffix">
|
||||
<string> time(s)</string>
|
||||
</property>
|
||||
<property name="minimum">
|
||||
<number>1</number>
|
||||
</property>
|
||||
<property name="maximum">
|
||||
<number>99</number>
|
||||
</property>
|
||||
<property name="value">
|
||||
<number>1</number>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<layout class="QHBoxLayout">
|
||||
<item>
|
||||
|
||||
Reference in New Issue
Block a user