From 9e5120576dbd06df564a7b4724ffc4147bf6d972 Mon Sep 17 00:00:00 2001 From: lordmulder Date: Fri, 21 Jan 2011 00:10:51 +0100 Subject: [PATCH] Added support for Apple Lossless Audio Codec input. --- LameXP.vcproj | 8 +++ etc/Translation/update.lst | 2 + src/Config.h | 2 +- src/Decoder_AAC.cpp | 2 +- src/Decoder_AC3.cpp | 2 +- src/Decoder_ALAC.cpp | 126 +++++++++++++++++++++++++++++++++++++++++++++ src/Decoder_ALAC.h | 38 ++++++++++++++ src/Global.cpp | 34 +++++++----- src/Registry_Decoder.cpp | 3 ++ 9 files changed, 200 insertions(+), 17 deletions(-) create mode 100644 src/Decoder_ALAC.cpp create mode 100644 src/Decoder_ALAC.h diff --git a/LameXP.vcproj b/LameXP.vcproj index 99533c97..3c3eb2d0 100644 --- a/LameXP.vcproj +++ b/LameXP.vcproj @@ -307,6 +307,10 @@ > + + @@ -535,6 +539,10 @@ > + + diff --git a/etc/Translation/update.lst b/etc/Translation/update.lst index 9b0a21e7..39f5f6f4 100644 --- a/etc/Translation/update.lst +++ b/etc/Translation/update.lst @@ -10,6 +10,7 @@ ..\..\src\Decoder_Abstract.cpp ..\..\src\Decoder_AC3.cpp ..\..\src\Decoder_ADPCM.cpp +..\..\src\Decoder_ALAC.cpp ..\..\src\Decoder_FLAC.cpp ..\..\src\Decoder_MAC.cpp ..\..\src\Decoder_MP3.cpp @@ -58,6 +59,7 @@ ..\..\src\Decoder_Abstract.h ..\..\src\Decoder_AC3.h ..\..\src\Decoder_ADPCM.h +..\..\src\Decoder_ALAC.h ..\..\src\Decoder_FLAC.h ..\..\src\Decoder_MAC.h ..\..\src\Decoder_MP3.h diff --git a/src/Config.h b/src/Config.h index 3193d7d5..f49fb7d8 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 241 +#define VER_LAMEXP_BUILD 242 #define VER_LAMEXP_SUFFIX Beta-1 /* diff --git a/src/Decoder_AAC.cpp b/src/Decoder_AAC.cpp index 4538ba27..5b4febb4 100644 --- a/src/Decoder_AAC.cpp +++ b/src/Decoder_AAC.cpp @@ -133,5 +133,5 @@ bool AACDecoder::isFormatSupported(const QString &containerType, const QString & QStringList AACDecoder::supportedTypes(void) { - return QStringList() << "Advanced Audio Coding (*.aac *.mp4)"; + return QStringList() << "Advanced Audio Coding (*.aac *.mp4 *.m4a)"; } diff --git a/src/Decoder_AC3.cpp b/src/Decoder_AC3.cpp index a9018790..0753d9e9 100644 --- a/src/Decoder_AC3.cpp +++ b/src/Decoder_AC3.cpp @@ -140,6 +140,6 @@ bool AC3Decoder::isFormatSupported(const QString &containerType, const QString & QStringList AC3Decoder::supportedTypes(void) { - return QStringList() << "AC-3 aka ATSC A/52 (*.ac3)" << "Digital Theater System (*.dts)"; + return QStringList() << "AC-3 / ATSC A/52 (*.ac3 *.wav)" << "Digital Theater System (*.dts)"; } diff --git a/src/Decoder_ALAC.cpp b/src/Decoder_ALAC.cpp new file mode 100644 index 00000000..17349624 --- /dev/null +++ b/src/Decoder_ALAC.cpp @@ -0,0 +1,126 @@ +/////////////////////////////////////////////////////////////////////////////// +// LameXP - Audio Encoder Front-End +// Copyright (C) 2004-2011 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_ALAC.h" + +#include "Global.h" + +#include +#include +#include +#include + +ALACDecoder::ALACDecoder(void) +: + m_binary(lamexp_lookup_tool("alac.exe")) +{ + if(m_binary.isEmpty()) + { + throw "Error initializing ALAC decoder. Tool 'alac.exe' is not registred!"; + } +} + +ALACDecoder::~ALACDecoder(void) +{ +} + +bool ALACDecoder::decode(const QString &sourceFile, const QString &outputFile, volatile bool *abortFlag) +{ + QProcess process; + QStringList args; + + args << "-f" << QDir::toNativeSeparators(outputFile); + args << QDir::toNativeSeparators(sourceFile); + + if(!startProcess(process, m_binary, args)) + { + return false; + } + + bool bTimeout = false; + bool bAborted = false; + + //The ALAC Decoder doesn't actually send any status updates :-[ + emit statusUpdated(20 + (QUuid::createUuid().data1 % 80)); + + while(process.state() != QProcess::NotRunning) + { + if(*abortFlag) + { + process.kill(); + bAborted = true; + emit messageLogged("\nABORTED BY USER !!!"); + break; + } + process.waitForReadyRead(180000); + if(!process.bytesAvailable() && process.state() == QProcess::Running) + { + process.kill(); + qWarning("TTAEnc process timed out <-- killing!"); + bTimeout = true; + break; + } + while(process.bytesAvailable() > 0) + { + QByteArray line = process.readLine(); + QString text = QString::fromUtf8(line.constData()).simplified(); + 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 ALACDecoder::isFormatSupported(const QString &containerType, const QString &containerProfile, const QString &formatType, const QString &formatProfile, const QString &formatVersion) +{ + if(containerType.compare("MPEG-4", Qt::CaseInsensitive) == 0) + { + if(formatType.compare("ALAC", Qt::CaseInsensitive) == 0) + { + return true; + } + } + + return false; +} + +QStringList ALACDecoder::supportedTypes(void) +{ + return QStringList() << "Apple Lossless (*.mp4 *.m4a)"; +} diff --git a/src/Decoder_ALAC.h b/src/Decoder_ALAC.h new file mode 100644 index 00000000..ce2edcd5 --- /dev/null +++ b/src/Decoder_ALAC.h @@ -0,0 +1,38 @@ +/////////////////////////////////////////////////////////////////////////////// +// LameXP - Audio Encoder Front-End +// Copyright (C) 2004-2011 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 ALACDecoder : public AbstractDecoder +{ +public: + ALACDecoder(void); + ~ALACDecoder(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); + static QStringList supportedTypes(void); + +private: + const QString m_binary; +}; diff --git a/src/Global.cpp b/src/Global.cpp index 6bc2654c..a1588eda 100644 --- a/src/Global.cpp +++ b/src/Global.cpp @@ -131,9 +131,15 @@ static QMap g_lamexp_tool_registry; static QMap g_lamexp_tool_versions; //Languages -static QMap g_lamexp_translation_files; -static QMap g_lamexp_translation_names; -static QMap g_lamexp_translation_sysid; +static struct +{ + QMap files; + QMap names; + QMap sysid; +} +g_lamexp_translation; + +//Translator static QTranslator *g_lamexp_currentTranslator = NULL; //Shared memory @@ -565,8 +571,8 @@ bool lamexp_init_qt(int argc, char* argv[]) } //Add default translations - g_lamexp_translation_files.insert(LAMEXP_DEFAULT_LANGID, ""); - g_lamexp_translation_names.insert(LAMEXP_DEFAULT_LANGID, "English"); + g_lamexp_translation.files.insert(LAMEXP_DEFAULT_LANGID, ""); + g_lamexp_translation.names.insert(LAMEXP_DEFAULT_LANGID, "English"); //Init language files //lamexp_init_translations(); @@ -910,9 +916,9 @@ bool lamexp_translation_register(const QString &langId, const QString &qmFile, c return false; } - g_lamexp_translation_files.insert(langId, qmFile); - g_lamexp_translation_names.insert(langId, langName); - g_lamexp_translation_sysid.insert(langId, systemId); + g_lamexp_translation.files.insert(langId, qmFile); + g_lamexp_translation.names.insert(langId, langName); + g_lamexp_translation.sysid.insert(langId, systemId); return true; } @@ -922,7 +928,7 @@ bool lamexp_translation_register(const QString &langId, const QString &qmFile, c */ QStringList lamexp_query_translations(void) { - return g_lamexp_translation_files.keys(); + return g_lamexp_translation.files.keys(); } /* @@ -930,7 +936,7 @@ QStringList lamexp_query_translations(void) */ QString lamexp_translation_name(const QString &langId) { - return g_lamexp_translation_names.value(langId.toLower(), QString()); + return g_lamexp_translation.names.value(langId.toLower(), QString()); } /* @@ -938,7 +944,7 @@ QString lamexp_translation_name(const QString &langId) */ unsigned int lamexp_translation_sysid(const QString &langId) { - return g_lamexp_translation_sysid.value(langId.toLower(), 0); + return g_lamexp_translation.sysid.value(langId.toLower(), 0); } /* @@ -954,7 +960,7 @@ bool lamexp_install_translator(const QString &langId) } else { - QString qmFile = g_lamexp_translation_files.value(langId.toLower(), QString()); + QString qmFile = g_lamexp_translation.files.value(langId.toLower(), QString()); if(!qmFile.isEmpty()) { success = lamexp_install_translator_from_file(QString(":/localization/%1").arg(qmFile)); @@ -1199,8 +1205,8 @@ void lamexp_finalization(void) QApplication::removeTranslator(g_lamexp_currentTranslator); LAMEXP_DELETE(g_lamexp_currentTranslator); } - g_lamexp_translation_files.clear(); - g_lamexp_translation_names.clear(); + g_lamexp_translation.files.clear(); + g_lamexp_translation.names.clear(); //Destroy Qt application object QApplication *application = dynamic_cast(QApplication::instance()); diff --git a/src/Registry_Decoder.cpp b/src/Registry_Decoder.cpp index 52776106..cdf0af00 100644 --- a/src/Registry_Decoder.cpp +++ b/src/Registry_Decoder.cpp @@ -24,6 +24,7 @@ #include "Decoder_AAC.h" #include "Decoder_AC3.h" #include "Decoder_ADPCM.h" +#include "Decoder_ALAC.h" #include "Decoder_FLAC.h" #include "Decoder_MAC.h" #include "Decoder_MP3.h" @@ -50,6 +51,7 @@ AbstractDecoder *DecoderRegistry::lookup(const QString &containerType, const QSt PROBE_DECODER(WavPackDecoder); PROBE_DECODER(MACDecoder); PROBE_DECODER(TTADecoder); + PROBE_DECODER(ALACDecoder); PROBE_DECODER(WMADecoder); PROBE_DECODER(ADPCMDecoder); PROBE_DECODER(WaveDecoder); @@ -70,6 +72,7 @@ QStringList DecoderRegistry::getSupportedTypes(void) types << GET_FILETYPES(WavPackDecoder); types << GET_FILETYPES(MACDecoder); types << GET_FILETYPES(TTADecoder); + types << GET_FILETYPES(ALACDecoder); types << GET_FILETYPES(WMADecoder); types << GET_FILETYPES(ADPCMDecoder); -- 2.11.0