Added optional support for the QAAC encoder. Requires QuickTime v7.7.1 (or later) and the QAAC front-end.

This commit is contained in:
LoRd_MuldeR 2011-11-21 01:22:41 +01:00
parent 346985876f
commit da5dfdc85e
18 changed files with 823 additions and 434 deletions

View File

@ -272,6 +272,7 @@ del "$(TargetDir)imageformats\q???d4.dll"
<ClCompile Include="src\Dialog_WorkingBanner.cpp" /> <ClCompile Include="src\Dialog_WorkingBanner.cpp" />
<ClCompile Include="src\Encoder_AAC.cpp" /> <ClCompile Include="src\Encoder_AAC.cpp" />
<ClCompile Include="src\Encoder_AAC_FHG.cpp" /> <ClCompile Include="src\Encoder_AAC_FHG.cpp" />
<ClCompile Include="src\Encoder_AAC_QAAC.cpp" />
<ClCompile Include="src\Encoder_Abstract.cpp" /> <ClCompile Include="src\Encoder_Abstract.cpp" />
<ClCompile Include="src\Encoder_AC3.cpp" /> <ClCompile Include="src\Encoder_AC3.cpp" />
<ClCompile Include="src\Encoder_FLAC.cpp" /> <ClCompile Include="src\Encoder_FLAC.cpp" />
@ -322,6 +323,7 @@ del "$(TargetDir)imageformats\q???d4.dll"
<ClCompile Include="tmp\MOC_Dialog_WorkingBanner.cpp" /> <ClCompile Include="tmp\MOC_Dialog_WorkingBanner.cpp" />
<ClCompile Include="tmp\MOC_Encoder_AAC.cpp" /> <ClCompile Include="tmp\MOC_Encoder_AAC.cpp" />
<ClCompile Include="tmp\MOC_Encoder_AAC_FHG.cpp" /> <ClCompile Include="tmp\MOC_Encoder_AAC_FHG.cpp" />
<ClCompile Include="tmp\MOC_Encoder_AAC_QAAC.cpp" />
<ClCompile Include="tmp\MOC_Encoder_Abstract.cpp" /> <ClCompile Include="tmp\MOC_Encoder_Abstract.cpp" />
<ClCompile Include="tmp\MOC_Encoder_AC3.cpp" /> <ClCompile Include="tmp\MOC_Encoder_AC3.cpp" />
<ClCompile Include="tmp\MOC_Encoder_FLAC.cpp" /> <ClCompile Include="tmp\MOC_Encoder_FLAC.cpp" />
@ -436,6 +438,17 @@ del "$(TargetDir)imageformats\q???d4.dll"
<Outputs Condition="'$(Configuration)|$(Platform)'=='Release_Static|Win32'">$(SolutionDir)tmp\MOC_%(Filename).cpp;%(Outputs)</Outputs> <Outputs Condition="'$(Configuration)|$(Platform)'=='Release_Static|Win32'">$(SolutionDir)tmp\MOC_%(Filename).cpp;%(Outputs)</Outputs>
<Outputs Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">$(SolutionDir)tmp\MOC_%(Filename).cpp;%(Outputs)</Outputs> <Outputs Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">$(SolutionDir)tmp\MOC_%(Filename).cpp;%(Outputs)</Outputs>
</CustomBuild> </CustomBuild>
<CustomBuild Include="src\Encoder_AAC_QAAC.h">
<Command Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">"$(QTDIR)\bin\moc.exe" -o "$(SolutionDir)tmp\MOC_%(Filename).cpp" "%(FullPath)"</Command>
<Message Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">MOC "$(SolutionDir)tmp\MOC_%(Filename).cpp"</Message>
<Outputs Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">$(SolutionDir)tmp\MOC_%(Filename).cpp;%(Outputs)</Outputs>
<Outputs Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">$(SolutionDir)tmp\MOC_%(Filename).cpp;%(Outputs)</Outputs>
<Outputs Condition="'$(Configuration)|$(Platform)'=='Release_Static|Win32'">$(SolutionDir)tmp\MOC_%(Filename).cpp;%(Outputs)</Outputs>
<Message Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">MOC "$(SolutionDir)tmp\MOC_%(Filename).cpp"</Message>
<Message Condition="'$(Configuration)|$(Platform)'=='Release_Static|Win32'">MOC "$(SolutionDir)tmp\MOC_%(Filename).cpp"</Message>
<Command Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">"$(QTDIR)\bin\moc.exe" -o "$(SolutionDir)tmp\MOC_%(Filename).cpp" "%(FullPath)"</Command>
<Command Condition="'$(Configuration)|$(Platform)'=='Release_Static|Win32'">"$(QTDIR)\bin\moc.exe" -o "$(SolutionDir)tmp\MOC_%(Filename).cpp" "%(FullPath)"</Command>
</CustomBuild>
<ClInclude Include="src\Tools.h" /> <ClInclude Include="src\Tools.h" />
<ClInclude Include="tmp\UIC_CueSheetImport.h" /> <ClInclude Include="tmp\UIC_CueSheetImport.h" />
<ClInclude Include="tmp\UIC_DropBox.h" /> <ClInclude Include="tmp\UIC_DropBox.h" />

View File

@ -334,6 +334,12 @@
<ClCompile Include="tmp\MOC_Thread_RAMObserver.cpp"> <ClCompile Include="tmp\MOC_Thread_RAMObserver.cpp">
<Filter>Generated Files\MOC</Filter> <Filter>Generated Files\MOC</Filter>
</ClCompile> </ClCompile>
<ClCompile Include="src\Encoder_AAC_QAAC.cpp">
<Filter>Source Files\Encoders</Filter>
</ClCompile>
<ClCompile Include="tmp\MOC_Encoder_AAC_QAAC.cpp">
<Filter>Generated Files\MOC</Filter>
</ClCompile>
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<ClInclude Include="src\Config.h"> <ClInclude Include="src\Config.h">
@ -626,6 +632,9 @@
<CustomBuild Include="src\Thread_RAMObserver.h"> <CustomBuild Include="src\Thread_RAMObserver.h">
<Filter>Header Files\Threads</Filter> <Filter>Header Files\Threads</Filter>
</CustomBuild> </CustomBuild>
<CustomBuild Include="src\Encoder_AAC_QAAC.h">
<Filter>Header Files\Encoders</Filter>
</CustomBuild>
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<None Include="res\MainIcon.ico" /> <None Include="res\MainIcon.ico" />

View File

@ -17,7 +17,9 @@ a:visited { color: #0000EE; }
<h3>LameXP - Version History</h3><br> <h3>LameXP - Version History</h3><br>
<a name="4.04"></a>Changes between v4.03 and v4.04:<br><ul> <a name="4.04"></a>Changes between v4.03 and v4.04:<br><ul>
<li>Added support for the QAAC Encoder, requires QuickTime v7.7.1 or newer (see <a href="FAQ.html#71a113b0" target="_blank">FAQ doc</a> for details)
<li>Updated LAME encoder to v3.99.2 Final (2011-11-18), compiled with ICL 12.1.7 and MSVC 10.0 (<a href="http://lame.cvs.sourceforge.net/viewvc/lame/lame/doc/html/history.html?revision=1.134" target="_blank">details</a>) <li>Updated LAME encoder to v3.99.2 Final (2011-11-18), compiled with ICL 12.1.7 and MSVC 10.0 (<a href="http://lame.cvs.sourceforge.net/viewvc/lame/lame/doc/html/history.html?revision=1.134" target="_blank">details</a>)
<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 in order to reduce the CPU usage of the LameXP process <li>Implemented coalescing of update signals in order to reduce the CPU usage of the LameXP process
</ul><br> </ul><br>

View File

@ -304,6 +304,7 @@ the same directory where your LameXP executable ('LameXP.exe') is located. For u
use any suitable archiver, such as <a href="http://rarlabs.com/download.htm" target="_blank">WinRAR</a> or <a href="http://sevenzip.sourceforge.net/" target="_blank">7-Zip</a>. Once the required Nero encoder binaries are located in<br> use any suitable archiver, such as <a href="http://rarlabs.com/download.htm" target="_blank">WinRAR</a> or <a href="http://sevenzip.sourceforge.net/" target="_blank">7-Zip</a>. Once the required Nero encoder binaries are located in<br>
the LameXP directory, the AAC encoding option should be "enabled" on the next startup of LameXP.<br> the LameXP directory, the AAC encoding option should be "enabled" on the next startup of LameXP.<br>
<br> <br>
<br>
Optionally LameXP also supports the FHG AAC Encoder now. Just like the Nero encoder, the FHG encoder can NOT<br> Optionally LameXP also supports the FHG AAC Encoder now. Just like the Nero encoder, the FHG encoder can NOT<br>
be redistributed along with LameXP. However the FHG AAC Encoder is included with Winamp v5.62, which is<br> be redistributed along with LameXP. However the FHG AAC Encoder is included with Winamp v5.62, which is<br>
available as a free download (you don't need to buy the "Pro" version!) from the official Winamp web-site at:<br><ul> available as a free download (you don't need to buy the "Pro" version!) from the official Winamp web-site at:<br><ul>
@ -320,7 +321,17 @@ In order to enable the FHG AAC Encoder support you will also need the 'FHG AAC E
<li><a href="http://uploaded.to/file/0h0c7qf6" target="_blank">http://uploaded.to/file/0h0c7qf6</a></ul> <li><a href="http://uploaded.to/file/0h0c7qf6" target="_blank">http://uploaded.to/file/0h0c7qf6</a></ul>
<br> <br>
Please follow the install instructions that are included with the 'FHG AAC Encoder Add-in' download package!<br> Please follow the install instructions that are included with the 'FHG AAC Encoder Add-in' download package!<br>
Note that you do NOT need to install the Add-in, if you only want to use the Nero AAC Encoder.<br><br> Note that you do NOT need to install the Add-in, if you only want to use the Nero AAC Encoder.<br>
<br>
<br>
As a third option, LameXP supports the QAAC encoder, i.e. the AAC encoder of QuickTime/iTunes. Just like the<br>
other two AAC encoders, the QAAC encoder can NOT be redistributed along with LameXP. Thus if you want to use<br>
the QAAC encoder, then you have to install QuickTime v7.7.1 (or newer). Alternatively iTunes v10.5 (or newer)<br>
can be installed. Both, QuickTime and iTunes, can be <a href="http://www.apple.com/quicktime/download/" target="_blank">downloaded for free</a> from the official Apple web-site.<br>
<br>
In addition to installing QuickTime/iTunes, you must download the QAAC encoder from <a href="http://sites.google.com/site/qaacpage/" target="_blank">this</a> web-site. Then put<br>
'qaac.exe' and 'libsoxrate.dll' as well as 'msvcr100.dll' and 'msvcp100.dll' into the same directory where<br>
your LameXP executable ('LameXP.exe') is located. QAAC will then be "enabled" on the next startup of LameXP.<br><br>
<br><br> <br><br>

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -29,8 +29,8 @@
#define VER_LAMEXP_MINOR_HI 0 #define VER_LAMEXP_MINOR_HI 0
#define VER_LAMEXP_MINOR_LO 4 #define VER_LAMEXP_MINOR_LO 4
#define VER_LAMEXP_TYPE Alpha #define VER_LAMEXP_TYPE Alpha
#define VER_LAMEXP_PATCH 1 #define VER_LAMEXP_PATCH 2
#define VER_LAMEXP_BUILD 781 #define VER_LAMEXP_BUILD 782
/////////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////////
// Tools versions // Tools versions
@ -38,6 +38,7 @@
#define VER_LAMEXP_TOOL_NEROAAC 1540 #define VER_LAMEXP_TOOL_NEROAAC 1540
#define VER_LAMEXP_TOOL_FHGAACENC 20110822 #define VER_LAMEXP_TOOL_FHGAACENC 20110822
#define VER_LAMEXP_TOOL_QAAC 104
/////////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////////
// Helper macros (aka: having fun with the C pre-processor) // Helper macros (aka: having fun with the C pre-processor)

View File

@ -90,6 +90,7 @@ MainWindow::MainWindow(FileListModel *fileListModel, AudioFileModel *metaInfo, S
m_settings(settingsModel), m_settings(settingsModel),
m_neroEncoderAvailable(lamexp_check_tool("neroAacEnc.exe") && lamexp_check_tool("neroAacDec.exe") && lamexp_check_tool("neroAacTag.exe")), m_neroEncoderAvailable(lamexp_check_tool("neroAacEnc.exe") && lamexp_check_tool("neroAacDec.exe") && lamexp_check_tool("neroAacTag.exe")),
m_fhgEncoderAvailable(lamexp_check_tool("fhgaacenc.exe") && lamexp_check_tool("enc_fhgaac.dll") && lamexp_check_tool("nsutil.dll") && lamexp_check_tool("libmp4v2.dll")), m_fhgEncoderAvailable(lamexp_check_tool("fhgaacenc.exe") && lamexp_check_tool("enc_fhgaac.dll") && lamexp_check_tool("nsutil.dll") && lamexp_check_tool("libmp4v2.dll")),
m_qaacEncoderAvailable(lamexp_check_tool("qaac.exe") && lamexp_check_tool("libsoxrate.dll") && lamexp_check_tool("msvcp100.dll") && lamexp_check_tool("msvcr100.dll")),
m_accepted(false), m_accepted(false),
m_firstTimeShown(true), m_firstTimeShown(true),
m_OutputFolderViewInitialized(false) m_OutputFolderViewInitialized(false)
@ -207,10 +208,10 @@ MainWindow::MainWindow(FileListModel *fileListModel, AudioFileModel *metaInfo, S
m_modeButtonGroup->addButton(radioButtonModeQuality, SettingsModel::VBRMode); m_modeButtonGroup->addButton(radioButtonModeQuality, SettingsModel::VBRMode);
m_modeButtonGroup->addButton(radioButtonModeAverageBitrate, SettingsModel::ABRMode); m_modeButtonGroup->addButton(radioButtonModeAverageBitrate, SettingsModel::ABRMode);
m_modeButtonGroup->addButton(radioButtonConstBitrate, SettingsModel::CBRMode); m_modeButtonGroup->addButton(radioButtonConstBitrate, SettingsModel::CBRMode);
radioButtonEncoderAAC->setEnabled(m_neroEncoderAvailable || m_fhgEncoderAvailable); radioButtonEncoderAAC->setEnabled(m_neroEncoderAvailable || m_fhgEncoderAvailable || m_qaacEncoderAvailable);
radioButtonEncoderMP3->setChecked(m_settings->compressionEncoder() == SettingsModel::MP3Encoder); radioButtonEncoderMP3->setChecked(m_settings->compressionEncoder() == SettingsModel::MP3Encoder);
radioButtonEncoderVorbis->setChecked(m_settings->compressionEncoder() == SettingsModel::VorbisEncoder); radioButtonEncoderVorbis->setChecked(m_settings->compressionEncoder() == SettingsModel::VorbisEncoder);
radioButtonEncoderAAC->setChecked((m_settings->compressionEncoder() == SettingsModel::AACEncoder) && (m_neroEncoderAvailable || m_fhgEncoderAvailable)); radioButtonEncoderAAC->setChecked((m_settings->compressionEncoder() == SettingsModel::AACEncoder) && (m_neroEncoderAvailable || m_fhgEncoderAvailable || m_qaacEncoderAvailable));
radioButtonEncoderAC3->setChecked(m_settings->compressionEncoder() == SettingsModel::AC3Encoder); radioButtonEncoderAC3->setChecked(m_settings->compressionEncoder() == SettingsModel::AC3Encoder);
radioButtonEncoderFLAC->setChecked(m_settings->compressionEncoder() == SettingsModel::FLACEncoder); radioButtonEncoderFLAC->setChecked(m_settings->compressionEncoder() == SettingsModel::FLACEncoder);
radioButtonEncoderPCM->setChecked(m_settings->compressionEncoder() == SettingsModel::PCMEncoder); radioButtonEncoderPCM->setChecked(m_settings->compressionEncoder() == SettingsModel::PCMEncoder);
@ -246,7 +247,7 @@ MainWindow::MainWindow(FileListModel *fileListModel, AudioFileModel *metaInfo, S
while(checkBoxUseSystemTempFolder->isChecked() == m_settings->customTempPathEnabled()) checkBoxUseSystemTempFolder->click(); while(checkBoxUseSystemTempFolder->isChecked() == m_settings->customTempPathEnabled()) checkBoxUseSystemTempFolder->click();
while(checkBoxRenameOutput->isChecked() != m_settings->renameOutputFilesEnabled()) checkBoxRenameOutput->click(); while(checkBoxRenameOutput->isChecked() != m_settings->renameOutputFilesEnabled()) checkBoxRenameOutput->click();
while(checkBoxForceStereoDownmix->isChecked() != m_settings->forceStereoDownmix()) checkBoxForceStereoDownmix->click(); while(checkBoxForceStereoDownmix->isChecked() != m_settings->forceStereoDownmix()) checkBoxForceStereoDownmix->click();
checkBoxNeroAAC2PassMode->setEnabled(!m_fhgEncoderAvailable); checkBoxNeroAAC2PassMode->setEnabled(!(m_fhgEncoderAvailable || m_qaacEncoderAvailable));
lineEditCustomParamLAME->setText(m_settings->customParametersLAME()); lineEditCustomParamLAME->setText(m_settings->customParametersLAME());
lineEditCustomParamOggEnc->setText(m_settings->customParametersOggEnc()); lineEditCustomParamOggEnc->setText(m_settings->customParametersOggEnc());
lineEditCustomParamNeroAAC->setText(m_settings->customParametersAacEnc()); lineEditCustomParamNeroAAC->setText(m_settings->customParametersAacEnc());
@ -1042,7 +1043,7 @@ void MainWindow::windowShown(void)
} }
else else
{ {
if(m_settings->neroAacNotificationsEnabled() && (!m_fhgEncoderAvailable)) if(m_settings->neroAacNotificationsEnabled() && (!(m_fhgEncoderAvailable || m_qaacEncoderAvailable)))
{ {
QString appPath = QDir(QCoreApplication::applicationDirPath()).canonicalPath(); QString appPath = QDir(QCoreApplication::applicationDirPath()).canonicalPath();
if(appPath.isEmpty()) appPath = QCoreApplication::applicationDirPath(); if(appPath.isEmpty()) appPath = QCoreApplication::applicationDirPath();

View File

@ -160,6 +160,7 @@ private:
const bool m_neroEncoderAvailable; const bool m_neroEncoderAvailable;
const bool m_fhgEncoderAvailable; const bool m_fhgEncoderAvailable;
const bool m_qaacEncoderAvailable;
WorkingBanner *m_banner; WorkingBanner *m_banner;
QStringList *m_delayedFileList; QStringList *m_delayedFileList;

View File

@ -35,6 +35,7 @@
#include "Encoder_Vorbis.h" #include "Encoder_Vorbis.h"
#include "Encoder_AAC.h" #include "Encoder_AAC.h"
#include "Encoder_AAC_FHG.h" #include "Encoder_AAC_FHG.h"
#include "Encoder_AAC_QAAC.h"
#include "Encoder_AC3.h" #include "Encoder_AC3.h"
#include "Encoder_FLAC.h" #include "Encoder_FLAC.h"
#include "Encoder_Wave.h" #include "Encoder_Wave.h"
@ -660,7 +661,16 @@ void ProcessingDialog::startNextJob(void)
break; break;
case SettingsModel::AACEncoder: case SettingsModel::AACEncoder:
{ {
if(lamexp_check_tool("fhgaacenc.exe") && lamexp_check_tool("enc_fhgaac.dll")) if(lamexp_check_tool("qaac.exe") && lamexp_check_tool("libsoxrate.dll"))
{
QAACEncoder *aacEncoder = new QAACEncoder();
aacEncoder->setBitrate(m_settings->compressionBitrate());
aacEncoder->setRCMode(m_settings->compressionRCMode());
aacEncoder->setProfile(m_settings->aacEncProfile());
aacEncoder->setCustomParams(m_settings->customParametersAacEnc());
encoder = aacEncoder;
}
else if(lamexp_check_tool("fhgaacenc.exe") && lamexp_check_tool("enc_fhgaac.dll"))
{ {
FHGAACEncoder *aacEncoder = new FHGAACEncoder(); FHGAACEncoder *aacEncoder = new FHGAACEncoder();
aacEncoder->setBitrate(m_settings->compressionBitrate()); aacEncoder->setBitrate(m_settings->compressionBitrate());

View File

@ -54,7 +54,7 @@ bool AACEncoder::encode(const QString &sourceFile, const AudioFileModel &metaInf
switch(m_configRCMode) switch(m_configRCMode)
{ {
case SettingsModel::VBRMode: case SettingsModel::VBRMode:
args << "-q" << QString().sprintf("%.2f", qMin(1.0, qMax(0.0, static_cast<double>(m_configBitrate * 5) / 100.0))); args << "-q" << QString().sprintf("%.2f", qBound(0.0, static_cast<double>(m_configBitrate * 5) / 100.0, 1.0));
break; break;
case SettingsModel::ABRMode: case SettingsModel::ABRMode:
args << "-br" << QString::number(qMax(32, qMin(500, (m_configBitrate * 8))) * 1000); args << "-br" << QString::number(qMax(32, qMin(500, (m_configBitrate * 8))) * 1000);

184
src/Encoder_AAC_QAAC.cpp Normal file
View File

@ -0,0 +1,184 @@
///////////////////////////////////////////////////////////////////////////////
// LameXP - Audio Encoder Front-End
// Copyright (C) 2004-2011 LoRd_MuldeR <MuldeR2@GMX.de>
//
// 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 "Encoder_AAC_QAAC.h"
#include "Global.h"
#include "Model_Settings.h"
#include <math.h>
#include <QProcess>
#include <QDir>
QAACEncoder::QAACEncoder(void)
:
m_binary_enc(lamexp_lookup_tool("qaac.exe")),
m_binary_dll(lamexp_lookup_tool("libsoxrate.dll"))
{
if(m_binary_enc.isEmpty() || m_binary_dll.isEmpty())
{
throw "Error initializing QAAC. Tool 'qaac.exe' is not registred!";
}
m_configProfile = 0;
}
QAACEncoder::~QAACEncoder(void)
{
}
bool QAACEncoder::encode(const QString &sourceFile, const AudioFileModel &metaInfo, const QString &outputFile, volatile bool *abortFlag)
{
QProcess process;
QStringList args;
if(m_configRCMode != SettingsModel::VBRMode)
{
switch(m_configProfile)
{
case 2:
case 3:
args << "--he"; //Forces use of HE AAC profile (there is no explicit HEv2 switch for QAAC)
break;
}
}
switch(m_configRCMode)
{
case SettingsModel::CBRMode:
args << "--cbr" << QString::number(qBound(32, m_configBitrate * 8, 500));
break;
case SettingsModel::ABRMode:
args << "--abr" << QString::number(qBound(32, m_configBitrate * 8, 500));
break;
case SettingsModel::VBRMode:
args << "--tvbr" << QString::number(qBound(0, qRound((static_cast<double>(m_configBitrate * 5) / 100.0) * 127.0), 127));
break;
default:
throw "Bad rate-control mode!";
break;
}
if(!m_configCustomParams.isEmpty()) args << m_configCustomParams.split(" ", QString::SkipEmptyParts);
if(!metaInfo.fileName().isEmpty()) args << "--title" << metaInfo.fileName();
if(!metaInfo.fileArtist().isEmpty()) args << "--artist" << metaInfo.fileArtist();
if(!metaInfo.fileAlbum().isEmpty()) args << "--album" << metaInfo.fileAlbum();
if(!metaInfo.fileGenre().isEmpty()) args << "--genre" << metaInfo.fileGenre();
if(!metaInfo.fileComment().isEmpty()) args << "--comment" << metaInfo.fileComment();
if(metaInfo.fileYear()) args << "--date" << QString::number(metaInfo.fileYear());
if(metaInfo.filePosition()) args << "--track" << QString::number(metaInfo.filePosition());
if(!metaInfo.fileCover().isEmpty()) args << "--artwork" << metaInfo.fileCover();
args << "-o" << QDir::toNativeSeparators(outputFile);
args << QDir::toNativeSeparators(sourceFile);
if(!startProcess(process, m_binary_enc, args))
{
return false;
}
bool bTimeout = false;
bool bAborted = false;
int prevProgress = -1;
QRegExp regExp("\\[(\\d+)\\.(\\d)%\\]");
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("QAAC 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 = false;
int progress = regExp.cap(1).toInt(&ok);
if(ok && (progress > prevProgress))
{
emit statusUpdated(progress);
prevProgress = qMin(progress + 2, 99);
}
}
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)
{
return false;
}
return true;
}
QString QAACEncoder::extension(void)
{
return "mp4";
}
bool QAACEncoder::isFormatSupported(const QString &containerType, const QString &containerProfile, const QString &formatType, const QString &formatProfile, const QString &formatVersion)
{
if(containerType.compare("Wave", Qt::CaseInsensitive) == 0)
{
if(formatType.compare("PCM", Qt::CaseInsensitive) == 0)
{
return true;
}
}
return false;
}
void QAACEncoder::setProfile(int profile)
{
m_configProfile = profile;
}

47
src/Encoder_AAC_QAAC.h Normal file
View File

@ -0,0 +1,47 @@
///////////////////////////////////////////////////////////////////////////////
// LameXP - Audio Encoder Front-End
// Copyright (C) 2004-2011 LoRd_MuldeR <MuldeR2@GMX.de>
//
// 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 "Encoder_Abstract.h"
#include <QObject>
class QAACEncoder : public AbstractEncoder
{
Q_OBJECT
public:
QAACEncoder(void);
~QAACEncoder(void);
virtual bool encode(const QString &sourceFile, const AudioFileModel &metaInfo, const QString &outputFile, volatile bool *abortFlag);
virtual bool isFormatSupported(const QString &containerType, const QString &containerProfile, const QString &formatType, const QString &formatProfile, const QString &formatVersion);
virtual QString extension(void);
//Advanced options
virtual void setProfile(int profile);
private:
const QString m_binary_enc;
const QString m_binary_dll;
int m_configProfile;
};

View File

@ -169,6 +169,7 @@ static const char *g_lamexp_support_url = "http://forum.doom9.org/showthread.php
//Tool versions (expected versions!) //Tool versions (expected versions!)
static const unsigned int g_lamexp_toolver_neroaac = VER_LAMEXP_TOOL_NEROAAC; static const unsigned int g_lamexp_toolver_neroaac = VER_LAMEXP_TOOL_NEROAAC;
static const unsigned int g_lamexp_toolver_fhgaacenc = VER_LAMEXP_TOOL_FHGAACENC; static const unsigned int g_lamexp_toolver_fhgaacenc = VER_LAMEXP_TOOL_FHGAACENC;
static const unsigned int g_lamexp_toolver_qaacenc = VER_LAMEXP_TOOL_QAAC;
//Special folders //Special folders
static QString g_lamexp_temp_folder; static QString g_lamexp_temp_folder;
@ -239,7 +240,7 @@ const char *lamexp_version_compiler(void) { return g_lamexp_version_compiler; }
const char *lamexp_version_arch(void) { return g_lamexp_version_arch; } const char *lamexp_version_arch(void) { return g_lamexp_version_arch; }
unsigned int lamexp_toolver_neroaac(void) { return g_lamexp_toolver_neroaac; } unsigned int lamexp_toolver_neroaac(void) { return g_lamexp_toolver_neroaac; }
unsigned int lamexp_toolver_fhgaacenc(void) { return g_lamexp_toolver_fhgaacenc; } unsigned int lamexp_toolver_fhgaacenc(void) { return g_lamexp_toolver_fhgaacenc; }
unsigned int lamexp_toolver_qaacenc(void) { return g_lamexp_toolver_qaacenc; }
/* /*
* URL getters * URL getters
*/ */

View File

@ -81,6 +81,7 @@ const char *lamexp_version_arch(void);
QDate lamexp_version_expires(void); QDate lamexp_version_expires(void);
unsigned int lamexp_toolver_neroaac(void); unsigned int lamexp_toolver_neroaac(void);
unsigned int lamexp_toolver_fhgaacenc(void); unsigned int lamexp_toolver_fhgaacenc(void);
unsigned int lamexp_toolver_qaacenc(void);
const char *lamexp_website_url(void); const char *lamexp_website_url(void);
const char *lamexp_support_url(void); const char *lamexp_support_url(void);
DWORD lamexp_get_os_version(void); DWORD lamexp_get_os_version(void);

View File

@ -221,6 +221,8 @@ void SettingsModel::validate(void)
if(!(lamexp_check_tool("neroAacEnc.exe") && lamexp_check_tool("neroAacDec.exe") && lamexp_check_tool("neroAacTag.exe"))) if(!(lamexp_check_tool("neroAacEnc.exe") && lamexp_check_tool("neroAacDec.exe") && lamexp_check_tool("neroAacTag.exe")))
{ {
if(!(lamexp_check_tool("fhgaacenc.exe") && lamexp_check_tool("enc_fhgaac.dll"))) if(!(lamexp_check_tool("fhgaacenc.exe") && lamexp_check_tool("enc_fhgaac.dll")))
{
if(!(lamexp_check_tool("qaac.exe") && lamexp_check_tool("libsoxrate.dll")))
{ {
if(this->compressionEncoder() == SettingsModel::AACEncoder) if(this->compressionEncoder() == SettingsModel::AACEncoder)
{ {
@ -229,6 +231,7 @@ void SettingsModel::validate(void)
} }
} }
} }
}
if(this->outputDir().isEmpty() || !QFileInfo(this->outputDir()).isDir()) if(this->outputDir().isEmpty() || !QFileInfo(this->outputDir()).isDir())
{ {

View File

@ -202,11 +202,10 @@ void InitializationThread::run()
//Register all translations //Register all translations
initTranslations(); initTranslations();
//Look for Nero AAC encoder //Look for AAC encoders
initNeroAac(); initNeroAac();
//Look for FHG AAC encoder
initFhgAac(); initFhgAac();
initQAac();
delay(); delay();
m_bSuccess = true; m_bSuccess = true;
@ -482,6 +481,111 @@ void InitializationThread::initFhgAac(void)
} }
} }
void InitializationThread::initQAac(void)
{
const QString appPath = QDir(QCoreApplication::applicationDirPath()).canonicalPath();
QFileInfo qaacFileInfo[4];
qaacFileInfo[0] = QFileInfo(QString("%1/qaac.exe").arg(appPath));
qaacFileInfo[1] = QFileInfo(QString("%1/libsoxrate.dll").arg(appPath));
qaacFileInfo[2] = QFileInfo(QString("%1/msvcp100.dll").arg(appPath));
qaacFileInfo[3] = QFileInfo(QString("%1/msvcr100.dll").arg(appPath));
bool qaacFilesFound = true;
for(int i = 0; i < 4; i++) { if(!qaacFileInfo[i].exists()) qaacFilesFound = false; }
//Lock the FhgAacEnc binaries
if(!qaacFilesFound)
{
qDebug("QAAC binaries not found -> QAAC support will be disabled!\n");
return;
}
qDebug("Found QAAC encoder:\n%s\n", qaacFileInfo[0].canonicalFilePath().toUtf8().constData());
LockedFile *qaacBin[4];
for(int i = 0; i < 4; i++) qaacBin[i] = NULL;
try
{
for(int i = 0; i < 4; i++)
{
qaacBin[i] = new LockedFile(qaacFileInfo[i].canonicalFilePath());
}
}
catch(...)
{
for(int i = 0; i < 4; i++) LAMEXP_DELETE(qaacBin[i]);
qWarning("Failed to get excluive lock to FhgAacEnc binary -> FhgAacEnc support will be disabled!");
return;
}
QProcess process;
process.setProcessChannelMode(QProcess::MergedChannels);
process.setReadChannel(QProcess::StandardOutput);
process.start(qaacFileInfo[0].canonicalFilePath(), QStringList());
if(!process.waitForStarted())
{
qWarning("QAAC process failed to create!");
qWarning("Error message: \"%s\"\n", process.errorString().toLatin1().constData());
process.kill();
process.waitForFinished(-1);
for(int i = 0; i < 4; i++) LAMEXP_DELETE(qaacBin[i]);
return;
}
QRegExp qaacEncSig("qaac (\\d)\\.(\\d)(\\d)", Qt::CaseInsensitive);
unsigned int qaacVersion = 0;
while(process.state() != QProcess::NotRunning)
{
process.waitForReadyRead();
if(!process.bytesAvailable() && process.state() == QProcess::Running)
{
qWarning("QAAC process time out -> killing!");
process.kill();
process.waitForFinished(-1);
for(int i = 0; i < 4; i++) LAMEXP_DELETE(qaacBin[i]);
return;
}
while(process.bytesAvailable() > 0)
{
QString line = QString::fromUtf8(process.readLine().constData()).simplified();
if(qaacEncSig.lastIndexIn(line) >= 0)
{
unsigned int tmp[3] = {0, 0, 0};
bool ok[3] = {false, false, false};
tmp[0] = qaacEncSig.cap(1).toUInt(&ok[0]);
tmp[1] = qaacEncSig.cap(2).toUInt(&ok[1]);
tmp[2] = qaacEncSig.cap(3).toUInt(&ok[2]);
if(ok[0] && ok[1] && ok[2])
{
qaacVersion = (qBound(0U, tmp[0], 9U) * 100) + (qBound(0U, tmp[1], 9U) * 10) + qBound(0U, tmp[2], 9U);
}
}
}
}
if(!(qaacVersion > 0))
{
qWarning("QAAC version couldn't be determined -> QAAC support will be disabled!");
for(int i = 0; i < 4; i++) LAMEXP_DELETE(qaacBin[i]);
return;
}
else if(qaacVersion < lamexp_toolver_qaacenc())
{
qWarning("QAAC version is too much outdated -> QAAC support will be disabled!");
for(int i = 0; i < 4; i++) LAMEXP_DELETE(qaacBin[i]);
return;
}
for(int i = 0; i < 4; i++)
{
lamexp_register_tool(qaacFileInfo[i].fileName(), qaacBin[i], qaacVersion);
}
}
void InitializationThread::selfTest(void) void InitializationThread::selfTest(void)
{ {
const unsigned int cpu[4] = {CPU_TYPE_X86_GEN, CPU_TYPE_X86_SSE, CPU_TYPE_X64_GEN, CPU_TYPE_X64_SSE}; const unsigned int cpu[4] = {CPU_TYPE_X86_GEN, CPU_TYPE_X86_SSE, CPU_TYPE_X64_GEN, CPU_TYPE_X64_SSE};

View File

@ -45,6 +45,7 @@ private:
void initTranslations(void); void initTranslations(void);
void initNeroAac(void); void initNeroAac(void);
void initFhgAac(void); void initFhgAac(void);
void initQAac(void);
bool m_bSuccess; bool m_bSuccess;
lamexp_cpu_t m_cpuFeatures; lamexp_cpu_t m_cpuFeatures;