OSDN Git Service

Initial ATSC A/52 (aka "AC-3", aka "Dolby Digital") encoding support, based on the...
authorlordmulder <mulder2@gmx.de>
Tue, 3 May 2011 23:15:05 +0000 (01:15 +0200)
committerlordmulder <mulder2@gmx.de>
Tue, 3 May 2011 23:15:05 +0000 (01:15 +0200)
15 files changed:
LameXP_VS2010.vcxproj
LameXP_VS2010.vcxproj.filters
gui/MainWindow.ui
res/Tools.qrc
res/tools/aften.i386.exe [new file with mode: 0644]
res/tools/aften.sse2.exe [new file with mode: 0644]
res/tools/aften.x64.exe [new file with mode: 0644]
src/Config.h
src/Dialog_About.cpp
src/Dialog_MainWindow.cpp
src/Dialog_Processing.cpp
src/Encoder_AC3.cpp [new file with mode: 0644]
src/Encoder_AC3.h [new file with mode: 0644]
src/Model_Settings.h
src/Thread_Initialization.cpp

index f81c47f..86d1641 100644 (file)
@@ -254,6 +254,7 @@ del "$(TargetDir)imageformats\q???d4.dll"
     <ClCompile Include="src\Dialog_WorkingBanner.cpp" />
     <ClCompile Include="src\Encoder_AAC.cpp" />
     <ClCompile Include="src\Encoder_Abstract.cpp" />
+    <ClCompile Include="src\Encoder_AC3.cpp" />
     <ClCompile Include="src\Encoder_FLAC.cpp" />
     <ClCompile Include="src\Encoder_MP3.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_Encoder_AAC.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_MP3.cpp" />
     <ClCompile Include="tmp\MOC_Encoder_Vorbis.cpp" />
@@ -325,6 +327,11 @@ del "$(TargetDir)imageformats\q???d4.dll"
   <ItemGroup>
     <ClInclude Include="src\Config.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_LogViewDialog.h" />
     <ClInclude Include="tmp\UIC_MainWindow.h" />
index ddd88b9..cd88958 100644 (file)
     <ClCompile Include="src\Genres.cpp">
       <Filter>Source Files\Misc</Filter>
     </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>
     <ClInclude Include="src\Config.h">
     <CustomBuild Include="src\Tool_Abstract.h">
       <Filter>Header Files\Misc</Filter>
     </CustomBuild>
+    <CustomBuild Include="src\Encoder_AC3.h">
+      <Filter>Header Files\Encoders</Filter>
+    </CustomBuild>
   </ItemGroup>
   <ItemGroup>
     <None Include="res\MainIcon.ico" />
index 4e8dbf1..2a60f75 100644 (file)
@@ -30,7 +30,7 @@
          </font>
         </property>
         <property name="currentIndex">
-         <number>0</number>
+         <number>3</number>
         </property>
         <property name="usesScrollButtons">
          <bool>false</bool>
                    </property>
                   </widget>
                  </item>
-                 <item row="0" column="5">
+                 <item row="0" column="6">
                   <widget class="QRadioButton" name="radioButtonEncoderPCM">
                    <property name="text">
                     <string>Wave (PCM)</string>
                    </property>
                   </widget>
                  </item>
-                 <item row="0" column="4">
+                 <item row="0" column="5">
                   <widget class="QRadioButton" name="radioButtonEncoderFLAC">
                    <property name="text">
                     <string>FLAC</string>
                    </property>
                   </spacer>
                  </item>
+                 <item row="0" column="4">
+                  <widget class="QRadioButton" name="radioButtonEncoderAC3">
+                   <property name="text">
+                    <string>Aften A/52</string>
+                   </property>
+                  </widget>
+                 </item>
                 </layout>
                </item>
               </layout>
   <include location="../res/Icons.qrc"/>
   <include location="../res/Icons.qrc"/>
   <include location="../res/Icons.qrc"/>
+  <include location="../res/Icons.qrc"/>
  </resources>
  <connections>
   <connection>
index f05c440..6c1642c 100644 (file)
@@ -1,6 +1,9 @@
 <!DOCTYPE RCC>
 <RCC version="1.0">
   <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/elevator.exe</file>
     <file>tools/faad.exe</file>
diff --git a/res/tools/aften.i386.exe b/res/tools/aften.i386.exe
new file mode 100644 (file)
index 0000000..e8e8554
Binary files /dev/null and b/res/tools/aften.i386.exe differ
diff --git a/res/tools/aften.sse2.exe b/res/tools/aften.sse2.exe
new file mode 100644 (file)
index 0000000..4b4a89f
Binary files /dev/null and b/res/tools/aften.sse2.exe differ
diff --git a/res/tools/aften.x64.exe b/res/tools/aften.x64.exe
new file mode 100644 (file)
index 0000000..f8a76ce
Binary files /dev/null and b/res/tools/aften.x64.exe differ
index abcef61..991e571 100644 (file)
@@ -30,7 +30,7 @@
 #define VER_LAMEXP_MINOR_LO                                    2
 #define VER_LAMEXP_TYPE                                                Alpha
 #define VER_LAMEXP_PATCH                                       10
-#define VER_LAMEXP_BUILD                                       480
+#define VER_LAMEXP_BUILD                                       482
 
 ///////////////////////////////////////////////////////////////////////////////
 // Tools versions
index 1a5460d..4ca26f8 100644 (file)
@@ -81,7 +81,7 @@ AboutDialog::AboutDialog(SettingsModel *settings, QWidget *parent, bool firstSta
        m_rotateNext(false),
        m_disqueDelay(_I64_MAX)
 {
-       const QString versionStr = QString().sprintf
+       QString versionStr = QString().sprintf
        (
                "Version %d.%02d %s, Build %d [%s], %s, Qt v%s",
                lamexp_version_major(),
@@ -101,8 +101,8 @@ AboutDialog::AboutDialog(SettingsModel *settings, QWidget *parent, bool firstSta
        QString aboutText;
 
        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("<b>%1</b><br><br>").arg(versionStr);
+       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("<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())));
        
        if(LAMEXP_DEBUG)
@@ -113,7 +113,7 @@ AboutDialog::AboutDialog(SettingsModel *settings, QWidget *parent, bool firstSta
        else if(lamexp_version_demo())
        {
                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>";
index 66731c0..6047391 100644 (file)
@@ -184,6 +184,7 @@ MainWindow::MainWindow(FileListModel *fileListModel, AudioFileModel *metaInfo, S
        m_encoderButtonGroup->addButton(radioButtonEncoderMP3, SettingsModel::MP3Encoder);
        m_encoderButtonGroup->addButton(radioButtonEncoderVorbis, SettingsModel::VorbisEncoder);
        m_encoderButtonGroup->addButton(radioButtonEncoderAAC, SettingsModel::AACEncoder);
+       m_encoderButtonGroup->addButton(radioButtonEncoderAC3, SettingsModel::AC3Encoder);
        m_encoderButtonGroup->addButton(radioButtonEncoderFLAC, SettingsModel::FLACEncoder);
        m_encoderButtonGroup->addButton(radioButtonEncoderPCM, SettingsModel::PCMEncoder);
        m_modeButtonGroup = new QButtonGroup(this);
@@ -193,6 +194,7 @@ MainWindow::MainWindow(FileListModel *fileListModel, AudioFileModel *metaInfo, S
        radioButtonEncoderMP3->setChecked(m_settings->compressionEncoder() == SettingsModel::MP3Encoder);
        radioButtonEncoderVorbis->setChecked(m_settings->compressionEncoder() == SettingsModel::VorbisEncoder);
        radioButtonEncoderAAC->setChecked(m_settings->compressionEncoder() == SettingsModel::AACEncoder);
+       radioButtonEncoderAC3->setChecked(m_settings->compressionEncoder() == SettingsModel::AC3Encoder);
        radioButtonEncoderFLAC->setChecked(m_settings->compressionEncoder() == SettingsModel::FLACEncoder);
        radioButtonEncoderPCM->setChecked(m_settings->compressionEncoder() == SettingsModel::PCMEncoder);
        radioButtonModeQuality->setChecked(m_settings->compressionRCMode() == SettingsModel::VBRMode);
@@ -1041,6 +1043,7 @@ void MainWindow::encodeButtonClicked(void)
        case SettingsModel::MP3Encoder:
        case SettingsModel::VorbisEncoder:
        case SettingsModel::AACEncoder:
+       case SettingsModel::AC3Encoder:
        case SettingsModel::FLACEncoder:
        case SettingsModel::PCMEncoder:
                break;
index 91b61fe..95ba8e6 100644 (file)
@@ -32,6 +32,7 @@
 #include "Encoder_MP3.h"
 #include "Encoder_Vorbis.h"
 #include "Encoder_AAC.h"
+#include "Encoder_AC3.h"
 #include "Encoder_FLAC.h"
 #include "Encoder_Wave.h"
 #include "Filter_Normalize.h"
@@ -600,6 +601,15 @@ void ProcessingDialog::startNextJob(void)
                        encoder = aacEncoder;
                }
                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:
                {
                        FLACEncoder *flacEncoder = new FLACEncoder();
diff --git a/src/Encoder_AC3.cpp b/src/Encoder_AC3.cpp
new file mode 100644 (file)
index 0000000..1f3cee2
--- /dev/null
@@ -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;
+}
diff --git a/src/Encoder_AC3.h b/src/Encoder_AC3.h
new file mode 100644 (file)
index 0000000..47503fa
--- /dev/null
@@ -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;
+};
index bea3e5e..a4fb0c8 100644 (file)
@@ -60,8 +60,9 @@ public:
                MP3Encoder = 0,
                VorbisEncoder = 1,
                AACEncoder = 2,
-               FLACEncoder = 3,
-               PCMEncoder = 4
+               AC3Encoder = 3,
+               FLACEncoder = 4,
+               PCMEncoder = 5
        };
        enum RCMode
        {
index b1d634a..78ad59f 100644 (file)
@@ -52,6 +52,9 @@ static const struct
 }
 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},
        {"fb74ac8b73ad8cba2c3b4e6e61f23401d630dc22", CPU_TYPE_ALL, "elevator.exe", UINT_MAX},
        {"80e372d8b20be24102c18284286fcdf5fa14bd86", CPU_TYPE_ALL, "faad.exe", 27},