diff --git a/gui/MainWindow.ui b/gui/MainWindow.ui
index 1bfba613..679524b1 100644
--- a/gui/MainWindow.ui
+++ b/gui/MainWindow.ui
@@ -7,7 +7,7 @@
0
0
676
- 550
+ 459
@@ -503,7 +503,7 @@
- Automatically generate playlist (.m3u)
+ Automatically generate playlist file (.m3u)
true
@@ -545,70 +545,284 @@
-
-
-
-
-
-
- true
+
+
-
+
+
+
+ 0
+ 75
+
-
- QFrame::StyledPanel
+
+
+ 50
+ false
+
-
- QFrame::Sunken
-
-
-
-
-
- :/images/Construction.gif
-
-
- Qt::AlignCenter
+
+ Encoder / Format
+
+
-
+
+
-
+
+
+ Lame MP3
+
+
+ true
+
+
+
+ -
+
+
+ Ogg Vorbis
+
+
+
+ -
+
+
+ Nero AAC
+
+
+
+ -
+
+
+ Wave (PCM)
+
+
+
+ -
+
+
+ FLAC
+
+
+
+ -
+
+
+ Qt::Horizontal
+
+
+ QSizePolicy::Fixed
+
+
+
+ 10
+ 20
+
+
+
+
+
+
+
- -
-
-
- Qt::Horizontal
-
-
+
-
+
+
- 40
- 20
+ 0
+ 75
-
-
- -
-
-
- Qt::Horizontal
+
+
+ 50
+ false
+
-
+
+ Rate Control Method
+
+
+
-
+
+
-
+
+
+ Quality-based (VBR)
+
+
+ true
+
+
+
+ -
+
+
+ Average Bitrate (ABR)
+
+
+
+ -
+
+
+ Constant Bitrate (CBR)
+
+
+
+ -
+
+
+ Qt::Horizontal
+
+
+ QSizePolicy::Fixed
+
+
+
+ 10
+ 20
+
+
+
+
+
+
+
+
+
+ -
+
+
- 40
- 20
+ 0
+ 100
-
-
- -
-
-
- Qt::Vertical
+
+
+ 50
+ false
+
-
-
- 20
- 40
-
+
+ Quality / Bitrate
-
+
+
-
+
+
-
+
+
+ 4
+
+
+ 50
+
+
+ 24
+
+
+ true
+
+
+ Qt::Horizontal
+
+
+ false
+
+
+ QSlider::TicksBelow
+
+
+ 5
+
+
+
+ -
+
+
+ Minimum
+
+
+ Qt::AlignLeading|Qt::AlignLeft|Qt::AlignTop
+
+
+
+ -
+
+
+ Maximum
+
+
+ Qt::AlignRight|Qt::AlignTop|Qt::AlignTrailing
+
+
+
+ -
+
+
+ (VALUE)
+
+
+ Qt::AlignHCenter|Qt::AlignTop
+
+
+
+ -
+
+
+ Qt::Vertical
+
+
+ QSizePolicy::Fixed
+
+
+
+ 20
+ 8
+
+
+
+
+ -
+
+
+ Qt::Horizontal
+
+
+ QSizePolicy::Fixed
+
+
+
+ 10
+ 20
+
+
+
+
+ -
+
+
+ Qt::Horizontal
+
+
+ QSizePolicy::Fixed
+
+
+
+ 10
+ 20
+
+
+
+
+
+
+
+
- -
-
+
-
+
Qt::Vertical
@@ -637,6 +851,9 @@
-
+
+ ForbiddenCursor
+
QFrame::StyledPanel
@@ -647,7 +864,7 @@
- :/images/Construction.gif
+ :/images/Cogwheels.png
Qt::AlignCenter
@@ -1052,6 +1269,26 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/res/Images.qrc b/res/Images.qrc
index 4a8c71cd..1a75d719 100644
--- a/res/Images.qrc
+++ b/res/Images.qrc
@@ -3,12 +3,13 @@
images/Busy.gif
images/HeaderIcon_MetaInfo.png
- images/Label.png
- images/Loading.gif
- images/Logo.png
- images/Splash.png
- images/Thumb.png
+ images/Label.png
+ images/Loading.gif
+ images/Logo.png
+ images/Splash.png
+ images/Thumb.png
images/Construction.gif
+ images/Cogwheels.png
images/Qt.svg
diff --git a/res/images/Cogwheels.png b/res/images/Cogwheels.png
new file mode 100644
index 00000000..5590ab8f
Binary files /dev/null and b/res/images/Cogwheels.png differ
diff --git a/src/Dialog_About.cpp b/src/Dialog_About.cpp
index 9c57d79b..e07788e4 100644
--- a/src/Dialog_About.cpp
+++ b/src/Dialog_About.cpp
@@ -36,6 +36,13 @@
//Helper macros
#define LINK(URL) QString("%2").arg(URL).arg(URL)
+//Constants
+const char *AboutDialog::neroAacUrl = "http://www.nero.com/eng/technologies-aac-codec.html";
+
+////////////////////////////////////////////////////////////
+// Constructor
+////////////////////////////////////////////////////////////
+
AboutDialog::AboutDialog(QWidget *parent)
: QMessageBox(parent)
{
@@ -83,6 +90,10 @@ AboutDialog::~AboutDialog(void)
{
}
+////////////////////////////////////////////////////////////
+// Public Functions
+////////////////////////////////////////////////////////////
+
int AboutDialog::exec()
{
PlaySound(MAKEINTRESOURCE(IDR_WAVE_ABOUT), GetModuleHandle(NULL), SND_RESOURCE | SND_ASYNC);
@@ -105,30 +116,32 @@ int AboutDialog::exec()
return 0;
}
+////////////////////////////////////////////////////////////
+// Private Functions
+////////////////////////////////////////////////////////////
+
void AboutDialog::showMoreAbout()
{
- const QString li("");
-
QString moreAboutText;
moreAboutText += "The following third-party software is used in LameXP:
";
- moreAboutText += "";
- moreAboutText += li + "LAME - OpenSource mp3 Encoder
";
+ moreAboutText += "";
+ moreAboutText += "- LAME - OpenSource mp3 Encoder
";
moreAboutText += "Released under the terms of the GNU Leser General Public License.
";
moreAboutText += LINK("http://lame.sourceforge.net/");
moreAboutText += "
";
- moreAboutText += li + "OggEnc - Ogg Vorbis Encoder";
+ moreAboutText += " - OggEnc - Ogg Vorbis Encoder";
moreAboutText += "
Completely open and patent-free audio encoding technology.
";
moreAboutText += LINK("http://www.vorbis.com/");
moreAboutText += "
";
- moreAboutText += li + "Nero AAC reference MPEG-4 Encoder
";
+ moreAboutText += " - Nero AAC reference MPEG-4 Encoder
";
moreAboutText += "Freeware state-of-the-art HE-AAC encoder with 2-Pass support.
";
moreAboutText += "(Available from vendor web-site as free download)
";
- moreAboutText += LINK("http://www.nero.com/eng/technologies-aac-codec.html/");
+ moreAboutText += LINK(neroAacUrl);
moreAboutText += "
";
- moreAboutText += li + "MediaInfo - Media File Analysis Tool
";
+ moreAboutText += " - MediaInfo - Media File Analysis Tool
";
moreAboutText += "Released under the terms of the GNU Leser General Public License.
";
moreAboutText += LINK("http://mediainfo.sourceforge.net/");
- moreAboutText += "
";
+ moreAboutText += "
";
QMessageBox *moreAboutBox = new QMessageBox(dynamic_cast(this->parent()));
moreAboutBox->setText(moreAboutText);
diff --git a/src/Dialog_About.h b/src/Dialog_About.h
index adfe5363..f597d60f 100644
--- a/src/Dialog_About.h
+++ b/src/Dialog_About.h
@@ -30,6 +30,7 @@ public:
public slots:
int exec();
+ static const char *neroAacUrl;
private:
void AboutDialog::showMoreAbout();
diff --git a/src/Dialog_MainWindow.cpp b/src/Dialog_MainWindow.cpp
index 34c12b5e..13ad56b5 100644
--- a/src/Dialog_MainWindow.cpp
+++ b/src/Dialog_MainWindow.cpp
@@ -56,9 +56,8 @@ if(m_banner->isVisible() || m_delayedFileTimer->isActive()) \
{ \
MessageBeep(MB_ICONEXCLAMATION); \
return; \
-} \
-
-#define LINK(X) ""
+}
+#define LINK(URL) QString("%2").arg(URL).arg(URL)
////////////////////////////////////////////////////////////
// Constructor
@@ -129,6 +128,11 @@ MainWindow::MainWindow(QWidget *parent)
connect(buttonEditMeta, SIGNAL(clicked()), this, SLOT(editMetaButtonClicked()));
connect(buttonClearMeta, SIGNAL(clicked()), this, SLOT(clearMetaButtonClicked()));
+ //Setup "Compression" tab
+ sliderBitrate->setValue(24);
+ connect(sliderBitrate, SIGNAL(valueChanged(int)), this, SLOT(updateBitrate(int)));
+ updateBitrate(sliderBitrate->value());
+
//Activate file menu actions
connect(actionOpenFolder, SIGNAL(triggered()), this, SLOT(openFolderActionActivated()));
@@ -265,6 +269,23 @@ void MainWindow::windowShown(void)
{
QStringList arguments = QApplication::arguments();
+ //Check for AAC support
+ if(lamexp_check_tool("neroAacEnc.exe") && lamexp_check_tool("neroAacDec.exe") && lamexp_check_tool("neroAacTag.exe"))
+ {
+ radioButtonEncoderAAC->setEnabled(true);
+ }
+ else
+ {
+ QString messageText;
+ messageText += "The Nero AAC encoder could not be found. AAC encoding support will be disabled.
";
+ messageText += "Please put 'neroAacEnc.exe', 'neroAacDec.exe' and 'neroAacTag.exe' into the LameXP directory!
";
+ messageText += "You can download the Nero AAC encoder for free from the official Nero web-site at:
";
+ messageText += "" + LINK(AboutDialog::neroAacUrl) + "
";
+ QMessageBox::information(this, "AAC Support Disabled", messageText);
+ radioButtonEncoderAAC->setEnabled(false);
+ }
+
+ //Add files from the command-line
for(int i = 0; i < arguments.count() - 1; i++)
{
if(!arguments[i].compare("--add", Qt::CaseInsensitive))
@@ -659,3 +680,11 @@ void MainWindow::handleDelayedFiles(void)
addFiles(selectedFiles);
}
+
+/*
+ * Update bitrate
+ */
+void MainWindow::updateBitrate(int value)
+{
+ labelBitrate->setText(QString("%1 kbps").arg(value * 8));
+}
diff --git a/src/Dialog_MainWindow.h b/src/Dialog_MainWindow.h
index af40ec63..ba14f3a9 100644
--- a/src/Dialog_MainWindow.h
+++ b/src/Dialog_MainWindow.h
@@ -66,6 +66,7 @@ private slots:
void handleDelayedFiles(void);
void editMetaButtonClicked(void);
void clearMetaButtonClicked(void);
+ void updateBitrate(int value);
protected:
void showEvent(QShowEvent *event);
diff --git a/src/Global.cpp b/src/Global.cpp
index b46715db..d9ea178d 100644
--- a/src/Global.cpp
+++ b/src/Global.cpp
@@ -285,8 +285,10 @@ int lamexp_init_ipc(void)
return 0;
}
- g_lamexp_semaphore_read_ptr = new QSystemSemaphore(g_lamexp_semaphore_read_uuid, 0);
- g_lamexp_semaphore_write_ptr = new QSystemSemaphore(g_lamexp_semaphore_write_uuid, 0);
+ const QString versionTag = QString().sprintf("@%d.%02d.%04d", lamexp_version_major(), lamexp_version_minor(), lamexp_version_build());
+
+ g_lamexp_semaphore_read_ptr = new QSystemSemaphore(QString(g_lamexp_semaphore_read_uuid).append(versionTag), 0);
+ g_lamexp_semaphore_write_ptr = new QSystemSemaphore(QString(g_lamexp_semaphore_write_uuid).append(versionTag), 0);
if(g_lamexp_semaphore_read_ptr->error() != QSystemSemaphore::NoError)
{
@@ -305,7 +307,7 @@ int lamexp_init_ipc(void)
return -1;
}
- g_lamexp_sharedmem_ptr = new QSharedMemory(g_lamexp_sharedmem_uuid, NULL);
+ g_lamexp_sharedmem_ptr = new QSharedMemory(QString(g_lamexp_sharedmem_uuid).append(versionTag), NULL);
if(!g_lamexp_sharedmem_ptr->create(sizeof(lamexp_ipc_t)))
{
@@ -495,20 +497,28 @@ void lamexp_finalization(void)
*/
void lamexp_register_tool(const QString &toolName, LockedFile *file)
{
- if(g_lamexp_tool_registry.contains(toolName))
+ if(g_lamexp_tool_registry.contains(toolName.toLower()))
{
throw "lamexp_register_tool: Tool is already registered!";
}
- g_lamexp_tool_registry.insert(toolName, file);
+ g_lamexp_tool_registry.insert(toolName.toLower(), file);
}
/*
- * Register tool
+ * Check for tool
+ */
+bool lamexp_check_tool(const QString &toolName)
+{
+ return g_lamexp_tool_registry.contains(toolName.toLower());
+}
+
+/*
+ * Lookup tool
*/
const QString lamexp_lookup_tool(const QString &toolName)
{
- if(g_lamexp_tool_registry.contains(toolName))
+ if(g_lamexp_tool_registry.contains(toolName.toLower()))
{
return g_lamexp_tool_registry.value(toolName)->filePath();
}
diff --git a/src/Global.h b/src/Global.h
index b2163223..0e03f37c 100644
--- a/src/Global.h
+++ b/src/Global.h
@@ -49,6 +49,7 @@ void lamexp_init_console(int argc, char* argv[]);
bool lamexp_init_qt(int argc, char* argv[]);
int lamexp_init_ipc(void);
void lamexp_register_tool(const QString &toolName, LockedFile *file);
+bool lamexp_check_tool(const QString &toolName);
const QString lamexp_lookup_tool(const QString &toolName);
void lamexp_finalization(void);
const QString &lamexp_temp_folder(void);
diff --git a/src/LockedFile.cpp b/src/LockedFile.cpp
index ce1c1650..1206d0b9 100644
--- a/src/LockedFile.cpp
+++ b/src/LockedFile.cpp
@@ -44,16 +44,16 @@ LockedFile::LockedFile(const QString &resourcePath, const QString &outPath, cons
if(outFile.write(reinterpret_cast(resource.data()), resource.size()) != resource.size())
{
QFile::remove(QFileInfo(outFile).absoluteFilePath());
- char error_msg[256];
- strcpy_s(error_msg, 256, QString("File '%1' could not be written!").arg(QFileInfo(outFile).fileName()).toUtf8().constData());
+ char error_msg[512];
+ strcpy_s(error_msg, 512, QString("File '%1' could not be written!").arg(QFileInfo(outFile).fileName()).toUtf8().constData());
throw error_msg;
}
outFile.close();
}
else
{
- char error_msg[256];
- strcpy_s(error_msg, 256, QString("File '%1' could not be created!").arg(QFileInfo(outFile).fileName()).toUtf8().constData());
+ char error_msg[512];
+ strcpy_s(error_msg, 512, QString("File '%1' could not be created!").arg(QFileInfo(outFile).fileName()).toUtf8().constData());
throw error_msg;
}
@@ -63,8 +63,8 @@ LockedFile::LockedFile(const QString &resourcePath, const QString &outPath, cons
if(m_fileHandle == INVALID_HANDLE_VALUE)
{
QFile::remove(QFileInfo(outFile).absoluteFilePath());
- char error_msg[256];
- strcpy_s(error_msg, 256, QString("File '%1' could not be locked!").arg(QFileInfo(outFile).fileName()).toLatin1().constData());
+ char error_msg[512];
+ strcpy_s(error_msg, 512, QString("File '%1' could not be locked!").arg(QFileInfo(outFile).fileName()).toLatin1().constData());
throw error_msg;
}
@@ -82,8 +82,31 @@ LockedFile::LockedFile(const QString &resourcePath, const QString &outPath, cons
qWarning("\nFile checksum error:\n Expected = %040s\n Detected = %040s\n", expectedHash.constData(), fileHash.result().toHex().constData());
LAMEXP_CLOSE(m_fileHandle);
QFile::remove(QFileInfo(outFile).absoluteFilePath());
+ char error_msg[512];
+ strcpy_s(error_msg, 512, QString("File '%1' is corruputed, take care!").arg(QFileInfo(outFile).fileName()).toLatin1().constData());
+ throw error_msg;
+ }
+}
+
+LockedFile::LockedFile(const QString &filePath)
+{
+ m_fileHandle = NULL;
+ QFileInfo existingFile(filePath);
+
+ if(!existingFile.exists())
+ {
char error_msg[256];
- strcpy_s(error_msg, 256, QString("File '%1' is corruputed, take care!").arg(QFileInfo(outFile).fileName()).toLatin1().constData());
+ strcpy_s(error_msg, 256, QString("File '%1' does not exist!").arg(existingFile.fileName()).toLatin1().constData());
+ throw error_msg;
+ }
+
+ //Now lock the file
+ m_fileHandle = CreateFileW(QWCHAR(QDir::toNativeSeparators(filePath)), GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, NULL, NULL);
+
+ if(m_fileHandle == INVALID_HANDLE_VALUE)
+ {
+ char error_msg[256];
+ strcpy_s(error_msg, 256, QString("File '%1' could not be locked!").arg(existingFile.fileName()).toLatin1().constData());
throw error_msg;
}
}
diff --git a/src/LockedFile.h b/src/LockedFile.h
index 17064499..b0bf28f0 100644
--- a/src/LockedFile.h
+++ b/src/LockedFile.h
@@ -27,6 +27,7 @@ class LockedFile
{
public:
LockedFile(const QString &resourcePath, const QString &outPath, const QByteArray &expectedHash = QByteArray());
+ LockedFile(const QString &filePath);
~LockedFile(void);
const QString &filePath();
diff --git a/src/Thread_Initialization.cpp b/src/Thread_Initialization.cpp
index 241febfe..57911550 100644
--- a/src/Thread_Initialization.cpp
+++ b/src/Thread_Initialization.cpp
@@ -24,6 +24,9 @@
#include "Global.h"
#include "LockedFile.h"
+#include
+#include
+
////////////////////////////////////////////////////////////
// TOOLS
////////////////////////////////////////////////////////////
@@ -43,7 +46,6 @@ static const struct lamexp_tool_t g_lamexp_tools[] =
{"e613a1b56a2187edb4cdf3628a5a3e60de2e8cbc", "lame.exe"},
{"775b260b3f64101beaeb317b74746f9bccdab842", "MAC.exe"},
{"e770eaa5f2449d0fd6b3f3c02a1f574fc4370b5e", "mediainfo_icl11.exe"},
-// {"6f57f93b597f143453c6a30ee0bc9d161afe2e4b", "mediainfo_msvc9.exe"},
{"55c293a80475f7aeccf449ac9487a4626e5139cb", "mpcdec.exe"},
{"8bbf4a3fffe2ff143eb5ba2cf82ca16d676e865d", "mpg123.exe"},
{"437a1b193727c3dbdd557b9a58659d1ce7fbec51", "oggdec.exe"},
@@ -114,6 +116,37 @@ void InitializationThread::run()
}
qDebug("All extracted.\n");
+
+ //Look for Nero encoder
+ QFileInfo neroFileInfo[3];
+ neroFileInfo[0] = QFileInfo(QString("%1/neroAacEnc.exe").arg(QCoreApplication::applicationDirPath()));
+ neroFileInfo[1] = QFileInfo(QString("%1/neroAacDec.exe").arg(QCoreApplication::applicationDirPath()));
+ neroFileInfo[2] = QFileInfo(QString("%1/neroAacTag.exe").arg(QCoreApplication::applicationDirPath()));
+
+ bool neroFilesFound = true;
+ for(int i = 0; i < 3; i++) { if(!neroFileInfo[i].exists()) neroFilesFound = false; }
+
+ //Lock the Nero binaries
+ if(neroFilesFound)
+ {
+ qDebug("Found Nero AAC encoder binary:\n%s\n", neroFileInfo[0].absoluteFilePath().toUtf8().constData());
+ LockedFile *neroBin[3];
+ for(int i = 0; i < 3; i++) neroBin[i] = NULL;
+ try
+ {
+ for(int i = 0; i < 3; i++) { neroBin[i] = new LockedFile(neroFileInfo[i].absoluteFilePath()); }
+ for(int i = 0; i < 3; i++) { lamexp_register_tool(neroFileInfo[i].fileName(), neroBin[i]); }
+ }
+ catch(...)
+ {
+ for(int i = 0; i < 3; i++) LAMEXP_DELETE(neroBin[i]);
+ qWarning("Failed to lock Nero encoder binary -> AAC encoding support will be disabled!");
+ }
+ }
+ else
+ {
+ qDebug("Nero encoder binaries not found -> AAC encoding support will be disabled!\n");
+ }
delay();
m_bSuccess = true;