diff --git a/LameXP.vcproj b/LameXP.vcproj index 62029661..3a4ec4c7 100644 --- a/LameXP.vcproj +++ b/LameXP.vcproj @@ -290,6 +290,10 @@ Filter="cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx" UniqueIdentifier="{4FC737F1-C7A5-4376-A066-2A32D752A2FF}" > + + @@ -428,6 +432,10 @@ RelativePath=".\src\Config.h" > + + @@ -437,7 +445,7 @@ @@ -447,7 +455,7 @@ @@ -457,7 +465,7 @@ @@ -1157,7 +1165,7 @@ @@ -1167,7 +1175,7 @@ @@ -1177,7 +1185,7 @@ diff --git a/etc/NSIS/setup.nsi b/etc/NSIS/setup.nsi index d2a7a1c3..e5869bf8 100644 --- a/etc/NSIS/setup.nsi +++ b/etc/NSIS/setup.nsi @@ -77,10 +77,6 @@ Function .onInit ${EndSwitch} FunctionEnd -Function .onInstSuccess - !insertmacro UAC_AsUser_Call Function LaunchApplication ${UAC_SYNCINSTDIR} -FunctionEnd - !insertmacro SECTION_BEGIN File /r `${LAMEXP_SOURCE_PATH}\*.*` !insertmacro SECTION_END @@ -102,7 +98,8 @@ Function CheckForUpdate SendMessage $R1 ${WM_SETTEXT} 0 "STR:Update" FunctionEnd -Function LaunchApplication - ExecShell "explore" "$INSTDIR" - Exec '"$INSTDIR\LameXP.exe"' +Function .onInstSuccess + StrCpy $R0 "$INSTDIR" + UAC_AsUser_ExecShell "explore" "$R0" "" "" SW_SHOWNORMAL + UAC_AsUser_ExecShell "open" "$R0\LameXP.exe" "" "$OUTDIR" SW_SHOWNORMAL FunctionEnd diff --git a/res/tools/faad.exe b/res/tools/faad.exe index d3defe1f..5e922bfa 100644 Binary files a/res/tools/faad.exe and b/res/tools/faad.exe differ diff --git a/res/tools/oggdec.exe b/res/tools/oggdec.exe index c5ee9055..f56ca7ae 100644 Binary files a/res/tools/oggdec.exe and b/res/tools/oggdec.exe differ diff --git a/src/Config.h b/src/Config.h index 9d5bd259..0e418117 100644 --- a/src/Config.h +++ b/src/Config.h @@ -25,7 +25,7 @@ #define VER_LAMEXP_MAJOR 4 #define VER_LAMEXP_MINOR_HI 0 #define VER_LAMEXP_MINOR_LO 0 -#define VER_LAMEXP_BUILD 110 +#define VER_LAMEXP_BUILD 113 #define VER_LAMEXP_SUFFIX TechPreview /* diff --git a/src/Decoder_AAC.cpp b/src/Decoder_AAC.cpp new file mode 100644 index 00000000..8f0c9f5c --- /dev/null +++ b/src/Decoder_AAC.cpp @@ -0,0 +1,132 @@ +/////////////////////////////////////////////////////////////////////////////// +// LameXP - Audio Encoder Front-End +// Copyright (C) 2004-2010 LoRd_MuldeR +// +// This program is free software; you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation; either version 2 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License along +// with this program; if not, write to the Free Software Foundation, Inc., +// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +// +// http://www.gnu.org/licenses/gpl-2.0.txt +/////////////////////////////////////////////////////////////////////////////// + +#include "Decoder_AAC.h" + +#include "Global.h" + +#include +#include +#include + +AACDecoder::AACDecoder(void) +: + m_binary(lamexp_lookup_tool("faad.exe")) +{ + if(m_binary.isEmpty()) + { + throw "Error initializing AAC decoder. Tool 'faad.exe' is not registred!"; + } +} + +AACDecoder::~AACDecoder(void) +{ +} + +bool AACDecoder::decode(const QString &sourceFile, const QString &outputFile, volatile bool *abortFlag) +{ + QProcess process; + QStringList args; + + args << "-o" << QDir::toNativeSeparators(outputFile); + args << QDir::toNativeSeparators(sourceFile); + + if(!startProcess(process, m_binary, args)) + { + return false; + } + + bool bTimeout = false; + bool bAborted = false; + + QRegExp regExp("[^\\w](\\d+)%\\s+decoding\\s+"); + + while(process.state() != QProcess::NotRunning) + { + if(*abortFlag) + { + process.kill(); + bAborted = true; + emit messageLogged("\nABORTED BY USER !!!"); + break; + } + process.waitForReadyRead(); + if(!process.bytesAvailable() && process.state() == QProcess::Running) + { + process.kill(); + qWarning("FAAD process timed out <-- killing!"); + bTimeout = true; + break; + } + while(process.bytesAvailable() > 0) + { + QByteArray line = process.readLine(); + 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 messageLogged(text); + } + } + } + + process.waitForFinished(); + if(process.state() != QProcess::NotRunning) + { + process.kill(); + process.waitForFinished(-1); + } + + emit statusUpdated(100); + emit messageLogged(QString().sprintf("\nExited with code: 0x%04X", process.exitCode())); + + if(bTimeout || bAborted || process.exitStatus() != QProcess::NormalExit || QFileInfo(outputFile).size() == 0) + { + return false; + } + + return true; +} + +bool AACDecoder::isFormatSupported(const QString &containerType, const QString &containerProfile, const QString &formatType, const QString &formatProfile, const QString &formatVersion) +{ + if(containerType.compare("ADTS", Qt::CaseInsensitive) == 0 || containerType.compare("MPEG-4", Qt::CaseInsensitive) == 0) + { + if(formatType.compare("AAC", Qt::CaseInsensitive) == 0) + { + if(formatProfile.compare("LC", Qt::CaseInsensitive) == 0 || formatProfile.compare("HE", Qt::CaseInsensitive) == 0) + { + if(formatVersion.compare("Version 2", Qt::CaseInsensitive) == 0 || formatVersion.compare("Version 4", Qt::CaseInsensitive) == 0) + { + return true; + } + } + } + } + + return false; +} + diff --git a/src/Decoder_AAC.h b/src/Decoder_AAC.h new file mode 100644 index 00000000..186b7e2a --- /dev/null +++ b/src/Decoder_AAC.h @@ -0,0 +1,37 @@ +/////////////////////////////////////////////////////////////////////////////// +// LameXP - Audio Encoder Front-End +// Copyright (C) 2004-2010 LoRd_MuldeR +// +// This program is free software; you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation; either version 2 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License along +// with this program; if not, write to the Free Software Foundation, Inc., +// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +// +// http://www.gnu.org/licenses/gpl-2.0.txt +/////////////////////////////////////////////////////////////////////////////// + +#pragma once + +#include "Decoder_Abstract.h" + +class AACDecoder : public AbstractDecoder +{ +public: + AACDecoder(void); + ~AACDecoder(void); + + virtual bool decode(const QString &sourceFile, const QString &outputFile, volatile bool *abortFlag); + static bool isFormatSupported(const QString &containerType, const QString &containerProfile, const QString &formatType, const QString &formatProfile, const QString &formatVersion); + +private: + const QString m_binary; +}; diff --git a/src/Decoder_Vorbis.cpp b/src/Decoder_Vorbis.cpp index 9e94808d..b1cb23bf 100644 --- a/src/Decoder_Vorbis.cpp +++ b/src/Decoder_Vorbis.cpp @@ -46,8 +46,8 @@ bool VorbisDecoder::decode(const QString &sourceFile, const QString &outputFile, QProcess process; QStringList args; - args << "-w" << pathToShort(QDir::toNativeSeparators(outputFile)); - args << pathToShort(QDir::toNativeSeparators(sourceFile)); + args << "-w" << QDir::toNativeSeparators(outputFile); + args << QDir::toNativeSeparators(sourceFile); if(!startProcess(process, m_binary, args)) { diff --git a/src/Dialog_Processing.cpp b/src/Dialog_Processing.cpp index 2a49ba08..0550ae0e 100644 --- a/src/Dialog_Processing.cpp +++ b/src/Dialog_Processing.cpp @@ -47,6 +47,13 @@ #include +#define CHANGE_BACKGROUND_COLOR(WIDGET, COLOR) \ +{ \ + QPalette palette = WIDGET->palette(); \ + palette.setColor(QPalette::Background, COLOR); \ + WIDGET->setPalette(palette); \ +} + //////////////////////////////////////////////////////////// // Constructor //////////////////////////////////////////////////////////// @@ -203,6 +210,7 @@ void ProcessingDialog::initEncoding(void) m_userAborted = false; m_playList.clear(); + CHANGE_BACKGROUND_COLOR(frame_header, QColor(Qt::white)); label_progress->setText("Encoding files, please wait..."); m_progressIndicator->start(); @@ -223,6 +231,8 @@ void ProcessingDialog::abortEncoding(void) m_userAborted = true; button_AbortProcess->setEnabled(false); + label_progress->setText("Aborted! Waiting for running jobs to terminate..."); + for(int i = 0; i < m_threadList.count(); i++) { m_threadList.at(i)->abort(); @@ -232,9 +242,12 @@ void ProcessingDialog::abortEncoding(void) void ProcessingDialog::doneEncoding(void) { m_runningThreads--; - progressBar->setValue(progressBar->value() + 1); - label_progress->setText(QString("Encoding: %1 files of %2 completed so far, please wait...").arg(QString::number(progressBar->value()), QString::number(progressBar->maximum()))); + + if(!m_userAborted) + { + 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(QWidget::sender())); if(index >= 0) @@ -267,6 +280,7 @@ void ProcessingDialog::doneEncoding(void) if(m_userAborted) { + CHANGE_BACKGROUND_COLOR(frame_header, QColor("#FFF3BA")); label_progress->setText((m_succeededFiles > 0) ? QString("Process was aborted by the user after %1 file(s)!").arg(QString::number(m_succeededFiles)) : "Process was aborted prematurely by the user!"); QApplication::processEvents(); if(m_settings->soundsEnabled()) PlaySound(MAKEINTRESOURCE(IDR_WAVE_ABORTED), GetModuleHandle(NULL), SND_RESOURCE | SND_SYNC); @@ -275,12 +289,14 @@ void ProcessingDialog::doneEncoding(void) { if(m_failedFiles) { + CHANGE_BACKGROUND_COLOR(frame_header, QColor("#FFBABA")); label_progress->setText(QString("Error: %1 of %2 files failed. Double-click failed items for detailed information!").arg(QString::number(m_failedFiles), QString::number(m_failedFiles + m_succeededFiles))); QApplication::processEvents(); if(m_settings->soundsEnabled()) PlaySound(MAKEINTRESOURCE(IDR_WAVE_ERROR), GetModuleHandle(NULL), SND_RESOURCE | SND_SYNC); } else { + CHANGE_BACKGROUND_COLOR(frame_header, QColor("#D1FFD5")); label_progress->setText("Alle files completed successfully."); QApplication::processEvents(); if(m_settings->soundsEnabled()) PlaySound(MAKEINTRESOURCE(IDR_WAVE_SUCCESS), GetModuleHandle(NULL), SND_RESOURCE | SND_SYNC); diff --git a/src/Encoder_MP3.cpp b/src/Encoder_MP3.cpp index 2b983d51..39c297e9 100644 --- a/src/Encoder_MP3.cpp +++ b/src/Encoder_MP3.cpp @@ -132,6 +132,7 @@ bool MP3Encoder::encode(const QString &sourceFile, const AudioFileModel &metaInf process.waitForFinished(-1); } + emit statusUpdated(100); emit messageLogged(QString().sprintf("\nExited with code: 0x%04X", process.exitCode())); if(bTimeout || bAborted || process.exitStatus() != QProcess::NormalExit) diff --git a/src/Encoder_Vorbis.cpp b/src/Encoder_Vorbis.cpp index befd54c3..71beebab 100644 --- a/src/Encoder_Vorbis.cpp +++ b/src/Encoder_Vorbis.cpp @@ -132,6 +132,7 @@ bool VorbisEncoder::encode(const QString &sourceFile, const AudioFileModel &meta process.waitForFinished(-1); } + emit statusUpdated(100); emit messageLogged(QString().sprintf("\nExited with code: 0x%04X", process.exitCode())); if(bTimeout || bAborted || process.exitStatus() != QProcess::NormalExit) diff --git a/src/Registry_Decoder.cpp b/src/Registry_Decoder.cpp index 59cfe90b..f58395ca 100644 --- a/src/Registry_Decoder.cpp +++ b/src/Registry_Decoder.cpp @@ -21,7 +21,7 @@ #include "Registry_Decoder.h" -#include "Decoder_Abstract.h" +#include "Decoder_AAC.h" #include "Decoder_MP3.h" #include "Decoder_Vorbis.h" @@ -33,6 +33,7 @@ AbstractDecoder *DecoderRegistry::lookup(const QString &containerType, const QSt { PROBE_DECODER(MP3Decoder); PROBE_DECODER(VorbisDecoder); + PROBE_DECODER(AACDecoder); return NULL; } diff --git a/src/Thread_Initialization.cpp b/src/Thread_Initialization.cpp index 07071645..b8e561af 100644 --- a/src/Thread_Initialization.cpp +++ b/src/Thread_Initialization.cpp @@ -41,7 +41,7 @@ struct lamexp_tool_t static const struct lamexp_tool_t g_lamexp_tools[] = { {"153f4274702f3629093b561a31dbf50e2c146305", "alac.exe"}, - {"09e5a07555a24b8c9d6af880b81eb8ed75be16fd", "faad.exe"}, + {"fb4fc54913672d8167fed367280bc5d39cf16a27", "faad.exe"}, {"070bf98f78e572a97e4703ef5720c682567a6a56", "flac.exe"}, {"cf379081035ae6bfb6f7bc22f13bfb7ac6302ac5", "gpgv.exe"}, {"d837bf6ee4dab557d8b02d46c75a24e58980fffa", "gpgv.gpg"}, @@ -50,7 +50,7 @@ static const struct lamexp_tool_t g_lamexp_tools[] = {"e8719fbfd7b690b3e518489f7aae3915305711c2", "mediainfo_icl11.exe"}, {"55c293a80475f7aeccf449ac9487a4626e5139cb", "mpcdec.exe"}, {"8bbf4a3fffe2ff143eb5ba2cf82ca16d676e865d", "mpg123.exe"}, - {"437a1b193727c3dbdd557b9a58659d1ce7fbec51", "oggdec.exe"}, + {"380c734e3c3948a844b9fae213d53a93ab20beba", "oggdec.exe"}, {"ecd15abe103184aca96e406f5f1c82c6fb2e665d", "oggenc2_i386.exe"}, {"ffe0fbd73352396dc3752ac9d484dbfc754a226d", "oggenc2_sse2.exe"}, {"a8c50872e544a55495a824426e9378984f2ae01d", "oggenc2_x64.exe"},