Properly detect Windows 8, now that Qt supports it officially.
[LameXP.git] / src / Encoder_AC3.cpp
blob10fdea6680df042c73d82a632b37bd5102f31f68
1 ///////////////////////////////////////////////////////////////////////////////
2 // LameXP - Audio Encoder Front-End
3 // Copyright (C) 2004-2013 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.
9 //
10 // This program is distributed in the hope that it will be useful,
11 // but WITHOUT ANY WARRANTY; without even the implied warranty of
12 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 // GNU General Public License for more details.
15 // You should have received a copy of the GNU General Public License along
16 // with this program; if not, write to the Free Software Foundation, Inc.,
17 // 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
19 // http://www.gnu.org/licenses/gpl-2.0.txt
20 ///////////////////////////////////////////////////////////////////////////////
22 #include "Encoder_AC3.h"
24 #include "Global.h"
25 #include "Model_Settings.h"
27 #include <QProcess>
28 #include <QDir>
30 static const int g_ac3BitratesLUT[20] = {32, 40, 48, 56, 64, 80, 96, 112, 128, 160, 192, 224, 256, 320, 384, 448, 512, 576, 640, -1};
32 ///////////////////////////////////////////////////////////////////////////////
33 // Encoder Info
34 ///////////////////////////////////////////////////////////////////////////////
36 class AC3EncoderInfo : public AbstractEncoderInfo
38 virtual bool isModeSupported(int mode) const
40 switch(mode)
42 case SettingsModel::VBRMode:
43 case SettingsModel::CBRMode:
44 return true;
45 break;
46 case SettingsModel::ABRMode:
47 return false;
48 break;
49 default:
50 throw "Bad RC mode specified!";
54 virtual int valueCount(int mode) const
56 switch(mode)
58 case SettingsModel::VBRMode:
59 return 65;
60 break;
61 case SettingsModel::ABRMode:
62 return 0;
63 break;
64 case SettingsModel::CBRMode:
65 return 19;
66 break;
67 default:
68 throw "Bad RC mode specified!";
72 virtual int valueAt(int mode, int index) const
74 switch(mode)
76 case SettingsModel::VBRMode:
77 return qBound(0, index * 16, 1023);
78 break;
79 case SettingsModel::ABRMode:
80 case SettingsModel::CBRMode:
81 return g_ac3BitratesLUT[qBound(0, index, 18)];
82 break;
83 default:
84 throw "Bad RC mode specified!";
88 virtual int valueType(int mode) const
90 switch(mode)
92 case SettingsModel::VBRMode:
93 return TYPE_QUALITY_LEVEL_INT;
94 break;
95 case SettingsModel::ABRMode:
96 case SettingsModel::CBRMode:
97 return TYPE_BITRATE;
98 break;
99 default:
100 throw "Bad RC mode specified!";
104 virtual const char *description(void) const
106 static const char* s_description = "Aften: A/52 Audio Encoder";
107 return s_description;
110 static const g_aftenEncoderInfo;
112 ///////////////////////////////////////////////////////////////////////////////
113 // Encoder implementation
114 ///////////////////////////////////////////////////////////////////////////////
116 AC3Encoder::AC3Encoder(void)
118 m_binary(lamexp_lookup_tool("aften.exe"))
120 if(m_binary.isEmpty())
122 throw "Error initializing FLAC encoder. Tool 'aften.exe' is not registred!";
125 m_configAudioCodingMode = 0;
126 m_configDynamicRangeCompression = 5;
127 m_configExponentSearchSize = 8;
128 m_configFastBitAllocation = false;
131 AC3Encoder::~AC3Encoder(void)
135 bool AC3Encoder::encode(const QString &sourceFile, const AudioFileModel_MetaInfo &metaInfo, const unsigned int duration, const QString &outputFile, volatile bool *abortFlag)
137 QProcess process;
138 QStringList args;
140 switch(m_configRCMode)
142 case SettingsModel::VBRMode:
143 args << "-q" << QString::number(qBound(0, m_configBitrate * 16, 1023));
144 break;
145 case SettingsModel::CBRMode:
146 args << "-b" << QString::number(g_ac3BitratesLUT[qBound(0, m_configBitrate, 18)]);
147 break;
148 default:
149 throw "Bad rate-control mode!";
150 break;
153 if(m_configAudioCodingMode >= 1)
155 args << "-acmod" << QString::number(m_configAudioCodingMode - 1);
157 if(m_configDynamicRangeCompression != 5)
159 args << "-dynrng" << QString::number(m_configDynamicRangeCompression);
161 if(m_configExponentSearchSize != 8)
163 args << "-exps" << QString::number(m_configExponentSearchSize);
165 if(m_configFastBitAllocation)
167 args << "-fba" << QString::number(1);
170 if(!m_configCustomParams.isEmpty()) args << m_configCustomParams.split(" ", QString::SkipEmptyParts);
172 args << QDir::toNativeSeparators(sourceFile);
173 args << QDir::toNativeSeparators(outputFile);
175 if(!startProcess(process, m_binary, args))
177 return false;
180 bool bTimeout = false;
181 bool bAborted = false;
182 int prevProgress = -1;
184 QRegExp regExp("progress:(\\s+)(\\d+)%(\\s+)\\|");
186 while(process.state() != QProcess::NotRunning)
188 if(*abortFlag)
190 process.kill();
191 bAborted = true;
192 emit messageLogged("\nABORTED BY USER !!!");
193 break;
195 process.waitForReadyRead(m_processTimeoutInterval);
196 if(!process.bytesAvailable() && process.state() == QProcess::Running)
198 process.kill();
199 qWarning("Aften process timed out <-- killing!");
200 emit messageLogged("\nPROCESS TIMEOUT !!!");
201 bTimeout = true;
202 break;
204 while(process.bytesAvailable() > 0)
206 QByteArray line = process.readLine();
207 QString text = QString::fromUtf8(line.constData()).simplified();
208 if(regExp.lastIndexIn(text) >= 0)
210 bool ok = false;
211 int progress = regExp.cap(2).toInt(&ok);
212 if(ok && (progress > prevProgress))
214 emit statusUpdated(progress);
215 prevProgress = qMin(progress + 2, 99);
218 else if(!text.isEmpty())
220 emit messageLogged(text);
225 process.waitForFinished();
226 if(process.state() != QProcess::NotRunning)
228 process.kill();
229 process.waitForFinished(-1);
232 emit statusUpdated(100);
233 emit messageLogged(QString().sprintf("\nExited with code: 0x%04X", process.exitCode()));
235 if(bTimeout || bAborted || process.exitCode() != EXIT_SUCCESS)
237 return false;
240 return true;
243 void AC3Encoder::setAudioCodingMode(int value)
245 m_configAudioCodingMode = qMin(8, qMax(0, value));
248 void AC3Encoder::setDynamicRangeCompression(int value)
250 m_configDynamicRangeCompression = qMin(5, qMax(0, value));
253 void AC3Encoder::setExponentSearchSize(int value)
255 m_configExponentSearchSize = qMin(32, qMax(1, value));
258 void AC3Encoder::setFastBitAllocation(bool value)
260 m_configFastBitAllocation = value;
263 QString AC3Encoder::extension(void)
265 return "ac3";
268 const unsigned int *AC3Encoder::supportedChannelCount(void)
270 static const unsigned int supportedChannels[] = {1, 2, 3, 4, 5, 6, NULL};
271 return supportedChannels;
274 const unsigned int *AC3Encoder::supportedSamplerates(void)
276 static const unsigned int supportedRates[] = {48000, 44100, 32000, NULL};
277 return supportedRates;
280 bool AC3Encoder::isFormatSupported(const QString &containerType, const QString &containerProfile, const QString &formatType, const QString &formatProfile, const QString &formatVersion)
282 if(containerType.compare("Wave", Qt::CaseInsensitive) == 0)
284 if(formatType.compare("PCM", Qt::CaseInsensitive) == 0)
286 return true;
290 return false;
293 const AbstractEncoderInfo *AC3Encoder::getEncoderInfo(void)
295 return &g_aftenEncoderInfo;