OSDN Git Service

Moved translation support into MUtilities library + make clean-up of temporary files...
[lamexp/LameXP.git] / src / Decoder_ALAC.cpp
1 ///////////////////////////////////////////////////////////////////////////////
2 // LameXP - Audio Encoder Front-End
3 // Copyright (C) 2004-2014 LoRd_MuldeR <MuldeR2@GMX.de>
4 //
5 // This program is free software; you can redistribute it and/or modify
6 // it under the terms of the GNU General Public License as published by
7 // the Free Software Foundation; either version 2 of the License, or
8 // (at your option) any later version, but always including the *additional*
9 // restrictions defined in the "License.txt" file.
10 //
11 // This program is distributed in the hope that it will be useful,
12 // but WITHOUT ANY WARRANTY; without even the implied warranty of
13 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14 // GNU General Public License for more details.
15 //
16 // You should have received a copy of the GNU General Public License along
17 // with this program; if not, write to the Free Software Foundation, Inc.,
18 // 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
19 //
20 // http://www.gnu.org/licenses/gpl-2.0.txt
21 ///////////////////////////////////////////////////////////////////////////////
22
23 #include "Decoder_ALAC.h"
24
25 //Internal
26 #include "Global.h"
27
28 //MUtils
29 #include <MUtils/Exception.h>
30
31 //Qt
32 #include <QDir>
33 #include <QProcess>
34 #include <QRegExp>
35 #include <QUuid>
36
37 ALACDecoder::ALACDecoder(void)
38 :
39         m_binary(lamexp_tools_lookup("refalac.exe"))
40 {
41         if(m_binary.isEmpty())
42         {
43                 MUTILS_THROW("Error initializing ALAC decoder. Tool 'refalac.exe' is not registred!");
44         }
45 }
46
47 ALACDecoder::~ALACDecoder(void)
48 {
49 }
50
51 bool ALACDecoder::decode(const QString &sourceFile, const QString &outputFile, volatile bool *abortFlag)
52 {
53         QProcess process;
54         QStringList args;
55
56         args << "--decode";
57         args << "-o" << QDir::toNativeSeparators(outputFile);
58         args << QDir::toNativeSeparators(sourceFile);
59
60         if(!startProcess(process, m_binary, args))
61         {
62                 return false;
63         }
64
65         bool bTimeout = false;
66         bool bAborted = false;
67         int prevProgress = -1;
68
69         //The ALAC Decoder doesn't actually send any status updates :-[
70         //emit statusUpdated(20 + (QUuid::createUuid().data1 % 60));
71         QRegExp regExp("\\[(\\d+)\\.(\\d)%\\]");
72
73         while(process.state() != QProcess::NotRunning)
74         {
75                 if(*abortFlag)
76                 {
77                         process.kill();
78                         bAborted = true;
79                         emit messageLogged("\nABORTED BY USER !!!");
80                         break;
81                 }
82                 process.waitForReadyRead(m_processTimeoutInterval);
83                 if(!process.bytesAvailable() && process.state() == QProcess::Running)
84                 {
85                         process.kill();
86                         qWarning("ALAC process timed out <-- killing!");
87                         emit messageLogged("\nPROCESS TIMEOUT !!!");
88                         bTimeout = true;
89                         break;
90                 }
91                 while(process.bytesAvailable() > 0)
92                 {
93                         QByteArray line = process.readLine();
94                         QString text = QString::fromUtf8(line.constData()).simplified();
95                         if(regExp.lastIndexIn(text) >= 0)
96                         {
97                                 bool ok[2] = {false, false};
98                                 int intVal[2] = {0, 0};
99                                 intVal[0] = regExp.cap(1).toInt(&ok[0]);
100                                 intVal[1] = regExp.cap(2).toInt(&ok[1]);
101                                 if(ok[0] && ok[1])
102                                 {
103                                         int progress = qRound(static_cast<double>(intVal[0]) + (static_cast<double>(intVal[1]) / 10.0));
104                                         if(progress > prevProgress)
105                                         {
106                                                 emit statusUpdated(progress);
107                                                 prevProgress = qMin(progress + 2, 99);
108                                         }
109                                 }
110                         }
111                         else if(!text.isEmpty())
112                         {
113                                 emit messageLogged(text);
114                         }
115                 }
116         }
117
118         process.waitForFinished();
119         if(process.state() != QProcess::NotRunning)
120         {
121                 process.kill();
122                 process.waitForFinished(-1);
123         }
124         
125         emit statusUpdated(100);
126         emit messageLogged(QString().sprintf("\nExited with code: 0x%04X", process.exitCode()));
127
128         if(bTimeout || bAborted || process.exitCode() != EXIT_SUCCESS || QFileInfo(outputFile).size() == 0)
129         {
130                 return false;
131         }
132         
133         return true;
134 }
135
136 bool ALACDecoder::isFormatSupported(const QString &containerType, const QString &containerProfile, const QString &formatType, const QString &formatProfile, const QString &formatVersion)
137 {
138         if(containerType.compare("MPEG-4", Qt::CaseInsensitive) == 0)
139         {
140                 if(formatType.compare("ALAC", Qt::CaseInsensitive) == 0)
141                 {
142                         return true;
143                 }
144         }
145
146         return false;
147 }
148
149 QStringList ALACDecoder::supportedTypes(void)
150 {
151         return QStringList() << "Apple Lossless (*.mp4 *.m4a)";
152 }