<li>Updated MediaInfo to v0.7.51+ (2011-11-19), compiled with ICL 12.1.6 and MSVC 10.0
<li>Implemented coalescing of update signals to reduce the CPU usage of the LameXP process (<a href="http://forum.doom9.org/showpost.php?p=1539631&postcount=507" target="_blank">details</a>)
<li>Run more than four instances in parallel on systems with more than four CPU cores (<a href="FAQ.html#89cbd3d0" target="_blank">details</a>)
+<li>Workaround for a bug that causes MediaInfo to not detect the duration of Wave files (64-Bit only)
</ul><br>
<a name="4.03"></a>Changes between v4.02 and v4.03:<br><ul>
<body>
<h3>LameXP - User Manual</h3>
<br>
-<img src="http://img840.imageshack.us/img840/873/pagenotfoundman.jpg" alt="404" style="border-style:solid;border-width:1px;border-color:LightSteelBlue"><br>
+<img src="http://lamexp.sourceforge.net/lamexp.png" alt="404" border="0"><br>
<br>
<br>
Sorry, there is no LameXP user manual (yet), but we have an extensive F.A.Q. document ;-)<br>
copy "%~dp0\..\..\License.txt" "%TMP_PATH%"
copy "%~dp0\..\..\doc\Changelog.html" "%TMP_PATH%"
copy "%~dp0\..\..\doc\Translate.html" "%TMP_PATH%"
+copy "%~dp0\..\..\doc\Manual.html" "%TMP_PATH%"
copy "%~dp0\..\..\doc\FAQ.html" "%TMP_PATH%"
REM ------------------------------------------
REM :: CREATE PACKAGES ::
CreateShortCut "$SMPROGRAMS\$StartMenuFolder\$(LAMEXP_LANG_LINK_CHANGELOG).lnk" "$INSTDIR\Changelog.html"
CreateShortCut "$SMPROGRAMS\$StartMenuFolder\$(LAMEXP_LANG_LINK_TRANSLATE).lnk" "$INSTDIR\Translate.html"
CreateShortCut "$SMPROGRAMS\$StartMenuFolder\$(LAMEXP_LANG_LINK_FAQ).lnk" "$INSTDIR\FAQ.html"
+ CreateShortCut "$SMPROGRAMS\$StartMenuFolder\$(LAMEXP_LANG_LINK_MANUAL).lnk" "$INSTDIR\FAQ.html"
CreateShortCut "$SMPROGRAMS\$StartMenuFolder\$(LAMEXP_LANG_LINK_UNINSTALL).lnk" "$INSTDIR\Uninstall.exe" "" "$INSTDIR\Uninstall.exe" 0
!insertmacro CreateWebLink "$SMPROGRAMS\$StartMenuFolder\Official LameXP Homepage.url" "http://mulder.dummwiedeutsch.de/"
LangString LAMEXP_LANG_LINK_TRANSLATE ${LANG_ENGLISH} "Translator's Guide"
LangString LAMEXP_LANG_LINK_UNINSTALL ${LANG_ENGLISH} "Uninstall"
LangString LAMEXP_LANG_LINK_FAQ ${LANG_ENGLISH} "Frequently Asked Questions"
+LangString LAMEXP_LANG_LINK_MANUAL ${LANG_ENGLISH} "User Manual"
LangString LAMEXP_LANG_PRERELEASE_WARNING ${LANG_ENGLISH} "You are about to install a Demo (pre-release) version of LameXP!"
</message>
<message>
<location filename="../../src/Dialog_Update.cpp" line="424"/>
- <location filename="../../src/Dialog_Update.cpp" line="1006"/>
<source>Network connectivity test has failed!</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../../src/Dialog_Update.cpp" line="427"/>
- <location filename="../../src/Dialog_Update.cpp" line="1009"/>
<source>Please make sure your internet connection is working properly and try again.</source>
<translation type="unfinished"></translation>
</message>
LangString LAMEXP_LANG_LINK_TRANSLATE ${LANG_GERMAN} "Leitfaden für Übersetzer"
LangString LAMEXP_LANG_LINK_UNINSTALL ${LANG_GERMAN} "Deinstallieren"
LangString LAMEXP_LANG_LINK_FAQ ${LANG_GERMAN} "Häufig Gestellte Fragen"
+LangString LAMEXP_LANG_LINK_MANUAL ${LANG_GERMAN} "Benutzerhandbuch"
LangString LAMEXP_LANG_PRERELEASE_WARNING ${LANG_GERMAN} "Sie sind dabei eine Demo (Test) Version von LameXP zu installieren!"
LangString LAMEXP_LANG_LINK_TRANSLATE ${LANG_SPANISH} "Guía de traducción"
LangString LAMEXP_LANG_LINK_UNINSTALL ${LANG_SPANISH} "Desinstalar"
LangString LAMEXP_LANG_LINK_FAQ ${LANG_SPANISH} "Preguntas frecuentes"
+LangString LAMEXP_LANG_LINK_MANUAL ${LANG_SPANISH} "User Manual"
LangString LAMEXP_LANG_PRERELEASE_WARNING ${LANG_SPANISH} "You are about to install a Demo (pre-release) version of LameXP!"
</message>
<message>
<location filename="../../src/Dialog_Update.cpp" line="424"/>
- <location filename="../../src/Dialog_Update.cpp" line="1006"/>
<source>Network connectivity test has failed!</source>
<translation type="unfinished">Test połączenia internetowego zakończony niepowodzeniem!</translation>
</message>
<message>
<location filename="../../src/Dialog_Update.cpp" line="427"/>
- <location filename="../../src/Dialog_Update.cpp" line="1009"/>
<source>Please make sure your internet connection is working properly and try again.</source>
<translation type="unfinished">Upewnij się że połączenie internetowe działa prawidłowo i spróbuj ponownie.</translation>
</message>
LangString LAMEXP_LANG_LINK_TRANSLATE ${LANG_RUSSIAN} "Руководство Переводчика"
LangString LAMEXP_LANG_LINK_UNINSTALL ${LANG_RUSSIAN} "Деинсталляция"
LangString LAMEXP_LANG_LINK_FAQ ${LANG_RUSSIAN} "Часто Задаваемые Вопросы"
+LangString LAMEXP_LANG_LINK_MANUAL ${LANG_RUSSIAN} "User Manual"
LangString LAMEXP_LANG_PRERELEASE_WARNING ${LANG_RUSSIAN} "Вы собираетесь установить ДЕМО (пред-релизную) версию LameXP!"
LangString LAMEXP_LANG_LINK_TRANSLATE ${LANG_UKRAINIAN} "Допомога Перекладачу"
LangString LAMEXP_LANG_LINK_UNINSTALL ${LANG_UKRAINIAN} "Видалення"
LangString LAMEXP_LANG_LINK_FAQ ${LANG_UKRAINIAN} "Часті Питання"
+LangString LAMEXP_LANG_LINK_MANUAL ${LANG_UKRAINIAN} "User Manual"
LangString LAMEXP_LANG_PRERELEASE_WARNING ${LANG_UKRAINIAN} "Ви збираєтесь встановити Демо (тестову) версію LameXP!"
#define VER_LAMEXP_MINOR_HI 0
#define VER_LAMEXP_MINOR_LO 4
#define VER_LAMEXP_TYPE Alpha
-#define VER_LAMEXP_PATCH 6
-#define VER_LAMEXP_BUILD 801
+#define VER_LAMEXP_PATCH 7
+#define VER_LAMEXP_BUILD 802
///////////////////////////////////////////////////////////////////////////////
// Tool versions (minimum expected versions!)
AACEncoder::AACEncoder(void)
:
m_binary_enc(lamexp_lookup_tool("neroAacEnc.exe")),
- m_binary_tag(lamexp_lookup_tool("neroAacTag.exe"))
+ m_binary_tag(lamexp_lookup_tool("neroAacTag.exe")),
+ m_binary_sox(lamexp_lookup_tool("sox.exe"))
{
- if(m_binary_enc.isEmpty() || m_binary_tag.isEmpty())
+ if(m_binary_enc.isEmpty() || m_binary_tag.isEmpty() || m_binary_sox.isEmpty())
{
throw "Error initializing AAC encoder. Tool 'neroAacEnc.exe' is not registred!";
}
bool AACEncoder::encode(const QString &sourceFile, const AudioFileModel &metaInfo, const QString &outputFile, volatile bool *abortFlag)
{
+ const unsigned int fileDuration = (metaInfo.fileDuration() > 0) ? metaInfo.fileDuration() : detectLength(sourceFile, abortFlag);
+
QProcess process;
QStringList args;
const QString baseName = QFileInfo(outputFile).fileName();
{
bool ok = false;
int progress = regExp_pass1.cap(1).toInt(&ok);
- if(ok && metaInfo.fileDuration() > 0)
+ if(ok && (fileDuration > 0))
{
- int newProgress = qRound((static_cast<double>(progress) / static_cast<double>(metaInfo.fileDuration())) * 50.0);
+ int newProgress = qRound((static_cast<double>(progress) / static_cast<double>(fileDuration)) * 50.0);
if(newProgress > prevProgress)
{
emit statusUpdated(newProgress);
{
bool ok = false;
int progress = regExp_pass2.cap(1).toInt(&ok);
- if(ok && metaInfo.fileDuration() > 0)
+ if(ok && (fileDuration > 0))
{
- int newProgress = qRound((static_cast<double>(progress) / static_cast<double>(metaInfo.fileDuration())) * 50.0) + 50;
+ int newProgress = qRound((static_cast<double>(progress) / static_cast<double>(fileDuration)) * 50.0) + 50;
if(newProgress > prevProgress)
{
emit statusUpdated(newProgress);
{
bool ok = false;
int progress = regExp.cap(1).toInt(&ok);
- if(ok && metaInfo.fileDuration() > 0)
+ if(ok && (fileDuration > 0))
{
- int newProgress = qRound((static_cast<double>(progress) / static_cast<double>(metaInfo.fileDuration())) * 100.0);
+ int newProgress = qRound((static_cast<double>(progress) / static_cast<double>(fileDuration)) * 100.0);
if(newProgress > prevProgress)
{
emit statusUpdated(newProgress);
return true;
}
+unsigned int AACEncoder::detectLength(const QString &sourceFile, volatile bool *abortFlag)
+{
+ unsigned int duration = 0;
+
+ QProcess process;
+ QStringList args;
+
+ args << "--i" << sourceFile;
+
+ if(!startProcess(process, m_binary_sox, args))
+ {
+ return duration;
+ }
+
+ bool bTimeout = false;
+ bool bAborted = false;
+
+ QRegExp regExp("Duration\\s*:\\s*(\\d\\d):(\\d\\d):(\\d\\d)\\.(\\d\\d)", Qt::CaseInsensitive);
+
+ while(process.state() != QProcess::NotRunning)
+ {
+ if(*abortFlag)
+ {
+ process.kill();
+ bAborted = true;
+ emit messageLogged("\nABORTED BY USER !!!");
+ break;
+ }
+ process.waitForReadyRead(m_processTimeoutInterval);
+ if(!process.bytesAvailable() && process.state() == QProcess::Running)
+ {
+ process.kill();
+ qWarning("SoX process timed out <-- killing!");
+ emit messageLogged("\nPROCESS TIMEOUT !!!");
+ 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[4] = {false, false, false, false};
+ unsigned int tmp1 = regExp.cap(1).toUInt(&ok[0]);
+ unsigned int tmp2 = regExp.cap(2).toUInt(&ok[1]);
+ unsigned int tmp3 = regExp.cap(3).toUInt(&ok[2]);
+ unsigned int tmp4 = regExp.cap(4).toUInt(&ok[3]);
+ if(ok[0] && ok[1] && ok[2] && ok[3])
+ {
+ duration = (tmp1 * 3600) + (tmp2 * 60) + tmp3 + qRound(static_cast<double>(tmp4) / 100.0);
+ }
+ }
+ if(!text.isEmpty())
+ {
+ emit messageLogged(text);
+ }
+ }
+ }
+
+ process.waitForFinished();
+ if(process.state() != QProcess::NotRunning)
+ {
+ process.kill();
+ process.waitForFinished(-1);
+ }
+
+ //qWarning("Duration detected is: %u", duration);
+ return duration;
+}
+
QString AACEncoder::extension(void)
{
return "mp4";
return false;
}
-
void AACEncoder::setProfile(int profile)
{
m_configProfile = profile;
private:
const QString m_binary_enc;
const QString m_binary_tag;
+ const QString m_binary_sox;
int m_configProfile;
bool m_configEnable2Pass;
+
+ unsigned int detectLength(const QString &sourceFile, volatile bool *abortFlag);
};