<File
RelativePath=".\src\Encoder_Abstract.h"
>
+ <FileConfiguration
+ Name="Debug|Win32"
+ >
+ <Tool
+ Name="VCCustomBuildTool"
+ Description="MOC "$(SolutionDir)tmp\MOC_$(SafeInputName).cpp""
+ CommandLine=""$(QTDIR)\bin\moc.exe" -o "$(SolutionDir)tmp\MOC_$(SafeInputName).cpp" "$(InputPath)"
"
+ Outputs=""$(SolutionDir)tmp\MOC_$(SafeInputName).cpp""
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="Release|Win32"
+ >
+ <Tool
+ Name="VCCustomBuildTool"
+ Description="MOC "$(SolutionDir)tmp\MOC_$(SafeInputName).cpp""
+ CommandLine=""$(QTDIR)\bin\moc.exe" -o "$(SolutionDir)tmp\MOC_$(SafeInputName).cpp" "$(InputPath)"
"
+ Outputs=""$(SolutionDir)tmp\MOC_$(SafeInputName).cpp""
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="Release_Static|Win32"
+ >
+ <Tool
+ Name="VCCustomBuildTool"
+ Description="MOC "$(SolutionDir)tmp\MOC_$(SafeInputName).cpp""
+ CommandLine=""$(QTDIR)\bin\moc.exe" -o "$(SolutionDir)tmp\MOC_$(SafeInputName).cpp" "$(InputPath)"
"
+ Outputs=""$(SolutionDir)tmp\MOC_$(SafeInputName).cpp""
+ />
+ </FileConfiguration>
</File>
<File
RelativePath=".\src\Encoder_MP3.h"
>
</File>
<File
+ RelativePath=".\tmp\MOC_Encoder_Abstract.cpp"
+ >
+ </File>
+ <File
RelativePath=".\tmp\MOC_Encoder_MP3.cpp"
>
</File>
#define VER_LAMEXP_MAJOR 4
#define VER_LAMEXP_MINOR_HI 0
#define VER_LAMEXP_MINOR_LO 0
-#define VER_LAMEXP_BUILD 44
+#define VER_LAMEXP_BUILD 49
#define VER_LAMEXP_SUFFIX TechPreview
/*
sourceFileView->setModel(m_fileListModel);
sourceFileView->verticalHeader()->setResizeMode(QHeaderView::ResizeToContents);
sourceFileView->horizontalHeader()->setResizeMode(QHeaderView::ResizeToContents);
+ m_dropNoteLabel = new QLabel(sourceFileView);
+ m_dropNoteLabel->setAlignment(Qt::AlignHCenter | Qt::AlignVCenter);
+ m_dropNoteLabel->setText("» You can drop in audio files here! «");
connect(buttonAddFiles, SIGNAL(clicked()), this, SLOT(addFilesButtonClicked()));
connect(buttonRemoveFile, SIGNAL(clicked()), this, SLOT(removeFileButtonClicked()));
connect(buttonClearFiles, SIGNAL(clicked()), this, SLOT(clearFilesButtonClicked()));
connect(buttonFileUp, SIGNAL(clicked()), this, SLOT(fileUpButtonClicked()));
connect(buttonFileDown, SIGNAL(clicked()), this, SLOT(fileDownButtonClicked()));
connect(buttonShowDetails, SIGNAL(clicked()), this, SLOT(showDetailsButtonClicked()));
+ connect(m_fileListModel, SIGNAL(rowsInserted(QModelIndex,int,int)), this, SLOT(rowsChanged(QModelIndex,int,int)));
+ connect(m_fileListModel, SIGNAL(rowsRemoved(QModelIndex,int,int)), this, SLOT(rowsChanged(QModelIndex,int,int)));
+ connect(m_fileListModel, SIGNAL(modelReset()), this, SLOT(modelReset()));
//Setup "Output" tab
m_fileSystemModel = new QFileSystemModel();
outputFolderView->setHeaderHidden(true);
outputFolderView->setAnimated(true);
connect(outputFolderView, SIGNAL(clicked(QModelIndex)), this, SLOT(outputFolderViewClicked(QModelIndex)));
- outputFolderView->setCurrentIndex(m_fileSystemModel->index(QDesktopServices::storageLocation(QDesktopServices::MusicLocation)));
+ outputFolderView->setCurrentIndex(m_fileSystemModel->index(m_settings->outputDir()));
outputFolderViewClicked(outputFolderView->currentIndex());
connect(buttonMakeFolder, SIGNAL(clicked()), this, SLOT(makeFolderButtonClicked()));
connect(buttonGotoHome, SIGNAL(clicked()), SLOT(gotoHomeFolderButtonClicked()));
LAMEXP_DELETE(m_delayedFileTimer);
LAMEXP_DELETE(m_metaInfoModel);
LAMEXP_DELETE(m_encoderButtonGroup);
+ LAMEXP_DELETE(m_encoderButtonGroup);
}
////////////////////////////////////////////////////////////
void MainWindow::showEvent(QShowEvent *event)
{
- QTimer::singleShot(0, this, SLOT(windowShown()));
m_accepted = false;
+ m_dropNoteLabel->setGeometry(0, 0, sourceFileView->width(), sourceFileView->height());
+ modelReset();
+ QTimer::singleShot(0, this, SLOT(windowShown()));
}
void MainWindow::dragEnterEvent(QDragEnterEvent *event)
}
}
+void MainWindow::resizeEvent(QResizeEvent *event)
+{
+ QMainWindow::resizeEvent(event);
+ m_dropNoteLabel->setGeometry(0, 0, sourceFileView->width(), sourceFileView->height());
+}
+
////////////////////////////////////////////////////////////
// Slots
////////////////////////////////////////////////////////////
LAMEXP_DELETE(aboutBox);
}
-#define IF_UNICODE(STR) if(_stricmp(STR.toUtf8().constData(),QString::fromLocal8Bit(STR.toLocal8Bit()).toUtf8().constData()))
-
/*
* Encode button
*/
{
ABORT_IF_BUSY;
+ if(m_fileListModel->rowCount() < 1)
+ {
+ QMessageBox::warning(this, "LameXP", "You must add at least one file to the list before proceeding!");
+ tabWidget->setCurrentIndex(0);
+ return;
+ }
+
if(m_settings->compressionEncoder() != SettingsModel::MP3Encoder)
{
- QMessageBox::warning(this, "LameXP", "Sorry, only Lame MP3 is supported at the moment!");
+ QMessageBox::warning(this, "LameXP", "Sorry, only Lame MP3 encoding is supported at the moment!");
tabWidget->setCurrentIndex(3);
return;
}
m_accepted = true;
close();
-
- //m_banner->show("Encoding files, please wait...");
- //QApplication::processEvents();
-
- //MP3Encoder *mp3Encoder = new MP3Encoder();
- //connect(mp3Encoder, SIGNAL(statusUpdated(QString)), m_banner, SLOT(setText(QString)));
-
- //for(int i = 0; i < m_fileListModel->rowCount(); i++)
- //{
- // AudioFileModel file = m_fileListModel->getFile(m_fileListModel->index(i,0));
- // QString outFolder = m_fileSystemModel->filePath(this->outputFolderView->currentIndex());
- //
- // QString baseName = QFileInfo(file.filePath()).fileName();
- // int pos = baseName.lastIndexOf(".");
- // if(pos >= 1) baseName = baseName.left(pos);
-
- // int n = 1;
- // QString outFileName = QString(outFolder).append("/").append(baseName).append(".mp3");
- //
- // while(QFileInfo(outFileName).exists())
- // {
- // outFileName = QString(outFolder).append("/").append(baseName).append(" (").append(QString::number(++n)).append(").mp3");
- // }
- //
- // mp3Encoder->encode(file, outFileName);
- //}
-
- //LAMEXP_DELETE(mp3Encoder);
- //m_banner->close();
- //
- //QMessageBox::information(this, "Done", "Encoding process completed.");
}
/*
QString selectedDir = m_fileSystemModel->filePath(index);
if(selectedDir.length() < 3) selectedDir.append(QDir::separator());
outputFolderLabel->setText(selectedDir);
+ m_settings->outputDir(selectedDir);
}
/*
break;
}
}
+
+/*
+ * Rows changed
+ */
+void MainWindow::rowsChanged(const QModelIndex &parent, int start, int end)
+{
+ m_dropNoteLabel->setVisible(m_fileListModel->rowCount() <= 0);
+}
+
+/*
+ * Model reset
+ */
+void MainWindow::modelReset(void)
+{
+ m_dropNoteLabel->setVisible(m_fileListModel->rowCount() <= 0);
+}
class SettingsModel;
class QButtonGroup;
class FileListModel;
+class AbstractEncoder;
class MainWindow: public QMainWindow, private Ui::MainWindow
{
void updateEncoder(int id);
void updateRCMode(int id);
void updateBitrate(int value);
+ void rowsChanged(const QModelIndex &parent, int start, int end);
+ void modelReset(void);
protected:
void showEvent(QShowEvent *event);
void dragEnterEvent(QDragEnterEvent *event);
void dropEvent(QDropEvent *event);
void closeEvent(QCloseEvent *event);
+ void resizeEvent(QResizeEvent *event);
private:
void addFiles(const QStringList &files);
AudioFileModel *m_metaData;
MetaInfoModel *m_metaInfoModel;
SettingsModel *m_settings;
+ QLabel *m_dropNoteLabel;
};
#include "Global.h"
#include "Model_FileList.h"
#include "Model_Progress.h"
+#include "Model_Settings.h"
#include "Thread_Process.h"
+#include "Encoder_MP3.h"
#include <QApplication>
#include <QRect>
// Constructor
////////////////////////////////////////////////////////////
-ProcessingDialog::ProcessingDialog(FileListModel *fileListModel)
+ProcessingDialog::ProcessingDialog(FileListModel *fileListModel, SettingsModel *settings)
+:
+ m_settings(settings)
{
//Init the dialog, from the .ui file
setupUi(this);
while(!m_threadList.isEmpty())
{
- delete m_threadList.takeFirst();
+ ProcessThread *thread = m_threadList.takeFirst();
+ thread->terminate();
+ thread->wait(15000);
+ delete thread;
}
}
m_runningThreads--;
progressBar->setValue(progressBar->value() + 1);
- label_progress->setText(QString("%1 files out of %2 completed, please wait...").arg(QString::number(progressBar->value()), QString::number(progressBar->maximum())));
+ label_progress->setText(QString("Encoding: %1 files of %2 completed so far, please wait...").arg(QString::number(progressBar->value()), QString::number(progressBar->maximum())));
+ int index = m_threadList.indexOf(dynamic_cast<ProcessThread*>(QWidget::sender()));
+ if(index >= 0)
+ {
+ m_threadList.takeAt(index)->deleteLater();
+ }
+
if(!m_pendingJobs.isEmpty() && !m_userAborted)
{
startNextJob();
qDebug("Running jobs: %u", m_runningThreads);
- label_progress->setText(m_userAborted ? "Process aborted by user." : "Alle files completed.");
+ label_progress->setText(m_userAborted ? "Process was aborted by the user!" : "Alle files completed successfully.");
m_progressIndicator->stop();
setCloseButtonEnabled(true);
return;
}
- ProcessThread *thread = new ProcessThread(m_pendingJobs.takeFirst());
+ AbstractEncoder *encoder = NULL;
+
+ switch(m_settings->compressionEncoder())
+ {
+ case SettingsModel::MP3Encoder:
+ {
+ MP3Encoder *mp3Encoder = new MP3Encoder();
+ mp3Encoder->setBitrate(m_settings->compressionBitrate());
+ mp3Encoder->setRCMode(m_settings->compressionRCMode());
+ encoder = mp3Encoder;
+ }
+ break;
+ default:
+ throw "Unsupported encoder!";
+ }
+
+ ProcessThread *thread = new ProcessThread(m_pendingJobs.takeFirst(), m_settings->outputDir(), encoder);
m_threadList.append(thread);
connect(thread, SIGNAL(finished()), this, SLOT(doneEncoding()), Qt::QueuedConnection);
connect(thread, SIGNAL(processStateInitialized(QUuid,QString,QString,int)), m_progressModel, SLOT(addJob(QUuid,QString,QString,int)), Qt::QueuedConnection);
class ProcessThread;
class FileListModel;
class AudioFileModel;
+class SettingsModel;
class ProcessingDialog : public QDialog, private Ui::ProcessingDialog
{
Q_OBJECT
public:
- ProcessingDialog(FileListModel *fileListModel = NULL);
+ ProcessingDialog(FileListModel *fileListModel, SettingsModel *settings);
~ProcessingDialog(void);
private slots:
void ProcessingDialog::startNextJob(void);
QList<AudioFileModel> m_pendingJobs;
+ SettingsModel *m_settings;
QList<ProcessThread*> m_threadList;
QMovie *m_progressIndicator;
ProgressModel *m_progressModel;
#include "Model_AudioFile.h"
-#include <QString>
+#include <QObject>
-class AbstractEncoder
+class AbstractEncoder : public QObject
{
+ Q_OBJECT
+
public:
AbstractEncoder(void);
~AbstractEncoder(void);
- virtual bool encode(const AudioFileModel &sourceFile, const QString &outputFile) = 0;
+ virtual bool encode(const AudioFileModel &sourceFile, const QString &outputFile, volatile bool *abortFlag) = 0;
+ virtual QString extension(void) = 0;
void setBitrate(int bitrate);
void setRCMode(int mode);
{
}
-bool MP3Encoder::encode(const AudioFileModel &sourceFile, const QString &outputFile)
+bool MP3Encoder::encode(const AudioFileModel &sourceFile, const QString &outputFile, volatile bool *abortFlag)
{
const QString baseName = QFileInfo(outputFile).fileName();
- emit statusUpdated(baseName);
+ emit statusUpdated(0);
QProcess process;
process.setProcessChannelMode(QProcess::MergedChannels);
return false;
}
+ bool bTimeout = false;
+ bool bAborted = false;
+
QRegExp regExp("\\(.*(\\d+)%\\)\\|");
while(process.state() != QProcess::NotRunning)
{
+ if(*abortFlag)
+ {
+ process.kill();
+ bAborted = true;
+ break;
+ }
process.waitForReadyRead();
+ if(!process.bytesAvailable() && process.state() == QProcess::Running)
+ {
+ process.kill();
+ qWarning("LAME process timed out <-- killing!");
+ bTimeout = true;
+ break;
+ }
while(process.bytesAvailable() > 0)
{
QByteArray line = process.readLine();
- qDebug("%s", line.constData());
- QString text = QString::fromLocal8Bit(line.constData()).simplified();
- if(regExp.lastIndexIn(line) >= 0)
+ QString text = QString::fromUtf8(line.constData()).simplified();
+ if(regExp.lastIndexIn(text) >= 0)
+ {
+ bool ok = false;
+ int progress = regExp.cap(1).toInt(&ok);
+ if(ok) emit statusUpdated(progress);
+ }
+ else if(!text.isEmpty())
{
- emit statusUpdated(QString("%1 [%2%]").arg(baseName, regExp.cap(1)));
+ qDebug("%s", text.toUtf8().constData());
}
}
}
process.waitForFinished();
-
if(process.state() != QProcess::NotRunning)
{
process.kill();
process.waitForFinished(-1);
}
- if(process.exitStatus() != QProcess::NormalExit)
+ if(bTimeout || bAborted || process.exitStatus() != QProcess::NormalExit)
{
return false;
}
return true;
-}
\ No newline at end of file
+}
+
+QString MP3Encoder::extension(void)
+{
+ return "mp3";
+}
#include <QObject>
-class MP3Encoder : public QObject, public AbstractEncoder
+class MP3Encoder : public AbstractEncoder
{
Q_OBJECT
MP3Encoder(void);
~MP3Encoder(void);
- virtual bool encode(const AudioFileModel &sourceFile, const QString &outputFile);
+ virtual bool encode(const AudioFileModel &sourceFile, const QString &outputFile, volatile bool *abortFlag);
+ virtual QString extension(void);
signals:
- void statusUpdated(const QString &text);
+ void statusUpdated(int progress);
private:
const QString m_binary;
#include "Model_Settings.h"
#include "Model_FileList.h"
#include "Model_AudioFile.h"
+#include "Encoder_Abstract.h"
//Qt includes
#include <QApplication>
#include <QMessageBox>
#include <QDate>
#include <QMutex>
+#include <QDir>
///////////////////////////////////////////////////////////////////////////////
// Main function
//Show processing dialog
if(bAccepted && fileListModel->rowCount() > 0)
{
- ProcessingDialog *processingDialog = new ProcessingDialog(fileListModel);
+ ProcessingDialog *processingDialog = new ProcessingDialog(fileListModel, settingsModel);
processingDialog->exec();
LAMEXP_DELETE(processingDialog);
}
////////////////////////////////////////////////////////////
FileListModel::FileListModel(void)
- : m_fileIcon(":/icons/page_white_cd.png")
+:
+ m_fileIcon(":/icons/page_white_cd.png")
{
- m_fileList.append(AudioFileModel("C:/Music/Buckethead - Crime Slunk Scene/The Fairy and the Devil.ogg", "The Fairy and the Devil"));
}
FileListModel::~FileListModel(void)
break;
}
}
+ else if(role == Qt::TextAlignmentRole)
+ {
+ return (index.column() == 1) ? QVariant(Qt::AlignHCenter | Qt::AlignVCenter) : QVariant();
+ }
}
return QVariant();
#include <QSettings>
#include <QDesktopServices>
#include <QApplication>
+#include <QString>
+#include <QFileInfo>
static const char *g_settingsId_versionNumber = "VersionNumber";
static const char *g_settingsId_licenseAccepted = "LicenseAccepted";
static const char *g_settingsId_compressionEncoder = "Compression/Encoder";
static const char *g_settingsId_compressionRCMode = "Compression/RCMode";
static const char *g_settingsId_compressionBitrate = "Compression/Bitrate";
+static const char *g_settingsId_outputDir = "OutputDirectory";
#define MAKE_GETTER(OPT,DEF) int SettingsModel::OPT(void) { return m_settings->value(g_settingsId_##OPT, DEF).toInt(); }
#define MAKE_SETTER(OPT) void SettingsModel::OPT(int value) { m_settings->setValue(g_settingsId_##OPT, value); }
+#define MAKE_GETTER2(OPT,DEF) QString SettingsModel::OPT(void) { return m_settings->value(g_settingsId_##OPT, DEF).toString().trimmed(); }
+#define MAKE_SETTER2(OPT) void SettingsModel::OPT(const QString &value) { m_settings->setValue(g_settingsId_##OPT, value); }
const int SettingsModel::mp3Bitrates[15] = {32, 40, 48, 56, 64, 80, 96, 112, 128, 160, 192, 224, 256, 320, -1};
{
if(this->compressionEncoder() == SettingsModel::AACEncoder) this->compressionEncoder(SettingsModel::MP3Encoder);
}
+ if(this->outputDir().isEmpty() || !QFileInfo(this->outputDir()).isDir())
+ {
+ this->outputDir(QDesktopServices::storageLocation(QDesktopServices::MusicLocation));
+ }
}
////////////////////////////////////////////////////////////
MAKE_GETTER(compressionBitrate, 0)
MAKE_SETTER(compressionBitrate)
+
+MAKE_GETTER2(outputDir, QString())
+MAKE_SETTER2(outputDir)
+
#pragma once
class QSettings;
+class QString;
#define MAKE_GETTER_DEC(OPT) int OPT(void)
#define MAKE_SETTER_DEC(OPT) void OPT(int value)
+#define MAKE_GETTER_DEC2(OPT) QString OPT(void)
+#define MAKE_SETTER_DEC2(OPT) void OPT(const QString &value)
class SettingsModel
{
MAKE_GETTER_DEC(compressionEncoder);
MAKE_GETTER_DEC(compressionRCMode);
MAKE_GETTER_DEC(compressionBitrate);
+ MAKE_GETTER_DEC2(outputDir);
//Setters
MAKE_SETTER_DEC(compressionBitrate);
MAKE_SETTER_DEC(compressionRCMode);
MAKE_SETTER_DEC(compressionEncoder);
+ MAKE_SETTER_DEC2(outputDir);
void validate(void);
#undef MAKE_GETTER_DEC
#undef MAKE_SETTER_DEC
+#undef MAKE_GETTER_DEC2
+#undef MAKE_SETTER_DEC2
#include "Global.h"
#include "Model_AudioFile.h"
#include "Model_Progress.h"
+#include "Encoder_Abstract.h"
+
+#include "Model_Settings.h"
#include <QUuid>
#include <QFileInfo>
+#include <QDir>
#include <limits.h>
#include <time.h>
// Constructor
////////////////////////////////////////////////////////////
-ProcessThread::ProcessThread(AudioFileModel audioFile)
+ProcessThread::ProcessThread(const AudioFileModel &audioFile, const QString &outputDirectory, AbstractEncoder *encoder)
:
m_audioFile(audioFile),
+ m_outputDirectory(outputDirectory),
+ m_encoder(encoder),
m_jobId(QUuid::createUuid()),
m_aborted(false)
{
+ connect(m_encoder, SIGNAL(statusUpdated(int)), this, SLOT(handleUpdate(int)), Qt::DirectConnection);
}
ProcessThread::~ProcessThread(void)
{
+ LAMEXP_DELETE(m_encoder);
}
void ProcessThread::run()
qDebug("Process thread %s has started.", m_jobId.toString().toLatin1().constData());
emit processStateInitialized(m_jobId, QFileInfo(m_audioFile.filePath()).fileName(), "Starting...", ProgressModel::JobRunning);
-
- QUuid uuid = QUuid::createUuid();
- qsrand(uuid.data1 * uuid.data2 * uuid.data3 * uuid.data4[0] * uuid.data4[1] * uuid.data4[2] * uuid.data4[3] * uuid.data4[4] * uuid.data4[5] * uuid.data4[6] * uuid.data4[7]);
- unsigned long delay = 100 + (qrand() % 150);
- for(int i = 1; i <= 100; i++)
+ if(!QFileInfo(m_audioFile.filePath()).isFile())
+ {
+ emit processStateChanged(m_jobId, "Not found!", ProgressModel::JobFailed);
+ return;
+ }
+
+ QString outFileName = generateOutFileName();
+ bool bSuccess = m_encoder->encode(m_audioFile, outFileName, &m_aborted);
+
+ if(bSuccess)
{
- if(m_aborted)
- {
- emit processStateChanged(m_jobId, "Aborted.", ProgressModel::JobFailed);
- return;
- }
-
- QThread::msleep(delay);
- emit processStateChanged(m_jobId, QString("Encoding (%1%)").arg(i), ProgressModel::JobRunning);
+ bSuccess = QFileInfo(outFileName).exists();
}
- emit processStateChanged(m_jobId, "Done (100%)", ProgressModel::JobComplete);
+ emit processStateChanged(m_jobId, (bSuccess ? "Done." : (m_aborted ? "Aborted!" : "Failed!")), (bSuccess ? ProgressModel::JobComplete : ProgressModel::JobFailed));
qDebug("Process thread is done.");
}
////////////////////////////////////////////////////////////
+// SLOTS
+////////////////////////////////////////////////////////////
+
+void ProcessThread::handleUpdate(int progress)
+{
+ emit processStateChanged(m_jobId, QString("Encoding (%1%)").arg(QString::number(progress)), ProgressModel::JobRunning);
+}
+
+////////////////////////////////////////////////////////////
+// PRIVAE FUNCTIONS
+////////////////////////////////////////////////////////////
+
+QString ProcessThread::generateOutFileName(void)
+{
+ int n = 1;
+
+ QString baseName = QFileInfo(m_audioFile.filePath()).completeBaseName();
+ QString targetDir = m_outputDirectory.isEmpty() ? QFileInfo(m_audioFile.filePath()).canonicalPath() : m_outputDirectory;
+ QDir(targetDir).mkpath(".");
+ QString outFileName = QString("%1/%2.%3").arg(targetDir, baseName, "mp3");
+
+ while(QFileInfo(outFileName).exists())
+ {
+ outFileName = QString("%1/%2 (%3).%4").arg(targetDir, baseName, QString::number(++n), m_encoder->extension());
+ }
+
+ return outFileName;
+}
+
+////////////////////////////////////////////////////////////
// EVENTS
////////////////////////////////////////////////////////////
#include <QUuid>
#include "Model_AudioFile.h"
+#include "Encoder_Abstract.h"
class ProcessThread: public QThread
{
Q_OBJECT
public:
- ProcessThread(AudioFileModel audioFile);
+ ProcessThread(const AudioFileModel &audioFile, const QString &outputDirectory, AbstractEncoder *encoder);
~ProcessThread(void);
void run();
void abort() { m_aborted = true; }
QUuid getId() { return m_jobId; }
+private slots:
+ void handleUpdate(int progress);
+
signals:
void processStateInitialized(const QUuid &jobId, const QString &jobName, const QString &jobInitialStatus, int jobInitialState);
void processStateChanged(const QUuid &jobId, const QString &newStatus, int newState);
private:
+ QString generateOutFileName(void);
+
const QUuid m_jobId;
AudioFileModel m_audioFile;
+ AbstractEncoder *m_encoder;
+ const QString m_outputDirectory;
volatile bool m_aborted;
};