From 1800af3c186e1efd17bf7b28efa6e797cf52cb9f Mon Sep 17 00:00:00 2001
From: devin <devin@devin-studio.(none)>
Date: Mon, 29 Oct 2012 17:26:08 -0500
Subject: [PATCH 529/530] my changes


Signed-off-by: devin <devin@devin-studio.(none)>
---
 include/export_project_dialog.h   |   20 +++--
 include/song.h                    |    3 +-
 src/core/ProjectRenderer.cpp      |    6 +-
 src/core/song.cpp                 |   65 +++++++++------
 src/gui/MainWindow.cpp            |    6 ++
 src/gui/export_project_dialog.cpp |  166 ++++++++++++++++++++++++++++---------
 6 files changed, 193 insertions(+), 73 deletions(-)

diff --git a/include/export_project_dialog.h b/include/export_project_dialog.h
index 266b9f9..944e5fe 100644
--- a/include/export_project_dialog.h
+++ b/include/export_project_dialog.h
@@ -28,17 +28,17 @@
 #define _EXPORT_PROJECT_DIALOG_H
 
 #include <QtGui/QDialog>
-
+#include <vector>
 #include "ui_export_project.h"
 
-class ProjectRenderer;
+#include "ProjectRenderer.h"
 
 
 class exportProjectDialog : public QDialog, public Ui::ExportProjectDialog
 {
 	Q_OBJECT
 public:
-	exportProjectDialog( const QString & _file_name, QWidget * _parent );
+	exportProjectDialog( const QString & _file_name, QWidget * _parent, bool multi_export );
 	virtual ~exportProjectDialog();
 
 
@@ -50,12 +50,20 @@ protected:
 private slots:
 	void startBtnClicked( void );
 	void updateTitleBar( int );
-
+	void render(ProjectRenderer* renderer);
+	void multi_render();
+	ProjectRenderer* prep_render();
+	void pop_render();
+    void accept();
 
 private:
 	QString m_fileName;
-	ProjectRenderer * m_renderer;
-
+	QString m_dirName;
+	std::vector<ProjectRenderer*> m_renderers;
+	bool m_multi_export;
+	std::vector<track*> m_unmuted;
+	ProjectRenderer::ExportFileFormats m_ft;
+	std::vector<track*> m_to_render_vec;
 } ;
 
 #endif
diff --git a/include/song.h b/include/song.h
index 3b12971..6eafefa 100644
--- a/include/song.h
+++ b/include/song.h
@@ -207,7 +207,8 @@ public slots:
 	void resumeFromPause();
 
 	void importProject();
-	void exportProject();
+	void exportProject(bool multiExport=false);
+	void exportProjectTracks();
 
 	void startExport();
 	void stopExport();
diff --git a/src/core/ProjectRenderer.cpp b/src/core/ProjectRenderer.cpp
index 37de20e..89f3f46 100644
--- a/src/core/ProjectRenderer.cpp
+++ b/src/core/ProjectRenderer.cpp
@@ -35,7 +35,7 @@
 #ifdef LMMS_HAVE_SCHED_H
 #include <sched.h>
 #endif
-
+#include <QMutexLocker>
 
 FileEncodeDevice __fileEncodeDevices[] =
 {
@@ -126,6 +126,7 @@ ProjectRenderer::ExportFileFormats ProjectRenderer::getFileFormatFromExtension(
 
 void ProjectRenderer::startProcessing()
 {
+
 	if( isReady() )
 	{
 		// have to do mixer stuff with GUI-thread-affinity in order to
@@ -139,11 +140,11 @@ void ProjectRenderer::startProcessing()
 			QThread::HighPriority
 #endif
 						);
+
 	}
 }
 
 
-
 void ProjectRenderer::run()
 {
 #if 0
@@ -157,6 +158,7 @@ void ProjectRenderer::run()
 #endif
 #endif
 
+
 	engine::getSong()->startExport();
 
 	song::playPos & pp = engine::getSong()->getPlayPos(
diff --git a/src/core/song.cpp b/src/core/song.cpp
index 8962e73..75f4f2e 100644
--- a/src/core/song.cpp
+++ b/src/core/song.cpp
@@ -60,7 +60,8 @@
 #include "templates.h"
 #include "text_float.h"
 #include "timeline.h"
-
+#include <vector>
+using namespace std;
 
 tick_t midiTime::s_ticksPerTact = DefaultTicksPerTact;
 
@@ -1136,9 +1137,12 @@ void song::restoreControllerStates( const QDomElement & _this )
 }
 
 
+void song::exportProjectTracks()
+{
+	exportProject(true);
+}
 
-
-void song::exportProject()
+void song::exportProject(bool multiExport)
 {
 	if( isEmpty() )
 	{
@@ -1151,38 +1155,51 @@ void song::exportProject()
 	}
 
 	QFileDialog efd( engine::mainWindow() );
-	efd.setFileMode( QFileDialog::AnyFile );
-	efd.setAcceptMode( QFileDialog::AcceptSave );
-	int idx = 0;
-	QStringList types;
-	while( __fileEncodeDevices[idx].m_fileFormat !=
-					ProjectRenderer::NumFileFormats )
+	if (multiExport)
 	{
-		types << tr( __fileEncodeDevices[idx].m_description );
-		++idx;
-	}
-	efd.setFilters( types );
-
-	QString base_filename;
-	if( !m_fileName.isEmpty() )
-	{
-		efd.setDirectory( QFileInfo( m_fileName ).absolutePath() );
-		base_filename = QFileInfo( m_fileName ).completeBaseName();
+		efd.setFileMode( QFileDialog::Directory);
+		efd.setWindowTitle( tr( "Select directory for writing exported tracks..." ) );
+		if( !m_fileName.isEmpty() )
+		{
+			efd.setDirectory( QFileInfo( m_fileName ).absolutePath() );
+		}
 	}
 	else
 	{
-		efd.setDirectory( configManager::inst()->userProjectsDir() );
-		base_filename = tr( "untitled" );
+		efd.setFileMode( QFileDialog::AnyFile );
+		int idx = 0;
+		QStringList types;
+		while( __fileEncodeDevices[idx].m_fileFormat !=
+						ProjectRenderer::NumFileFormats )
+		{
+			types << tr( __fileEncodeDevices[idx].m_description );
+			++idx;
+		}
+		efd.setFilters( types );
+		QString base_filename;
+		if( !m_fileName.isEmpty() )
+		{
+			efd.setDirectory( QFileInfo( m_fileName ).absolutePath() );
+			base_filename = QFileInfo( m_fileName ).completeBaseName();
+		}
+		else
+		{
+			efd.setDirectory( configManager::inst()->userProjectsDir() );
+			base_filename = tr( "untitled" );
+		}
+		efd.selectFile( base_filename + __fileEncodeDevices[0].m_extension );
+		efd.setWindowTitle( tr( "Select file for project-export..." ) );
 	}
-	efd.selectFile( base_filename + __fileEncodeDevices[0].m_extension );
-	efd.setWindowTitle( tr( "Select file for project-export..." ) );
+
+	efd.setAcceptMode( QFileDialog::AcceptSave );
+
 
 	if( efd.exec() == QDialog::Accepted &&
 		!efd.selectedFiles().isEmpty() && !efd.selectedFiles()[0].isEmpty() )
 	{
 		const QString export_file_name = efd.selectedFiles()[0];
 		exportProjectDialog epd( export_file_name,
-						engine::mainWindow() );
+						engine::mainWindow(), multiExport );
 		epd.exec();
 	}
 }
diff --git a/src/gui/MainWindow.cpp b/src/gui/MainWindow.cpp
index 4966ff1..262ef41 100644
--- a/src/gui/MainWindow.cpp
+++ b/src/gui/MainWindow.cpp
@@ -255,6 +255,12 @@ void MainWindow::finalize( void )
 					engine::getSong(),
 					SLOT( exportProject() ),
 					Qt::CTRL + Qt::Key_E );
+	project_menu->addAction( embed::getIconPixmap( "project_export" ),
+					tr( "E&xport tracks..." ),
+					engine::getSong(),
+					SLOT( exportProjectTracks() ),
+					Qt::CTRL + Qt::Key_E );
+
 	project_menu->addSeparator();
 	project_menu->addAction( embed::getIconPixmap( "exit" ), tr( "&Quit" ),
 					qApp, SLOT( closeAllWindows() ),
diff --git a/src/gui/export_project_dialog.cpp b/src/gui/export_project_dialog.cpp
index c3804ea..a0bb876 100644
--- a/src/gui/export_project_dialog.cpp
+++ b/src/gui/export_project_dialog.cpp
@@ -23,20 +23,21 @@
  */
 
 #include <QtCore/QFileInfo>
+#include <QtCore/QDir>
 #include <QtGui/QMessageBox>
 
 #include "export_project_dialog.h"
+#include "song.h"
 #include "engine.h"
 #include "MainWindow.h"
-#include "ProjectRenderer.h"
 
 
 exportProjectDialog::exportProjectDialog( const QString & _file_name,
-							QWidget * _parent ) :
+							QWidget * _parent, bool multi_export=false ) :
 	QDialog( _parent ),
 	Ui::ExportProjectDialog(),
 	m_fileName( _file_name ),
-	m_renderer( NULL )
+	m_multi_export(multi_export)
 {
 	setupUi( this );
 	setWindowTitle( tr( "Export project to %1" ).arg( 
@@ -83,7 +84,12 @@ exportProjectDialog::exportProjectDialog( const QString & _file_name,
 
 exportProjectDialog::~exportProjectDialog()
 {
-	delete m_renderer;
+
+	for( std::vector<ProjectRenderer*>::const_iterator it = m_renderers.begin();
+							it != m_renderers.end(); ++it )
+	{
+		delete (*it);
+	}
 }
 
 
@@ -91,13 +97,31 @@ exportProjectDialog::~exportProjectDialog()
 
 void exportProjectDialog::reject()
 {
-	if( m_renderer == NULL )
+	for( std::vector<ProjectRenderer*>::const_iterator it = m_renderers.begin();
+							it != m_renderers.end(); ++it )
 	{
-		accept();
+		(*it)->abortProcessing();
+	}
+}
+void exportProjectDialog::accept()
+{
+	// If more to render, kick off next render job
+	if (m_renderers.size() > 0)
+	{
+		pop_render( );
 	}
 	else
 	{
-		m_renderer->abortProcessing();
+		// If done, then reset mute states
+		while(!m_unmuted.empty())
+		{
+			track* restore_track = m_unmuted.back();
+			m_unmuted.pop_back();
+			restore_track->setMuted(false);
+		}
+
+		QDialog::accept();
+
 	}
 }
 
@@ -106,19 +130,106 @@ void exportProjectDialog::reject()
 
 void exportProjectDialog::closeEvent( QCloseEvent * _ce )
 {
-	if( m_renderer != NULL && m_renderer->isRunning() )
+	for( std::vector<ProjectRenderer*>::const_iterator it = m_renderers.begin();
+							it != m_renderers.end(); ++it )
 	{
-		m_renderer->abortProcessing();
+		if( (*it)->isRunning() )
+		{
+			(*it)->abortProcessing();
+		}
 	}
 	QDialog::closeEvent( _ce );
 }
 
+void exportProjectDialog::pop_render() {
 
+	track* render_track = m_to_render_vec.back();
+	m_to_render_vec.pop_back();
 
+	for (std::vector<track*>::const_iterator it = m_unmuted.begin();
+			it != m_unmuted.end(); ++it) {
+		if ((*it) == render_track) {
+			(*it)->setMuted(false);
+		} else {
+			(*it)->setMuted(true);
+		}
+	}
+
+	// Pop next render job and start
+	ProjectRenderer* r = m_renderers.back();
+	m_renderers.pop_back();
+	render(r);
+}
+
+void exportProjectDialog::multi_render()
+{
+	m_dirName = m_fileName;
+	QString path = QDir(m_fileName).filePath("text.txt");
+	std::string strTest = path.toStdString();
+
+	const trackContainer::trackList & tl = engine::getSong()->tracks();
+
+	// Check for all unmuted tracks.  Remember list.
+	int x = 0;
+	for( trackContainer::trackList::const_iterator it = tl.begin();
+							it != tl.end(); ++it )
+	{
+		// Don't mute automation tracks
+		if (! (*it)->isMuted() && (*it)->nodeName() != "automationtrack")
+		{
+			m_unmuted.push_back((*it));
+			QString nextName = (*it)->name();
+			nextName = nextName.remove(QRegExp("[^a-zA-Z]"));
+			QString name = QString("%1_%2.wav").arg(x++).arg(nextName);
+			m_fileName = QDir(m_dirName).filePath(name);
+			std::string strTest = m_fileName.toStdString();
+			prep_render();
+		}
+	}
+
+	m_to_render_vec = m_unmuted;
+
+	pop_render( );
+}
+
+ProjectRenderer* exportProjectDialog::prep_render(
+		) {
+	mixer::qualitySettings qs =
+			mixer::qualitySettings(
+					static_cast<mixer::qualitySettings::Interpolation>(interpolationCB->currentIndex()),
+					static_cast<mixer::qualitySettings::Oversampling>(oversamplingCB->currentIndex()),
+					sampleExactControllersCB->isChecked(),
+					aliasFreeOscillatorsCB->isChecked());
+	ProjectRenderer::OutputSettings os = ProjectRenderer::OutputSettings(
+			samplerateCB->currentText().section(" ", 0, 0).toUInt(), false,
+			bitrateCB->currentText().section(" ", 0, 0).toUInt(),
+			static_cast<ProjectRenderer::Depths>(depthCB->currentIndex()));
+	ProjectRenderer* renderer = new ProjectRenderer(qs, os, m_ft, m_fileName);
+	m_renderers.push_back(renderer);
+	return renderer;
+}
+
+void exportProjectDialog::render(ProjectRenderer* renderer)
+{
+
+	if (renderer->isReady()) {
+		connect(renderer, SIGNAL( progressChanged( int ) ), progressBar,
+				SLOT( setValue( int ) ));
+		connect(renderer, SIGNAL( progressChanged( int ) ), this,
+				SLOT( updateTitleBar( int ) ));
+		connect(renderer, SIGNAL( finished() ), this, SLOT( accept() ));
+		connect(renderer, SIGNAL( finished() ), engine::mainWindow(),
+				SLOT( resetWindowTitle() ));
+
+		renderer->startProcessing();
+	} else {
+		accept();
+	}
+}
 
 void exportProjectDialog::startBtnClicked()
 {
-	ProjectRenderer::ExportFileFormats ft = ProjectRenderer::NumFileFormats;
+	m_ft = ProjectRenderer::NumFileFormats;
 
 	for( int i = 0; i < ProjectRenderer::NumFileFormats; ++i )
 	{
@@ -126,12 +237,12 @@ void exportProjectDialog::startBtnClicked()
 			ProjectRenderer::tr(
 				__fileEncodeDevices[i].m_description ) )
 		{
-			ft = __fileEncodeDevices[i].m_fileFormat;
+			m_ft = __fileEncodeDevices[i].m_fileFormat;
 			break;
 		}
 	}
 
-	if( ft == ProjectRenderer::NumFileFormats )
+	if( m_ft == ProjectRenderer::NumFileFormats )
 	{
 		QMessageBox::information( this, tr( "Error" ),
 			tr( "Error while determining file-encoder device. "
@@ -146,38 +257,13 @@ void exportProjectDialog::startBtnClicked()
 
 	updateTitleBar( 0 );
 
-	mixer::qualitySettings qs = mixer::qualitySettings(
-		static_cast<mixer::qualitySettings::Interpolation>(
-					interpolationCB->currentIndex() ),
-		static_cast<mixer::qualitySettings::Oversampling>(
-					oversamplingCB->currentIndex() ),
-					sampleExactControllersCB->isChecked(),
-					aliasFreeOscillatorsCB->isChecked() );
-
-	ProjectRenderer::OutputSettings os = ProjectRenderer::OutputSettings(
-		samplerateCB->currentText().section( " ", 0, 0 ).toUInt(),
-		false,
-		bitrateCB->currentText().section( " ", 0, 0 ).toUInt(),
-		static_cast<ProjectRenderer::Depths>(
-						depthCB->currentIndex() ) );
-
-	m_renderer = new ProjectRenderer( qs, os, ft, m_fileName );
-	if( m_renderer->isReady() )
+	if (m_multi_export==true)
 	{
-		connect( m_renderer, SIGNAL( progressChanged( int ) ),
-				progressBar, SLOT( setValue( int ) ) );
-		connect( m_renderer, SIGNAL( progressChanged( int ) ),
-				this, SLOT( updateTitleBar( int ) ) );
-		connect( m_renderer, SIGNAL( finished() ),
-				this, SLOT( accept() ) );
-		connect( m_renderer, SIGNAL( finished() ),
-			engine::mainWindow(), SLOT( resetWindowTitle() ) );
-
-		m_renderer->startProcessing();
+		multi_render();
 	}
 	else
 	{
-		accept();
+		render(prep_render());
 	}
 }
 
-- 
1.7.9.5

