Initial ATSC A/52 (aka "AC-3", aka "Dolby Digital") encoding support, based on the Aften encoder.

This commit is contained in:
LoRd_MuldeR 2011-05-04 01:15:05 +02:00
parent 6a6ac5396d
commit be71e483b1
15 changed files with 243 additions and 10 deletions

View File

@ -254,6 +254,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_Abstract.cpp" /> <ClCompile Include="src\Encoder_Abstract.cpp" />
<ClCompile Include="src\Encoder_AC3.cpp" />
<ClCompile Include="src\Encoder_FLAC.cpp" /> <ClCompile Include="src\Encoder_FLAC.cpp" />
<ClCompile Include="src\Encoder_MP3.cpp" /> <ClCompile Include="src\Encoder_MP3.cpp" />
<ClCompile Include="src\Encoder_Vorbis.cpp" /> <ClCompile Include="src\Encoder_Vorbis.cpp" />
@ -297,6 +298,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_Abstract.cpp" /> <ClCompile Include="tmp\MOC_Encoder_Abstract.cpp" />
<ClCompile Include="tmp\MOC_Encoder_AC3.cpp" />
<ClCompile Include="tmp\MOC_Encoder_FLAC.cpp" /> <ClCompile Include="tmp\MOC_Encoder_FLAC.cpp" />
<ClCompile Include="tmp\MOC_Encoder_MP3.cpp" /> <ClCompile Include="tmp\MOC_Encoder_MP3.cpp" />
<ClCompile Include="tmp\MOC_Encoder_Vorbis.cpp" /> <ClCompile Include="tmp\MOC_Encoder_Vorbis.cpp" />
@ -325,6 +327,11 @@ del "$(TargetDir)imageformats\q???d4.dll"
<ItemGroup> <ItemGroup>
<ClInclude Include="src\Config.h" /> <ClInclude Include="src\Config.h" />
<ClInclude Include="src\Decoder_AAC.h" /> <ClInclude Include="src\Decoder_AAC.h" />
<CustomBuild Include="src\Encoder_AC3.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>
</CustomBuild>
<ClInclude Include="tmp\UIC_DropBox.h" /> <ClInclude Include="tmp\UIC_DropBox.h" />
<ClInclude Include="tmp\UIC_LogViewDialog.h" /> <ClInclude Include="tmp\UIC_LogViewDialog.h" />
<ClInclude Include="tmp\UIC_MainWindow.h" /> <ClInclude Include="tmp\UIC_MainWindow.h" />

View File

@ -283,6 +283,12 @@
<ClCompile Include="src\Genres.cpp"> <ClCompile Include="src\Genres.cpp">
<Filter>Source Files\Misc</Filter> <Filter>Source Files\Misc</Filter>
</ClCompile> </ClCompile>
<ClCompile Include="src\Encoder_AC3.cpp">
<Filter>Source Files\Encoders</Filter>
</ClCompile>
<ClCompile Include="tmp\MOC_Encoder_AC3.cpp">
<Filter>Generated Files\MOC</Filter>
</ClCompile>
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<ClInclude Include="src\Config.h"> <ClInclude Include="src\Config.h">
@ -536,6 +542,9 @@
<CustomBuild Include="src\Tool_Abstract.h"> <CustomBuild Include="src\Tool_Abstract.h">
<Filter>Header Files\Misc</Filter> <Filter>Header Files\Misc</Filter>
</CustomBuild> </CustomBuild>
<CustomBuild Include="src\Encoder_AC3.h">
<Filter>Header Files\Encoders</Filter>
</CustomBuild>
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<None Include="res\MainIcon.ico" /> <None Include="res\MainIcon.ico" />

View File

@ -30,7 +30,7 @@
</font> </font>
</property> </property>
<property name="currentIndex"> <property name="currentIndex">
<number>0</number> <number>3</number>
</property> </property>
<property name="usesScrollButtons"> <property name="usesScrollButtons">
<bool>false</bool> <bool>false</bool>
@ -738,14 +738,14 @@
</property> </property>
</widget> </widget>
</item> </item>
<item row="0" column="5"> <item row="0" column="6">
<widget class="QRadioButton" name="radioButtonEncoderPCM"> <widget class="QRadioButton" name="radioButtonEncoderPCM">
<property name="text"> <property name="text">
<string>Wave (PCM)</string> <string>Wave (PCM)</string>
</property> </property>
</widget> </widget>
</item> </item>
<item row="0" column="4"> <item row="0" column="5">
<widget class="QRadioButton" name="radioButtonEncoderFLAC"> <widget class="QRadioButton" name="radioButtonEncoderFLAC">
<property name="text"> <property name="text">
<string>FLAC</string> <string>FLAC</string>
@ -768,6 +768,13 @@
</property> </property>
</spacer> </spacer>
</item> </item>
<item row="0" column="4">
<widget class="QRadioButton" name="radioButtonEncoderAC3">
<property name="text">
<string>Aften A/52</string>
</property>
</widget>
</item>
</layout> </layout>
</item> </item>
</layout> </layout>
@ -3164,6 +3171,7 @@
<include location="../res/Icons.qrc"/> <include location="../res/Icons.qrc"/>
<include location="../res/Icons.qrc"/> <include location="../res/Icons.qrc"/>
<include location="../res/Icons.qrc"/> <include location="../res/Icons.qrc"/>
<include location="../res/Icons.qrc"/>
</resources> </resources>
<connections> <connections>
<connection> <connection>

View File

@ -1,6 +1,9 @@
<!DOCTYPE RCC> <!DOCTYPE RCC>
<RCC version="1.0"> <RCC version="1.0">
<qresource> <qresource>
<file>tools/aften.i386.exe</file>
<file>tools/aften.sse2.exe</file>
<file>tools/aften.x64.exe</file>
<file>tools/alac.exe</file> <file>tools/alac.exe</file>
<file>tools/elevator.exe</file> <file>tools/elevator.exe</file>
<file>tools/faad.exe</file> <file>tools/faad.exe</file>

BIN
res/tools/aften.i386.exe Normal file

Binary file not shown.

BIN
res/tools/aften.sse2.exe Normal file

Binary file not shown.

BIN
res/tools/aften.x64.exe Normal file

Binary file not shown.

View File

@ -30,7 +30,7 @@
#define VER_LAMEXP_MINOR_LO 2 #define VER_LAMEXP_MINOR_LO 2
#define VER_LAMEXP_TYPE Alpha #define VER_LAMEXP_TYPE Alpha
#define VER_LAMEXP_PATCH 10 #define VER_LAMEXP_PATCH 10
#define VER_LAMEXP_BUILD 480 #define VER_LAMEXP_BUILD 482
/////////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////////
// Tools versions // Tools versions

View File

@ -81,7 +81,7 @@ AboutDialog::AboutDialog(SettingsModel *settings, QWidget *parent, bool firstSta
m_rotateNext(false), m_rotateNext(false),
m_disqueDelay(_I64_MAX) m_disqueDelay(_I64_MAX)
{ {
const QString versionStr = QString().sprintf QString versionStr = QString().sprintf
( (
"Version %d.%02d %s, Build %d [%s], %s, Qt v%s", "Version %d.%02d %s, Build %d [%s], %s, Qt v%s",
lamexp_version_major(), lamexp_version_major(),
@ -101,8 +101,8 @@ AboutDialog::AboutDialog(SettingsModel *settings, QWidget *parent, bool firstSta
QString aboutText; QString aboutText;
aboutText += QString("<h2>%1</h2>").arg(tr("LameXP &minus; Audio Encoder Front-end")); aboutText += QString("<h2>%1</h2>").arg(tr("LameXP &minus; Audio Encoder Front-end"));
aboutText += QString("<b>Copyright (C) 2004-%1 LoRd_MuldeR &lt;MuldeR2@GMX.de&gt;. Some rights reserved.</b><br>").arg(max(lamexp_version_date().year(), QDate::currentDate().year())); aboutText += QString("<nobr><b>Copyright (C) 2004-%1 LoRd_MuldeR &lt;MuldeR2@GMX.de&gt;. Some rights reserved.</b></nobr><br>").arg(max(lamexp_version_date().year(), QDate::currentDate().year())).replace("-", "&minus;");
aboutText += QString("<b>%1</b><br><br>").arg(versionStr); aboutText += QString("<nobr><b>%1</b></nobr><br><br>").arg(versionStr).replace("-", "&minus;");
aboutText += QString("<nobr>%1</nobr><br>").arg(tr("Please visit %1 for news and updates!").arg(LINK(lamexp_website_url()))); aboutText += QString("<nobr>%1</nobr><br>").arg(tr("Please visit %1 for news and updates!").arg(LINK(lamexp_website_url())));
if(LAMEXP_DEBUG) if(LAMEXP_DEBUG)
@ -113,7 +113,7 @@ AboutDialog::AboutDialog(SettingsModel *settings, QWidget *parent, bool firstSta
else if(lamexp_version_demo()) else if(lamexp_version_demo())
{ {
int daysLeft = max(QDate::currentDate().daysTo(lamexp_version_expires()), 0); int daysLeft = max(QDate::currentDate().daysTo(lamexp_version_expires()), 0);
aboutText += QString("<hr><nobr><font color=\"crimson\">%1</font></nobr>").arg(tr("Note: This demo (pre-release) version of LameXP will expire at %1. Still %2 days left.").arg(lamexp_version_expires().toString(Qt::ISODate), QString::number(daysLeft))); aboutText += QString("<hr><nobr><font color=\"crimson\">%1</font></nobr>").arg(tr("Note: This demo (pre-release) version of LameXP will expire at %1. Still %2 days left.").arg(lamexp_version_expires().toString(Qt::ISODate), QString::number(daysLeft))).replace("-", "&minus;");
} }
aboutText += "<hr><br>"; aboutText += "<hr><br>";

View File

@ -184,6 +184,7 @@ MainWindow::MainWindow(FileListModel *fileListModel, AudioFileModel *metaInfo, S
m_encoderButtonGroup->addButton(radioButtonEncoderMP3, SettingsModel::MP3Encoder); m_encoderButtonGroup->addButton(radioButtonEncoderMP3, SettingsModel::MP3Encoder);
m_encoderButtonGroup->addButton(radioButtonEncoderVorbis, SettingsModel::VorbisEncoder); m_encoderButtonGroup->addButton(radioButtonEncoderVorbis, SettingsModel::VorbisEncoder);
m_encoderButtonGroup->addButton(radioButtonEncoderAAC, SettingsModel::AACEncoder); m_encoderButtonGroup->addButton(radioButtonEncoderAAC, SettingsModel::AACEncoder);
m_encoderButtonGroup->addButton(radioButtonEncoderAC3, SettingsModel::AC3Encoder);
m_encoderButtonGroup->addButton(radioButtonEncoderFLAC, SettingsModel::FLACEncoder); m_encoderButtonGroup->addButton(radioButtonEncoderFLAC, SettingsModel::FLACEncoder);
m_encoderButtonGroup->addButton(radioButtonEncoderPCM, SettingsModel::PCMEncoder); m_encoderButtonGroup->addButton(radioButtonEncoderPCM, SettingsModel::PCMEncoder);
m_modeButtonGroup = new QButtonGroup(this); m_modeButtonGroup = new QButtonGroup(this);
@ -193,6 +194,7 @@ MainWindow::MainWindow(FileListModel *fileListModel, AudioFileModel *metaInfo, S
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); radioButtonEncoderAAC->setChecked(m_settings->compressionEncoder() == SettingsModel::AACEncoder);
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);
radioButtonModeQuality->setChecked(m_settings->compressionRCMode() == SettingsModel::VBRMode); radioButtonModeQuality->setChecked(m_settings->compressionRCMode() == SettingsModel::VBRMode);
@ -1041,6 +1043,7 @@ void MainWindow::encodeButtonClicked(void)
case SettingsModel::MP3Encoder: case SettingsModel::MP3Encoder:
case SettingsModel::VorbisEncoder: case SettingsModel::VorbisEncoder:
case SettingsModel::AACEncoder: case SettingsModel::AACEncoder:
case SettingsModel::AC3Encoder:
case SettingsModel::FLACEncoder: case SettingsModel::FLACEncoder:
case SettingsModel::PCMEncoder: case SettingsModel::PCMEncoder:
break; break;

View File

@ -32,6 +32,7 @@
#include "Encoder_MP3.h" #include "Encoder_MP3.h"
#include "Encoder_Vorbis.h" #include "Encoder_Vorbis.h"
#include "Encoder_AAC.h" #include "Encoder_AAC.h"
#include "Encoder_AC3.h"
#include "Encoder_FLAC.h" #include "Encoder_FLAC.h"
#include "Encoder_Wave.h" #include "Encoder_Wave.h"
#include "Filter_Normalize.h" #include "Filter_Normalize.h"
@ -600,6 +601,15 @@ void ProcessingDialog::startNextJob(void)
encoder = aacEncoder; encoder = aacEncoder;
} }
break; break;
case SettingsModel::AC3Encoder:
{
AC3Encoder *ac3Encoder = new AC3Encoder();
ac3Encoder->setBitrate(m_settings->compressionBitrate());
ac3Encoder->setRCMode(m_settings->compressionRCMode());
ac3Encoder->setCustomParams(m_settings->customParametersNeroAAC());
encoder = ac3Encoder;
}
break;
case SettingsModel::FLACEncoder: case SettingsModel::FLACEncoder:
{ {
FLACEncoder *flacEncoder = new FLACEncoder(); FLACEncoder *flacEncoder = new FLACEncoder();

147
src/Encoder_AC3.cpp Normal file
View File

@ -0,0 +1,147 @@
///////////////////////////////////////////////////////////////////////////////
// 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_AC3.h"
#include "Global.h"
#include "Model_Settings.h"
#include <QProcess>
#include <QDir>
#define max(a,b) (((a) > (b)) ? (a) : (b))
#define min(a,b) (((a) < (b)) ? (a) : (b))
AC3Encoder::AC3Encoder(void)
:
m_binary(lamexp_lookup_tool("aften.exe"))
{
if(m_binary.isEmpty())
{
throw "Error initializing FLAC encoder. Tool 'aften.exe' is not registred!";
}
}
AC3Encoder::~AC3Encoder(void)
{
}
bool AC3Encoder::encode(const QString &sourceFile, const AudioFileModel &metaInfo, const QString &outputFile, volatile bool *abortFlag)
{
QProcess process;
QStringList args;
//args << QString("-%1").arg(QString::number(max(0, min(8, m_configBitrate))));
//if(!metaInfo.fileName().isEmpty()) args << "-T" << QString("title=%1").arg(metaInfo.fileName());
//if(!metaInfo.fileArtist().isEmpty()) args << "-T" << QString("artist=%1").arg(metaInfo.fileArtist());
//if(!metaInfo.fileAlbum().isEmpty()) args << "-T" << QString("album=%1").arg(metaInfo.fileAlbum());
//if(!metaInfo.fileGenre().isEmpty()) args << "-T" << QString("genre=%1").arg(metaInfo.fileGenre());
//if(!metaInfo.fileComment().isEmpty()) args << "-T" << QString("comment=%1").arg(metaInfo.fileComment());
//if(metaInfo.fileYear()) args << "-T" << QString("date=%1").arg(QString::number(metaInfo.fileYear()));
//if(metaInfo.filePosition()) args << "-T" << QString("track=%1").arg(QString::number(metaInfo.filePosition()));
//if(!metaInfo.fileCover().isEmpty()) args << QString("--picture=%1").arg(metaInfo.fileCover());
//if(!m_configCustomParams.isEmpty()) args << m_configCustomParams.split(" ", QString::SkipEmptyParts);
args << QDir::toNativeSeparators(sourceFile);
args << QDir::toNativeSeparators(outputFile);
if(!startProcess(process, m_binary, args))
{
return false;
}
bool bTimeout = false;
bool bAborted = false;
QRegExp regExp("progress:(\\s+)(\\d+)%(\\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("Aften 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(2).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)
{
return false;
}
return true;
}
QString AC3Encoder::extension(void)
{
return "ac3";
}
bool AC3Encoder::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;
}

42
src/Encoder_AC3.h Normal file
View File

@ -0,0 +1,42 @@
///////////////////////////////////////////////////////////////////////////////
// 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 AC3Encoder : public AbstractEncoder
{
Q_OBJECT
public:
AC3Encoder(void);
~AC3Encoder(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);
private:
const QString m_binary;
};

View File

@ -60,8 +60,9 @@ public:
MP3Encoder = 0, MP3Encoder = 0,
VorbisEncoder = 1, VorbisEncoder = 1,
AACEncoder = 2, AACEncoder = 2,
FLACEncoder = 3, AC3Encoder = 3,
PCMEncoder = 4 FLACEncoder = 4,
PCMEncoder = 5
}; };
enum RCMode enum RCMode
{ {

View File

@ -52,6 +52,9 @@ static const struct
} }
g_lamexp_tools[] = g_lamexp_tools[] =
{ {
{"0a6252606c1ceda7b8973e5935ef72d60b8fd64d", CPU_TYPE_X86, "aften.i386.exe", 8},
{"22253052acba92a0088bbf0aa82a8c505c07b854", CPU_TYPE_SSE, "aften.sse2.exe", 8},
{"2996a48b01b65a2c1806482654beeea7ffcf1f80", CPU_TYPE_X64, "aften.x64.exe", 8},
{"3b41f85dde8d4a5a0f4cd5f461099d0db24610ba", CPU_TYPE_ALL, "alac.exe", UINT_MAX}, {"3b41f85dde8d4a5a0f4cd5f461099d0db24610ba", CPU_TYPE_ALL, "alac.exe", UINT_MAX},
{"fb74ac8b73ad8cba2c3b4e6e61f23401d630dc22", CPU_TYPE_ALL, "elevator.exe", UINT_MAX}, {"fb74ac8b73ad8cba2c3b4e6e61f23401d630dc22", CPU_TYPE_ALL, "elevator.exe", UINT_MAX},
{"80e372d8b20be24102c18284286fcdf5fa14bd86", CPU_TYPE_ALL, "faad.exe", 27}, {"80e372d8b20be24102c18284286fcdf5fa14bd86", CPU_TYPE_ALL, "faad.exe", 27},