Refactor ExportProjectDialog (#8215)
This refactors the export dialog to no longer use the export_project.ui file and moves it into standard C++ Qt code. This also brings minor changes to the dialog, such as horizontal labels instead of vertical ones.
This commit is contained in:
@@ -59,7 +59,8 @@ constexpr int BYTES_PER_FRAME = sizeof(SampleFrame);
|
||||
|
||||
constexpr float OUTPUT_SAMPLE_MULTIPLIER = 32767.0f;
|
||||
|
||||
constexpr auto SUPPORTED_SAMPLERATES = std::array{44100, 48000, 88200, 96000, 192000};
|
||||
constexpr auto SUPPORTED_SAMPLERATES = std::array{44100, 48000, 88200, 96000, 192000};
|
||||
constexpr auto SUPPORTED_BITRATES = std::array{64, 128, 160, 192, 256, 320};
|
||||
|
||||
class LMMS_EXPORT AudioEngine : public QObject
|
||||
{
|
||||
|
||||
@@ -27,45 +27,71 @@
|
||||
#define LMMS_GUI_EXPORT_PROJECT_DIALOG_H
|
||||
|
||||
#include <QDialog>
|
||||
#include <memory>
|
||||
#include "ui_export_project.h"
|
||||
|
||||
#include "ProjectRenderer.h"
|
||||
#include "RenderManager.h"
|
||||
|
||||
namespace lmms::gui
|
||||
{
|
||||
class QString;
|
||||
class QLabel;
|
||||
class QProgressBar;
|
||||
class QCheckBox;
|
||||
class QComboBox;
|
||||
class QSpinBox;
|
||||
class QFormLayout;
|
||||
class QGroupBox;
|
||||
|
||||
namespace lmms::gui {
|
||||
|
||||
class ExportProjectDialog : public QDialog, public Ui::ExportProjectDialog
|
||||
class ExportProjectDialog : public QDialog
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
ExportProjectDialog( const QString & _file_name, QWidget * _parent, bool multi_export );
|
||||
enum class Mode
|
||||
{
|
||||
ExportProject,
|
||||
ExportTracks,
|
||||
};
|
||||
|
||||
protected:
|
||||
void reject() override;
|
||||
void closeEvent( QCloseEvent * _ce ) override;
|
||||
|
||||
|
||||
private slots:
|
||||
void startBtnClicked();
|
||||
void updateTitleBar( int );
|
||||
void accept() override;
|
||||
void startExport();
|
||||
|
||||
void onFileFormatChanged(int);
|
||||
ExportProjectDialog(const QString& path, Mode mode, QWidget* parent = nullptr);
|
||||
|
||||
private:
|
||||
QString m_fileName;
|
||||
QString m_dirName;
|
||||
QString m_fileExtension;
|
||||
bool m_multiExport;
|
||||
void accept() override;
|
||||
void reject() override;
|
||||
void onFileFormatChanged(int index);
|
||||
void onStartButtonClicked();
|
||||
void updateTitleBar(int prog);
|
||||
|
||||
ProjectRenderer::ExportFileFormat m_ft;
|
||||
QLabel* m_fileFormatLabel = nullptr;
|
||||
QComboBox* m_fileFormatComboBox = nullptr;
|
||||
|
||||
QLabel* m_sampleRateLabel = nullptr;
|
||||
QComboBox* m_sampleRateComboBox = nullptr;
|
||||
|
||||
QLabel* m_bitRateLabel = nullptr;
|
||||
QComboBox* m_bitRateComboBox = nullptr;
|
||||
|
||||
QLabel* m_bitDepthLabel = nullptr;
|
||||
QComboBox* m_bitDepthComboBox = nullptr;
|
||||
|
||||
QLabel* m_stereoModeLabel = nullptr;
|
||||
QComboBox* m_stereoModeComboBox = nullptr;
|
||||
|
||||
QLabel* m_compressionLevelLabel = nullptr;
|
||||
QComboBox* m_compressionLevelComboBox = nullptr;
|
||||
|
||||
QGroupBox* m_fileFormatSettingsGroupBox = nullptr;
|
||||
QFormLayout* m_fileFormatSettingsLayout = nullptr;
|
||||
|
||||
QCheckBox* m_exportAsLoopBox = nullptr;
|
||||
QCheckBox* m_exportBetweenLoopMarkersBox = nullptr;
|
||||
QLabel* m_loopRepeatLabel = nullptr;
|
||||
QSpinBox* m_loopRepeatBox = nullptr;
|
||||
QPushButton* m_startButton = nullptr;
|
||||
QPushButton* m_cancelButton = nullptr;
|
||||
QProgressBar* m_progressBar = nullptr;
|
||||
|
||||
QString m_path;
|
||||
Mode m_mode;
|
||||
std::unique_ptr<RenderManager> m_renderManager;
|
||||
} ;
|
||||
|
||||
};
|
||||
|
||||
} // namespace lmms::gui
|
||||
|
||||
|
||||
@@ -39,14 +39,16 @@ public:
|
||||
{
|
||||
Depth16Bit,
|
||||
Depth24Bit,
|
||||
Depth32Bit
|
||||
Depth32Bit,
|
||||
Count
|
||||
};
|
||||
|
||||
enum class StereoMode
|
||||
{
|
||||
Mono,
|
||||
Stereo,
|
||||
JointStereo,
|
||||
Mono
|
||||
Count
|
||||
};
|
||||
|
||||
public:
|
||||
|
||||
@@ -1505,7 +1505,9 @@ void MainWindow::exportProject(bool multiExport)
|
||||
}
|
||||
}
|
||||
|
||||
ExportProjectDialog epd( exportFileName, getGUI()->mainWindow(), multiExport );
|
||||
ExportProjectDialog epd(exportFileName,
|
||||
multiExport ? ExportProjectDialog::Mode::ExportTracks : ExportProjectDialog::Mode::ExportProject,
|
||||
getGUI()->mainWindow());
|
||||
epd.exec();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -22,274 +22,279 @@
|
||||
*
|
||||
*/
|
||||
|
||||
#include <QFileInfo>
|
||||
#include <QMessageBox>
|
||||
|
||||
#include "ExportProjectDialog.h"
|
||||
|
||||
#include <QCheckBox>
|
||||
#include <QComboBox>
|
||||
#include <QDir>
|
||||
#include <QFileInfo>
|
||||
#include <QFormLayout>
|
||||
#include <QGroupBox>
|
||||
#include <QLabel>
|
||||
#include <QProgressBar>
|
||||
#include <QPushButton>
|
||||
#include <QSpinBox>
|
||||
#include <QVBoxLayout>
|
||||
|
||||
#include "Engine.h"
|
||||
#include "ProjectRenderer.h"
|
||||
#include "Song.h"
|
||||
#include "GuiApplication.h"
|
||||
#include "MainWindow.h"
|
||||
#include "OutputSettings.h"
|
||||
|
||||
namespace lmms::gui
|
||||
namespace lmms::gui {
|
||||
|
||||
namespace {
|
||||
constexpr auto maxCompressionLevel = 8;
|
||||
constexpr auto defaultCompressionLevel = 5;
|
||||
constexpr auto defaultBitRate = SUPPORTED_BITRATES[2];
|
||||
constexpr auto defaultBitDepth = OutputSettings::BitDepth::Depth24Bit;
|
||||
constexpr auto defaultStereoMode = OutputSettings::StereoMode::Stereo;
|
||||
constexpr auto maxLoopRepeat = std::numeric_limits<int>::max();
|
||||
} // namespace
|
||||
|
||||
ExportProjectDialog::ExportProjectDialog(const QString& path, Mode mode, QWidget* parent)
|
||||
: QDialog(parent)
|
||||
, m_fileFormatLabel(new QLabel(tr("File format:")))
|
||||
, m_fileFormatComboBox(new QComboBox())
|
||||
, m_sampleRateLabel(new QLabel(tr("Sampling rate:")))
|
||||
, m_sampleRateComboBox(new QComboBox())
|
||||
, m_bitRateLabel(new QLabel(tr("Bit rate:")))
|
||||
, m_bitRateComboBox(new QComboBox())
|
||||
, m_bitDepthLabel(new QLabel(tr("Bit depth:")))
|
||||
, m_bitDepthComboBox(new QComboBox())
|
||||
, m_stereoModeLabel(new QLabel(("Stereo mode:")))
|
||||
, m_stereoModeComboBox(new QComboBox())
|
||||
, m_compressionLevelLabel(new QLabel(tr("Compression level:")))
|
||||
, m_compressionLevelComboBox(new QComboBox())
|
||||
, m_fileFormatSettingsGroupBox(new QGroupBox(tr("File format settings")))
|
||||
, m_fileFormatSettingsLayout(new QFormLayout(m_fileFormatSettingsGroupBox))
|
||||
, m_exportAsLoopBox(new QCheckBox(tr("Export as loop (remove extra bar)")))
|
||||
, m_exportBetweenLoopMarkersBox(new QCheckBox(tr("Export between loop markers")))
|
||||
, m_loopRepeatLabel(new QLabel(tr("Render looped section:")))
|
||||
, m_loopRepeatBox(new QSpinBox())
|
||||
, m_startButton(new QPushButton(tr("Start")))
|
||||
, m_cancelButton(new QPushButton(tr("Cancel")))
|
||||
, m_progressBar(new QProgressBar())
|
||||
, m_path(path)
|
||||
, m_mode(mode)
|
||||
{
|
||||
setWindowTitle(tr("Export project"));
|
||||
|
||||
ExportProjectDialog::ExportProjectDialog( const QString & _file_name,
|
||||
QWidget * _parent, bool multi_export=false ) :
|
||||
QDialog( _parent ),
|
||||
Ui::ExportProjectDialog(),
|
||||
m_fileName( _file_name ),
|
||||
m_fileExtension(),
|
||||
m_multiExport( multi_export ),
|
||||
m_renderManager( nullptr )
|
||||
{
|
||||
setupUi( this );
|
||||
setWindowTitle( tr( "Export project to %1" ).arg(
|
||||
QFileInfo( _file_name ).fileName() ) );
|
||||
|
||||
// Get the extension of the chosen file.
|
||||
QStringList parts = _file_name.split( '.' );
|
||||
QString fileExt;
|
||||
if( parts.size() > 0 )
|
||||
for (const auto& device : ProjectRenderer::fileEncodeDevices)
|
||||
{
|
||||
fileExt = "." + parts[parts.size()-1];
|
||||
if (!device.isAvailable()) { continue; }
|
||||
m_fileFormatComboBox->addItem(tr(device.m_description), static_cast<int>(device.m_fileFormat));
|
||||
}
|
||||
|
||||
int cbIndex = 0;
|
||||
for (auto i = std::size_t{0}; i < ProjectRenderer::NumFileFormats; ++i)
|
||||
for (const auto& sampleRate : SUPPORTED_SAMPLERATES)
|
||||
{
|
||||
if( ProjectRenderer::fileEncodeDevices[i].isAvailable() )
|
||||
const auto str = tr("%1 %2").arg(QString::number(sampleRate), "Hz");
|
||||
m_sampleRateComboBox->addItem(str, sampleRate);
|
||||
}
|
||||
|
||||
for (const auto& bitRate : SUPPORTED_BITRATES)
|
||||
{
|
||||
const auto str = tr("%1 %2").arg(QString::number(bitRate), "KBit/s");
|
||||
m_bitRateComboBox->addItem(str, bitRate);
|
||||
}
|
||||
|
||||
for (auto i = 0; i < static_cast<int>(OutputSettings::BitDepth::Count); ++i)
|
||||
{
|
||||
switch (static_cast<OutputSettings::BitDepth>(i))
|
||||
{
|
||||
// Get the extension of this format.
|
||||
QString renderExt = ProjectRenderer::fileEncodeDevices[i].m_extension;
|
||||
|
||||
// Add to combo box.
|
||||
fileFormatCB->addItem( ProjectRenderer::tr(
|
||||
ProjectRenderer::fileEncodeDevices[i].m_description ),
|
||||
QVariant( static_cast<int>(ProjectRenderer::fileEncodeDevices[i].m_fileFormat) ) // Format tag; later used for identification.
|
||||
);
|
||||
|
||||
// If this is our extension, select it.
|
||||
if( QString::compare( renderExt, fileExt,
|
||||
Qt::CaseInsensitive ) == 0 )
|
||||
{
|
||||
fileFormatCB->setCurrentIndex( cbIndex );
|
||||
}
|
||||
|
||||
cbIndex++;
|
||||
case OutputSettings::BitDepth::Depth16Bit:
|
||||
m_bitDepthComboBox->addItem(tr("16 Bit integer"), i);
|
||||
break;
|
||||
case OutputSettings::BitDepth::Depth24Bit:
|
||||
m_bitDepthComboBox->addItem(tr("24 Bit integer"), i);
|
||||
break;
|
||||
case OutputSettings::BitDepth::Depth32Bit:
|
||||
m_bitDepthComboBox->addItem(tr("32 Bit float"), i);
|
||||
break;
|
||||
default:
|
||||
assert(false && "invalid or unsupported bit depth");
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
int const MAX_LEVEL=8;
|
||||
for(int i=0; i<=MAX_LEVEL; ++i)
|
||||
for (auto i = 0; i < static_cast<int>(OutputSettings::StereoMode::Count); ++i)
|
||||
{
|
||||
QString info="";
|
||||
if ( i==0 ){ info = tr( "( Fastest - biggest )" ); }
|
||||
else if ( i==MAX_LEVEL ){ info = tr( "( Slowest - smallest )" ); }
|
||||
|
||||
compLevelCB->addItem(
|
||||
QString::number(i)+" "+info,
|
||||
QVariant(i/static_cast<double>(MAX_LEVEL))
|
||||
);
|
||||
}
|
||||
compLevelCB->setCurrentIndex(5);
|
||||
#ifndef LMMS_HAVE_SF_COMPLEVEL
|
||||
// Disable this widget; the setting would be ignored by the renderer.
|
||||
compressionWidget->setVisible(false);
|
||||
#endif
|
||||
|
||||
for (const auto sampleRate : SUPPORTED_SAMPLERATES)
|
||||
{
|
||||
samplerateCB->addItem(tr("%1 Hz").arg(sampleRate), sampleRate);
|
||||
switch (static_cast<OutputSettings::StereoMode>(i))
|
||||
{
|
||||
case OutputSettings::StereoMode::Mono:
|
||||
m_stereoModeComboBox->addItem(tr("Mono"), i);
|
||||
break;
|
||||
case OutputSettings::StereoMode::Stereo:
|
||||
m_stereoModeComboBox->addItem(tr("Stereo"), i);
|
||||
break;
|
||||
case OutputSettings::StereoMode::JointStereo:
|
||||
m_stereoModeComboBox->addItem(tr("Joint stereo"), i);
|
||||
break;
|
||||
default:
|
||||
assert(false && "invalid or unsupported stereo mode");
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
const auto currentIndex = std::max(0, samplerateCB->findData(Engine::audioEngine()->outputSampleRate()));
|
||||
samplerateCB->setCurrentIndex(currentIndex);
|
||||
for (auto i = 0; i <= maxCompressionLevel; ++i)
|
||||
{
|
||||
const auto compressionValue = static_cast<float>(i) / maxCompressionLevel;
|
||||
switch (i)
|
||||
{
|
||||
case 0:
|
||||
m_compressionLevelComboBox->addItem(tr("%1 (Fastest, biggest)").arg(i), compressionValue);
|
||||
break;
|
||||
case maxCompressionLevel:
|
||||
m_compressionLevelComboBox->addItem(tr("%1 (Slowest, smallest)").arg(i), compressionValue);
|
||||
break;
|
||||
default:
|
||||
m_compressionLevelComboBox->addItem(QString::number(i), compressionValue);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
connect( startButton, SIGNAL(clicked()),
|
||||
this, SLOT(startBtnClicked()));
|
||||
|
||||
auto loopRepeatLayout = new QHBoxLayout{};
|
||||
loopRepeatLayout->addWidget(m_loopRepeatLabel);
|
||||
loopRepeatLayout->addWidget(m_loopRepeatBox);
|
||||
|
||||
auto exportSettingsGroupBox = new QGroupBox(tr("Export settings"));
|
||||
auto exportSettingsLayout = new QVBoxLayout{exportSettingsGroupBox};
|
||||
exportSettingsLayout->addWidget(m_exportAsLoopBox);
|
||||
exportSettingsLayout->addWidget(m_exportBetweenLoopMarkersBox);
|
||||
exportSettingsLayout->addLayout(loopRepeatLayout);
|
||||
|
||||
m_fileFormatSettingsLayout->addRow(m_fileFormatLabel, m_fileFormatComboBox);
|
||||
|
||||
auto startCancelButtonsLayout = new QHBoxLayout{};
|
||||
startCancelButtonsLayout->addStretch();
|
||||
startCancelButtonsLayout->addWidget(m_startButton);
|
||||
startCancelButtonsLayout->addWidget(m_cancelButton);
|
||||
|
||||
auto mainLayout = new QVBoxLayout(this);
|
||||
mainLayout->addWidget(exportSettingsGroupBox);
|
||||
mainLayout->addWidget(m_fileFormatSettingsGroupBox);
|
||||
mainLayout->addStretch();
|
||||
mainLayout->addLayout(startCancelButtonsLayout);
|
||||
mainLayout->addWidget(m_progressBar);
|
||||
|
||||
m_progressBar->setValue(0);
|
||||
m_loopRepeatBox->setRange(1, maxLoopRepeat);
|
||||
m_loopRepeatBox->setValue(1);
|
||||
m_loopRepeatBox->setSuffix(tr(" time(s)"));
|
||||
|
||||
m_fileFormatComboBox->setCurrentIndex(-1);
|
||||
connect(m_fileFormatComboBox, qOverload<int>(&QComboBox::currentIndexChanged), this,
|
||||
&ExportProjectDialog::onFileFormatChanged);
|
||||
|
||||
if (mode == Mode::ExportProject)
|
||||
{
|
||||
const auto pathExtension = QFileInfo{path}.completeSuffix().prepend(".");
|
||||
const auto pathFormat = ProjectRenderer::getFileFormatFromExtension(pathExtension);
|
||||
m_fileFormatComboBox->setCurrentIndex(
|
||||
std::max(0, m_fileFormatComboBox->findData(static_cast<int>(pathFormat))));
|
||||
}
|
||||
|
||||
m_bitRateComboBox->setCurrentIndex(std::max(0, m_bitRateComboBox->findData(defaultBitRate)));
|
||||
m_bitDepthComboBox->setCurrentIndex(std::max(0, m_bitDepthComboBox->findData(static_cast<int>(defaultBitDepth))));
|
||||
m_stereoModeComboBox->setCurrentIndex(
|
||||
std::max(0, m_stereoModeComboBox->findData(static_cast<int>(defaultStereoMode))));
|
||||
m_compressionLevelComboBox->setCurrentIndex(defaultCompressionLevel);
|
||||
|
||||
connect(m_startButton, &QPushButton::clicked, this, &ExportProjectDialog::onStartButtonClicked);
|
||||
connect(m_cancelButton, &QPushButton::clicked, this, &ExportProjectDialog::reject);
|
||||
}
|
||||
|
||||
|
||||
void ExportProjectDialog::reject()
|
||||
void ExportProjectDialog::onFileFormatChanged(int index)
|
||||
{
|
||||
if( m_renderManager ) {
|
||||
m_renderManager->abortProcessing();
|
||||
if (m_mode == Mode::ExportProject)
|
||||
{
|
||||
const auto fileInfo = QFileInfo{m_path};
|
||||
const auto extension
|
||||
= ProjectRenderer::getFileExtensionFromFormat(static_cast<ProjectRenderer::ExportFileFormat>(index));
|
||||
m_path = fileInfo.path() + QDir::separator() + fileInfo.completeBaseName() + extension;
|
||||
}
|
||||
m_renderManager.reset(nullptr);
|
||||
|
||||
QDialog::reject();
|
||||
// Remove and detach all rows after the file format row
|
||||
while (m_fileFormatSettingsLayout->rowCount() > 1)
|
||||
{
|
||||
const auto& [label, field] = m_fileFormatSettingsLayout->takeRow(1);
|
||||
label->widget()->setParent(nullptr);
|
||||
field->widget()->setParent(nullptr);
|
||||
}
|
||||
|
||||
switch (static_cast<ProjectRenderer::ExportFileFormat>(index))
|
||||
{
|
||||
case ProjectRenderer::ExportFileFormat::Wave:
|
||||
m_fileFormatSettingsLayout->addRow(m_sampleRateLabel, m_sampleRateComboBox);
|
||||
m_fileFormatSettingsLayout->addRow(m_bitDepthLabel, m_bitDepthComboBox);
|
||||
break;
|
||||
case ProjectRenderer::ExportFileFormat::Flac:
|
||||
m_fileFormatSettingsLayout->addRow(m_sampleRateLabel, m_sampleRateComboBox);
|
||||
m_fileFormatSettingsLayout->addRow(m_bitDepthLabel, m_bitDepthComboBox);
|
||||
m_fileFormatSettingsLayout->addRow(m_compressionLevelLabel, m_compressionLevelComboBox);
|
||||
break;
|
||||
case ProjectRenderer::ExportFileFormat::Ogg:
|
||||
m_fileFormatSettingsLayout->addRow(m_sampleRateLabel, m_sampleRateComboBox);
|
||||
m_fileFormatSettingsLayout->addRow(m_bitRateLabel, m_bitRateComboBox);
|
||||
break;
|
||||
case ProjectRenderer::ExportFileFormat::MP3:
|
||||
m_fileFormatSettingsLayout->addRow(m_stereoModeLabel, m_stereoModeComboBox);
|
||||
m_fileFormatSettingsLayout->addRow(m_bitRateLabel, m_bitRateComboBox);
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void ExportProjectDialog::onStartButtonClicked()
|
||||
{
|
||||
const auto sampleRate = static_cast<sample_rate_t>(m_sampleRateComboBox->currentData().toInt());
|
||||
const auto bitRate = static_cast<bitrate_t>(m_bitRateComboBox->currentData().toInt());
|
||||
const auto bitDepth = static_cast<OutputSettings::BitDepth>(m_bitDepthComboBox->currentData().toInt());
|
||||
const auto stereoMode = static_cast<OutputSettings::StereoMode>(m_stereoModeComboBox->currentData().toInt());
|
||||
auto outputSettings = OutputSettings{sampleRate, bitRate, bitDepth, stereoMode};
|
||||
|
||||
const auto compressionLevel = m_compressionLevelComboBox->currentData().toDouble();
|
||||
outputSettings.setCompressionLevel(compressionLevel);
|
||||
|
||||
const auto format = static_cast<ProjectRenderer::ExportFileFormat>(m_fileFormatComboBox->currentData().toInt());
|
||||
m_renderManager = std::make_unique<RenderManager>(outputSettings, format, m_path);
|
||||
m_startButton->setEnabled(false);
|
||||
|
||||
Engine::getSong()->setExportLoop(m_exportAsLoopBox->isChecked());
|
||||
Engine::getSong()->setRenderBetweenMarkers(m_exportBetweenLoopMarkersBox->isChecked());
|
||||
Engine::getSong()->setLoopRenderCount(m_loopRepeatBox->value());
|
||||
|
||||
connect(m_renderManager.get(), &RenderManager::progressChanged, m_progressBar, &QProgressBar::setValue);
|
||||
connect(m_renderManager.get(), &RenderManager::progressChanged, this, &ExportProjectDialog::updateTitleBar);
|
||||
connect(m_renderManager.get(), &RenderManager::finished, this, &QDialog::accept);
|
||||
|
||||
switch (m_mode)
|
||||
{
|
||||
case Mode::ExportProject:
|
||||
m_renderManager->renderProject();
|
||||
break;
|
||||
case Mode::ExportTracks:
|
||||
m_renderManager->renderTracks();
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void ExportProjectDialog::accept()
|
||||
{
|
||||
m_renderManager.reset(nullptr);
|
||||
QDialog::accept();
|
||||
|
||||
getGUI()->mainWindow()->resetWindowTitle();
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
void ExportProjectDialog::closeEvent( QCloseEvent * _ce )
|
||||
void ExportProjectDialog::reject()
|
||||
{
|
||||
Engine::getSong()->setLoopRenderCount(1);
|
||||
if( m_renderManager ) {
|
||||
m_renderManager->abortProcessing();
|
||||
}
|
||||
|
||||
QDialog::closeEvent( _ce );
|
||||
if (m_renderManager) { m_renderManager->abortProcessing(); }
|
||||
m_renderManager.reset(nullptr);
|
||||
QDialog::reject();
|
||||
}
|
||||
|
||||
|
||||
OutputSettings::StereoMode mapToStereoMode(int index)
|
||||
void ExportProjectDialog::updateTitleBar(int prog)
|
||||
{
|
||||
switch (index)
|
||||
{
|
||||
case 0:
|
||||
return OutputSettings::StereoMode::Mono;
|
||||
case 1:
|
||||
return OutputSettings::StereoMode::Stereo;
|
||||
case 2:
|
||||
return OutputSettings::StereoMode::JointStereo;
|
||||
default:
|
||||
return OutputSettings::StereoMode::Stereo;
|
||||
}
|
||||
}
|
||||
|
||||
void ExportProjectDialog::startExport()
|
||||
{
|
||||
const auto bitrates = std::array{64, 128, 160, 192, 256, 320};
|
||||
|
||||
OutputSettings os = OutputSettings(samplerateCB->currentData().toInt(), bitrates[bitrateCB->currentIndex()],
|
||||
static_cast<OutputSettings::BitDepth>(depthCB->currentIndex()),
|
||||
mapToStereoMode(stereoModeComboBox->currentIndex()));
|
||||
|
||||
if (compressionWidget->isVisible())
|
||||
{
|
||||
double level = compLevelCB->itemData(compLevelCB->currentIndex()).toDouble();
|
||||
os.setCompressionLevel(level);
|
||||
}
|
||||
|
||||
// Make sure we have the the correct file extension
|
||||
// so there's no confusion about the codec in use.
|
||||
auto output_name = m_fileName;
|
||||
if (!(m_multiExport || output_name.endsWith(m_fileExtension,Qt::CaseInsensitive)))
|
||||
{
|
||||
output_name+=m_fileExtension;
|
||||
}
|
||||
|
||||
m_renderManager.reset(new RenderManager(os, m_ft, output_name));
|
||||
|
||||
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)));
|
||||
connect( m_renderManager.get(), SIGNAL(progressChanged(int)),
|
||||
this, SLOT(updateTitleBar(int)));
|
||||
connect( m_renderManager.get(), SIGNAL(finished()),
|
||||
this, SLOT(accept())) ;
|
||||
connect( m_renderManager.get(), SIGNAL(finished()),
|
||||
getGUI()->mainWindow(), SLOT(resetWindowTitle()));
|
||||
|
||||
if ( m_multiExport )
|
||||
{
|
||||
m_renderManager->renderTracks();
|
||||
}
|
||||
else
|
||||
{
|
||||
m_renderManager->renderProject();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void ExportProjectDialog::onFileFormatChanged(int index)
|
||||
{
|
||||
// Extract the format tag from the currently selected item,
|
||||
// and adjust the UI properly.
|
||||
QVariant format_tag = fileFormatCB->itemData(index);
|
||||
bool successful_conversion = false;
|
||||
auto exportFormat = static_cast<ProjectRenderer::ExportFileFormat>(
|
||||
format_tag.toInt(&successful_conversion)
|
||||
);
|
||||
Q_ASSERT(successful_conversion);
|
||||
|
||||
bool stereoModeVisible = (exportFormat == ProjectRenderer::ExportFileFormat::MP3);
|
||||
|
||||
bool sampleRateControlsVisible = (exportFormat != ProjectRenderer::ExportFileFormat::MP3);
|
||||
|
||||
bool bitRateControlsEnabled =
|
||||
(exportFormat == ProjectRenderer::ExportFileFormat::Ogg ||
|
||||
exportFormat == ProjectRenderer::ExportFileFormat::MP3);
|
||||
|
||||
bool bitDepthControlEnabled =
|
||||
(exportFormat == ProjectRenderer::ExportFileFormat::Wave ||
|
||||
exportFormat == ProjectRenderer::ExportFileFormat::Flac);
|
||||
|
||||
#ifdef LMMS_HAVE_SF_COMPLEVEL
|
||||
bool compressionLevelVisible = (exportFormat == ProjectRenderer::ExportFileFormat::Flac);
|
||||
compressionWidget->setVisible(compressionLevelVisible);
|
||||
#endif
|
||||
|
||||
stereoModeWidget->setVisible(stereoModeVisible);
|
||||
sampleRateWidget->setVisible(sampleRateControlsVisible);
|
||||
|
||||
bitrateWidget->setVisible(bitRateControlsEnabled);
|
||||
|
||||
depthWidget->setVisible(bitDepthControlEnabled);
|
||||
}
|
||||
|
||||
void ExportProjectDialog::startBtnClicked()
|
||||
{
|
||||
m_ft = ProjectRenderer::ExportFileFormat::Count;
|
||||
|
||||
// Get file format from current menu selection.
|
||||
bool successful_conversion = false;
|
||||
QVariant tag = fileFormatCB->itemData(fileFormatCB->currentIndex());
|
||||
m_ft = static_cast<ProjectRenderer::ExportFileFormat>(
|
||||
tag.toInt(&successful_conversion)
|
||||
);
|
||||
|
||||
if( !successful_conversion )
|
||||
{
|
||||
QMessageBox::information( this, tr( "Error" ),
|
||||
tr( "Error while determining file-encoder device. "
|
||||
"Please try to choose a different output "
|
||||
"format." ) );
|
||||
reject();
|
||||
return;
|
||||
}
|
||||
|
||||
// Find proper file extension.
|
||||
for (auto i = std::size_t{0}; i < ProjectRenderer::NumFileFormats; ++i)
|
||||
{
|
||||
if (m_ft == ProjectRenderer::fileEncodeDevices[i].m_fileFormat)
|
||||
{
|
||||
m_fileExtension = QString( QLatin1String( ProjectRenderer::fileEncodeDevices[i].m_extension ) );
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
startButton->setEnabled( false );
|
||||
progressBar->setEnabled( true );
|
||||
|
||||
updateTitleBar( 0 );
|
||||
|
||||
startExport();
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
void ExportProjectDialog::updateTitleBar( int _prog )
|
||||
{
|
||||
getGUI()->mainWindow()->setWindowTitle(
|
||||
tr( "Rendering: %1%" ).arg( _prog ) );
|
||||
setWindowTitle(tr("Rendering: %1%").arg(prog));
|
||||
}
|
||||
|
||||
} // namespace lmms::gui
|
||||
|
||||
@@ -1,417 +0,0 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<ui version="4.0">
|
||||
<class>ExportProjectDialog</class>
|
||||
<widget class="QDialog" name="ExportProjectDialog">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>0</x>
|
||||
<y>0</y>
|
||||
<width>379</width>
|
||||
<height>400</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="minimumSize">
|
||||
<size>
|
||||
<width>379</width>
|
||||
<height>400</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="maximumSize">
|
||||
<size>
|
||||
<width>379</width>
|
||||
<height>400</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="windowTitle">
|
||||
<string>Export project</string>
|
||||
</property>
|
||||
<layout class="QVBoxLayout">
|
||||
<item>
|
||||
<widget class="QCheckBox" name="exportLoopCB">
|
||||
<property name="text">
|
||||
<string>Export as loop (remove extra bar)</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QCheckBox" name="renderMarkersCB">
|
||||
<property name="text">
|
||||
<string>Export between loop markers</string>
|
||||
</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>2147483647</number> <!-- INT_MAX -->
|
||||
</property>
|
||||
<property name="value">
|
||||
<number>1</number>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<layout class="QHBoxLayout">
|
||||
<item>
|
||||
<widget class="QGroupBox" name="outputGroupBox">
|
||||
<property name="title">
|
||||
<string>File format settings</string>
|
||||
</property>
|
||||
<layout class="QVBoxLayout">
|
||||
<item>
|
||||
<widget class="QLabel" name="label">
|
||||
<property name="text">
|
||||
<string>File format:</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QComboBox" name="fileFormatCB"/>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QWidget" name="sampleRateWidget" native="true">
|
||||
<layout class="QVBoxLayout" name="verticalLayout">
|
||||
<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="labelSampleRate">
|
||||
<property name="text">
|
||||
<string>Sampling rate:</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QComboBox" name="samplerateCB" />
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QWidget" name="depthWidget" native="true">
|
||||
<layout class="QVBoxLayout">
|
||||
<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="labelBitDepth">
|
||||
<property name="text">
|
||||
<string>Bit depth:</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QComboBox" name="depthCB">
|
||||
<property name="currentIndex">
|
||||
<number>1</number>
|
||||
</property>
|
||||
<item>
|
||||
<property name="text">
|
||||
<string>16 Bit integer</string>
|
||||
</property>
|
||||
</item>
|
||||
<item>
|
||||
<property name="text">
|
||||
<string>24 Bit integer</string>
|
||||
</property>
|
||||
</item>
|
||||
<item>
|
||||
<property name="text">
|
||||
<string>32 Bit float</string>
|
||||
</property>
|
||||
</item>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QWidget" name="stereoModeWidget" native="true">
|
||||
<layout class="QVBoxLayout" name="verticalLayout_4">
|
||||
<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="labelStereoMode_3">
|
||||
<property name="text">
|
||||
<string>Stereo mode:</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QComboBox" name="stereoModeComboBox">
|
||||
<property name="currentIndex">
|
||||
<number>1</number>
|
||||
</property>
|
||||
<item>
|
||||
<property name="text">
|
||||
<string>Mono</string>
|
||||
</property>
|
||||
</item>
|
||||
<item>
|
||||
<property name="text">
|
||||
<string>Stereo</string>
|
||||
</property>
|
||||
</item>
|
||||
<item>
|
||||
<property name="text">
|
||||
<string>Joint stereo</string>
|
||||
</property>
|
||||
</item>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QWidget" name="compressionWidget" native="true">
|
||||
<layout class="QVBoxLayout" name="_2">
|
||||
<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="labelCompLevel">
|
||||
<property name="text">
|
||||
<string>Compression level:</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QComboBox" name="compLevelCB">
|
||||
<property name="currentIndex">
|
||||
<number>-1</number>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QWidget" name="bitrateWidget" native="true">
|
||||
<layout class="QVBoxLayout">
|
||||
<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="labelBitRate">
|
||||
<property name="text">
|
||||
<string>Bitrate:</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QComboBox" name="bitrateCB">
|
||||
<property name="currentIndex">
|
||||
<number>2</number>
|
||||
</property>
|
||||
<item>
|
||||
<property name="text">
|
||||
<string>64 KBit/s</string>
|
||||
</property>
|
||||
</item>
|
||||
<item>
|
||||
<property name="text">
|
||||
<string>128 KBit/s</string>
|
||||
</property>
|
||||
</item>
|
||||
<item>
|
||||
<property name="text">
|
||||
<string>160 KBit/s</string>
|
||||
</property>
|
||||
</item>
|
||||
<item>
|
||||
<property name="text">
|
||||
<string>192 KBit/s</string>
|
||||
</property>
|
||||
</item>
|
||||
<item>
|
||||
<property name="text">
|
||||
<string>256 KBit/s</string>
|
||||
</property>
|
||||
</item>
|
||||
<item>
|
||||
<property name="text">
|
||||
<string>320 KBit/s</string>
|
||||
</property>
|
||||
</item>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<spacer>
|
||||
<property name="orientation">
|
||||
<enum>Qt::Vertical</enum>
|
||||
</property>
|
||||
<property name="sizeHint" stdset="0">
|
||||
<size>
|
||||
<width>0</width>
|
||||
<height>0</height>
|
||||
</size>
|
||||
</property>
|
||||
</spacer>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
<item>
|
||||
<layout class="QHBoxLayout">
|
||||
<item>
|
||||
<spacer>
|
||||
<property name="orientation">
|
||||
<enum>Qt::Horizontal</enum>
|
||||
</property>
|
||||
<property name="sizeHint" stdset="0">
|
||||
<size>
|
||||
<width>0</width>
|
||||
<height>0</height>
|
||||
</size>
|
||||
</property>
|
||||
</spacer>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QPushButton" name="startButton">
|
||||
<property name="text">
|
||||
<string>Start</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QPushButton" name="cancelButton">
|
||||
<property name="text">
|
||||
<string>Cancel</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QProgressBar" name="progressBar">
|
||||
<property name="enabled">
|
||||
<bool>false</bool>
|
||||
</property>
|
||||
<property name="value">
|
||||
<number>0</number>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
<resources/>
|
||||
<connections>
|
||||
<connection>
|
||||
<sender>cancelButton</sender>
|
||||
<signal>clicked()</signal>
|
||||
<receiver>ExportProjectDialog</receiver>
|
||||
<slot>reject()</slot>
|
||||
<hints>
|
||||
<hint type="sourcelabel">
|
||||
<x>511</x>
|
||||
<y>372</y>
|
||||
</hint>
|
||||
<hint type="destinationlabel">
|
||||
<x>202</x>
|
||||
<y>175</y>
|
||||
</hint>
|
||||
</hints>
|
||||
</connection>
|
||||
<connection>
|
||||
<sender>fileFormatCB</sender>
|
||||
<signal>currentIndexChanged(int)</signal>
|
||||
<receiver>ExportProjectDialog</receiver>
|
||||
<slot>onFileFormatChanged(int)</slot>
|
||||
<hints>
|
||||
<hint type="sourcelabel">
|
||||
<x>111</x>
|
||||
<y>85</y>
|
||||
</hint>
|
||||
<hint type="destinationlabel">
|
||||
<x>518</x>
|
||||
<y>212</y>
|
||||
</hint>
|
||||
</hints>
|
||||
</connection>
|
||||
</connections>
|
||||
<slots>
|
||||
<slot>onFileFormatChanged(int)</slot>
|
||||
</slots>
|
||||
</ui>
|
||||
Reference in New Issue
Block a user