OSDN Git Service

Merge branch 'master' of github.com:lordmulder/LameXP
[lamexp/LameXP.git] / src / Thread_FileAnalyzer.cpp
1 ///////////////////////////////////////////////////////////////////////////////
2 // LameXP - Audio Encoder Front-End
3 // Copyright (C) 2004-2011 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.
14 //
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.
18 //
19 // http://www.gnu.org/licenses/gpl-2.0.txt
20 ///////////////////////////////////////////////////////////////////////////////
21
22 #include "Thread_FileAnalyzer.h"
23
24 #include "Global.h"
25 #include "LockedFile.h"
26 #include "Model_AudioFile.h"
27 #include "PlaylistImporter.h"
28
29 #include <QDir>
30 #include <QFileInfo>
31 #include <QProcess>
32 #include <QDate>
33 #include <QTime>
34 #include <QDebug>
35
36 #include <math.h>
37
38 ////////////////////////////////////////////////////////////
39 // Constructor
40 ////////////////////////////////////////////////////////////
41
42 FileAnalyzer::FileAnalyzer(const QStringList &inputFiles)
43 :
44         m_inputFiles(inputFiles),
45         m_mediaInfoBin(lamexp_lookup_tool("mediainfo.exe")),
46         m_avs2wavBin(lamexp_lookup_tool("avs2wav.exe")),
47         m_abortFlag(false)
48 {
49         m_bSuccess = false;
50         m_bAborted = false;
51                 
52         if(m_mediaInfoBin.isEmpty())
53         {
54                 qFatal("Invalid path to MediaInfo binary. Tool not initialized properly.");
55         }
56
57         m_filesAccepted = 0;
58         m_filesRejected = 0;
59         m_filesDenied = 0;
60         m_filesDummyCDDA = 0;
61         m_filesCueSheet = 0;
62 }
63
64 ////////////////////////////////////////////////////////////
65 // Thread Main
66 ////////////////////////////////////////////////////////////
67
68 void FileAnalyzer::run()
69 {
70         m_bSuccess = false;
71         m_bAborted = false;
72
73         m_filesAccepted = 0;
74         m_filesRejected = 0;
75         m_filesDenied = 0;
76         m_filesDummyCDDA = 0;
77         m_filesCueSheet = 0;
78
79         m_inputFiles.sort();
80         m_recentlyAdded.clear();
81         m_abortFlag = false;
82
83         while(!m_inputFiles.isEmpty())
84         {
85                 int fileType = fileTypeNormal;
86                 QString currentFile = QDir::fromNativeSeparators(m_inputFiles.takeFirst());
87                 qDebug("Analyzing: %s", currentFile.toUtf8().constData());
88                 emit fileSelected(QFileInfo(currentFile).fileName());
89                 AudioFileModel file = analyzeFile(currentFile, &fileType);
90                 
91                 if(m_abortFlag)
92                 {
93                         MessageBeep(MB_ICONERROR);
94                         m_bAborted = true;
95                         qWarning("Operation cancelled by user!");
96                         return;
97                 }
98                 if(fileType == fileTypeSkip)
99                 {
100                         qWarning("File was recently added, skipping!");
101                         continue;
102                 }
103                 if(fileType == fileTypeDenied)
104                 {
105                         m_filesDenied++;
106                         qWarning("Cannot access file for reading, skipping!");
107                         continue;
108                 }
109                 if(fileType == fileTypeCDDA)
110                 {
111                         m_filesDummyCDDA++;
112                         qWarning("Dummy CDDA file detected, skipping!");
113                         continue;
114                 }
115                 
116                 if(file.fileName().isEmpty() || file.formatContainerType().isEmpty() || file.formatAudioType().isEmpty())
117                 {
118                         if(PlaylistImporter::importPlaylist(m_inputFiles, currentFile))
119                         {
120                                 qDebug("Imported playlist file.");
121                         }
122                         else if(!QFileInfo(currentFile).suffix().compare("cue", Qt::CaseInsensitive))
123                         {
124                                 qWarning("Cue Sheet file detected, skipping!");
125                                 m_filesCueSheet++;
126                         }
127                         else if(!QFileInfo(currentFile).suffix().compare("avs", Qt::CaseInsensitive))
128                         {
129                                 qDebug("Found a potential Avisynth script, investigating...");
130                                 if(analyzeAvisynthFile(currentFile, file))
131                                 {
132                                         m_filesAccepted++;
133                                         emit fileAnalyzed(file);
134                                 }
135                                 else
136                                 {
137                                         qDebug("Rejected Avisynth file: %s", file.filePath().toUtf8().constData());
138                                         m_filesRejected++;
139                                 }
140                         }
141                         else
142                         {
143                                 qDebug("Rejected file of unknown type: %s", file.filePath().toUtf8().constData());
144                                 m_filesRejected++;
145                         }
146                         continue;
147                 }
148
149                 m_filesAccepted++;
150                 m_recentlyAdded.append(file.filePath());
151                 emit fileAnalyzed(file);
152         }
153
154         qDebug("All files added.\n");
155         m_bSuccess = true;
156 }
157
158 ////////////////////////////////////////////////////////////
159 // Privtae Functions
160 ////////////////////////////////////////////////////////////
161
162 const AudioFileModel FileAnalyzer::analyzeFile(const QString &filePath, int *type)
163 {
164         *type = fileTypeNormal;
165         
166         AudioFileModel audioFile(filePath);
167         m_currentSection = sectionOther;
168         m_currentCover = coverNone;
169
170         if(m_recentlyAdded.contains(filePath, Qt::CaseInsensitive))
171         {
172                 *type = fileTypeSkip;
173                 return audioFile;
174         }
175
176         QFile readTest(filePath);
177         if(!readTest.open(QIODevice::ReadOnly))
178         {
179                 *type = fileTypeDenied;
180                 return audioFile;
181         }
182         
183         if(checkFile_CDDA(readTest))
184         {
185                 *type = fileTypeCDDA;
186                 return audioFile;
187         }
188         
189         readTest.close();
190
191         QProcess process;
192         process.setProcessChannelMode(QProcess::MergedChannels);
193         process.setReadChannel(QProcess::StandardOutput);
194         process.start(m_mediaInfoBin, QStringList() << QDir::toNativeSeparators(filePath));
195                 
196         if(!process.waitForStarted())
197         {
198                 qWarning("MediaInfo process failed to create!");
199                 qWarning("Error message: \"%s\"\n", process.errorString().toLatin1().constData());
200                 process.kill();
201                 process.waitForFinished(-1);
202                 return audioFile;
203         }
204
205         while(process.state() != QProcess::NotRunning)
206         {
207                 if(m_abortFlag)
208                 {
209                         process.kill();
210                         qWarning("Process was aborted on user request!");
211                         break;
212                 }
213                 
214                 if(!process.waitForReadyRead())
215                 {
216                         if(process.state() == QProcess::Running)
217                         {
218                                 qWarning("MediaInfo time out. Killing process and skipping file!");
219                                 process.kill();
220                                 process.waitForFinished(-1);
221                                 return audioFile;
222                         }
223                 }
224
225                 QByteArray data;
226
227                 while(process.canReadLine())
228                 {
229                         QString line = QString::fromUtf8(process.readLine().constData()).simplified();
230                         if(!line.isEmpty())
231                         {
232                                 int index = line.indexOf(':');
233                                 if(index > 0)
234                                 {
235                                         QString key = line.left(index-1).trimmed();
236                                         QString val = line.mid(index+1).trimmed();
237                                         if(!key.isEmpty() && !val.isEmpty())
238                                         {
239                                                 updateInfo(audioFile, key, val);
240                                         }
241                                 }
242                                 else
243                                 {
244                                         updateSection(line);
245                                 }
246                         }
247                 }
248         }
249
250         if(audioFile.fileName().isEmpty())
251         {
252                 QString baseName = QFileInfo(filePath).fileName();
253                 int index = baseName.lastIndexOf(".");
254
255                 if(index >= 0)
256                 {
257                         baseName = baseName.left(index);
258                 }
259
260                 baseName = baseName.replace("_", " ").simplified();
261                 index = baseName.lastIndexOf(" - ");
262
263                 if(index >= 0)
264                 {
265                         baseName = baseName.mid(index + 3).trimmed();
266                 }
267
268                 audioFile.setFileName(baseName);
269         }
270         
271         process.waitForFinished();
272         if(process.state() != QProcess::NotRunning)
273         {
274                 process.kill();
275                 process.waitForFinished(-1);
276         }
277
278         if(m_currentCover != coverNone)
279         {
280                 retrieveCover(audioFile, filePath);
281         }
282
283         return audioFile;
284 }
285
286 void FileAnalyzer::updateSection(const QString &section)
287 {
288         if(section.startsWith("General", Qt::CaseInsensitive))
289         {
290                 m_currentSection = sectionGeneral;
291         }
292         else if(!section.compare("Audio", Qt::CaseInsensitive) || section.startsWith("Audio #1", Qt::CaseInsensitive))
293         {
294                 m_currentSection = sectionAudio;
295         }
296         else if(section.startsWith("Audio", Qt::CaseInsensitive) || section.startsWith("Video", Qt::CaseInsensitive) || section.startsWith("Text", Qt::CaseInsensitive) ||
297                 section.startsWith("Menu", Qt::CaseInsensitive) || section.startsWith("Image", Qt::CaseInsensitive) || section.startsWith("Chapters", Qt::CaseInsensitive))
298         {
299                 m_currentSection = sectionOther;
300         }
301         else
302         {
303                 m_currentSection = sectionOther;
304                 qWarning("Unknown section: %s", section.toUtf8().constData());
305         }
306 }
307
308 void FileAnalyzer::updateInfo(AudioFileModel &audioFile, const QString &key, const QString &value)
309 {
310         switch(m_currentSection)
311         {
312         case sectionGeneral:
313                 if(!key.compare("Title", Qt::CaseInsensitive) || !key.compare("Track", Qt::CaseInsensitive) || !key.compare("Track Name", Qt::CaseInsensitive))
314                 {
315                         if(audioFile.fileName().isEmpty()) audioFile.setFileName(value);
316                 }
317                 else if(!key.compare("Duration", Qt::CaseInsensitive))
318                 {
319                         if(!audioFile.fileDuration()) audioFile.setFileDuration(parseDuration(value));
320                 }
321                 else if(!key.compare("Artist", Qt::CaseInsensitive) || !key.compare("Performer", Qt::CaseInsensitive))
322                 {
323                         if(audioFile.fileArtist().isEmpty()) audioFile.setFileArtist(value);
324                 }
325                 else if(!key.compare("Album", Qt::CaseInsensitive))
326                 {
327                         if(audioFile.fileAlbum().isEmpty()) audioFile.setFileAlbum(value);
328                 }
329                 else if(!key.compare("Genre", Qt::CaseInsensitive))
330                 {
331                         if(audioFile.fileGenre().isEmpty()) audioFile.setFileGenre(value);
332                 }
333                 else if(!key.compare("Year", Qt::CaseInsensitive) || !key.compare("Recorded Date", Qt::CaseInsensitive) || !key.compare("Encoded Date", Qt::CaseInsensitive))
334                 {
335                         if(!audioFile.fileYear()) audioFile.setFileYear(parseYear(value));
336                 }
337                 else if(!key.compare("Comment", Qt::CaseInsensitive))
338                 {
339                         if(audioFile.fileComment().isEmpty()) audioFile.setFileComment(value);
340                 }
341                 else if(!key.compare("Track Name/Position", Qt::CaseInsensitive))
342                 {
343                         if(!audioFile.filePosition()) audioFile.setFilePosition(value.toInt());
344                 }
345                 else if(!key.compare("Format", Qt::CaseInsensitive))
346                 {
347                         if(audioFile.formatContainerType().isEmpty()) audioFile.setFormatContainerType(value);
348                 }
349                 else if(!key.compare("Format Profile", Qt::CaseInsensitive))
350                 {
351                         if(audioFile.formatContainerProfile().isEmpty()) audioFile.setFormatContainerProfile(value);
352                 }
353                 else if(!key.compare("Cover", Qt::CaseInsensitive) || !key.compare("Cover type", Qt::CaseInsensitive))
354                 {
355                         if(m_currentCover == coverNone) m_currentCover = coverJpeg;
356                 }
357                 else if(!key.compare("Cover MIME", Qt::CaseInsensitive))
358                 {
359                         QString temp = value.split(" ", QString::SkipEmptyParts, Qt::CaseInsensitive).first();
360                         if(!temp.compare("image/jpeg", Qt::CaseInsensitive))
361                         {
362                                 m_currentCover = coverJpeg;
363                         }
364                         else if(!temp.compare("image/png", Qt::CaseInsensitive))
365                         {
366                                 m_currentCover = coverPng;
367                         }
368                         else if(!temp.compare("image/gif", Qt::CaseInsensitive))
369                         {
370                                 m_currentCover = coverGif;
371                         }
372                 }
373                 break;
374
375         case sectionAudio:
376                 if(!key.compare("Year", Qt::CaseInsensitive) || !key.compare("Recorded Date", Qt::CaseInsensitive) || !key.compare("Encoded Date", Qt::CaseInsensitive))
377                 {
378                         if(!audioFile.fileYear()) audioFile.setFileYear(parseYear(value));
379                 }
380                 else if(!key.compare("Format", Qt::CaseInsensitive))
381                 {
382                         if(audioFile.formatAudioType().isEmpty()) audioFile.setFormatAudioType(value);
383                 }
384                 else if(!key.compare("Format Profile", Qt::CaseInsensitive))
385                 {
386                         if(audioFile.formatAudioProfile().isEmpty()) audioFile.setFormatAudioProfile(value);
387                 }
388                 else if(!key.compare("Format Version", Qt::CaseInsensitive))
389                 {
390                         if(audioFile.formatAudioVersion().isEmpty()) audioFile.setFormatAudioVersion(value);
391                 }
392                 else if(!key.compare("Channel(s)", Qt::CaseInsensitive))
393                 {
394                         if(!audioFile.formatAudioChannels()) audioFile.setFormatAudioChannels(value.split(" ", QString::SkipEmptyParts).first().toUInt());
395                 }
396                 else if(!key.compare("Sampling rate", Qt::CaseInsensitive))
397                 {
398                         if(!audioFile.formatAudioSamplerate())
399                         {
400                                 bool ok = false;
401                                 float fTemp = abs(value.split(" ", QString::SkipEmptyParts).first().toFloat(&ok));
402                                 if(ok) audioFile.setFormatAudioSamplerate(static_cast<unsigned int>(floor(fTemp * 1000.0f + 0.5f)));
403                         }
404                 }
405                 else if(!key.compare("Bit depth", Qt::CaseInsensitive))
406                 {
407                         if(!audioFile.formatAudioBitdepth()) audioFile.setFormatAudioBitdepth(value.split(" ", QString::SkipEmptyParts).first().toUInt());
408                 }
409                 else if(!key.compare("Duration", Qt::CaseInsensitive))
410                 {
411                         if(!audioFile.fileDuration()) audioFile.setFileDuration(parseDuration(value));
412                 }
413                 else if(!key.compare("Bit rate", Qt::CaseInsensitive))
414                 {
415                         if(!audioFile.formatAudioBitrate())
416                         {
417                                 bool ok = false;
418                                 unsigned int uiTemp = value.split(" ", QString::SkipEmptyParts).first().toUInt(&ok);
419                                 if(ok)
420                                 {
421                                         audioFile.setFormatAudioBitrate(uiTemp);
422                                 }
423                                 else
424                                 {
425                                         float fTemp = abs(value.split(" ", QString::SkipEmptyParts).first().toFloat(&ok));
426                                         if(ok) audioFile.setFormatAudioBitrate(static_cast<unsigned int>(floor(fTemp + 0.5f)));
427                                 }
428                         }
429                 }
430                 else if(!key.compare("Bit rate mode", Qt::CaseInsensitive))
431                 {
432                         if(audioFile.formatAudioBitrateMode() == AudioFileModel::BitrateModeUndefined)
433                         {
434                                 if(!value.compare("Constant", Qt::CaseInsensitive)) audioFile.setFormatAudioBitrateMode(AudioFileModel::BitrateModeConstant);
435                                 if(!value.compare("Variable", Qt::CaseInsensitive)) audioFile.setFormatAudioBitrateMode(AudioFileModel::BitrateModeVariable);
436                         }
437                 }
438                 break;
439         }
440 }
441
442 unsigned int FileAnalyzer::parseYear(const QString &str)
443 {
444         if(str.startsWith("UTC", Qt::CaseInsensitive))
445         {
446                 QDate date = QDate::fromString(str.mid(3).trimmed().left(10), "yyyy-MM-dd");
447                 if(date.isValid())
448                 {
449                         return date.year();
450                 }
451                 else
452                 {
453                         return 0;
454                 }
455         }
456         else
457         {
458                 bool ok = false;
459                 int year = str.toInt(&ok);
460                 if(ok && year > 0)
461                 {
462                         return year;
463                 }
464                 else
465                 {
466                         return 0;
467                 }
468         }
469 }
470
471 unsigned int FileAnalyzer::parseDuration(const QString &str)
472 {
473         QTime time;
474
475         time = QTime::fromString(str, "z'ms'");
476         if(time.isValid())
477         {
478                 return max(1, (time.hour() * 60 * 60) + (time.minute() * 60) + time.second());
479         }
480
481         time = QTime::fromString(str, "s's 'z'ms'");
482         if(time.isValid())
483         {
484                 return max(1, (time.hour() * 60 * 60) + (time.minute() * 60) + time.second());
485         }
486
487         time = QTime::fromString(str, "m'mn 's's'");
488         if(time.isValid())
489         {
490                 return max(1, (time.hour() * 60 * 60) + (time.minute() * 60) + time.second());
491         }
492
493         time = QTime::fromString(str, "h'h 'm'mn'");
494         if(time.isValid())
495         {
496                 return max(1, (time.hour() * 60 * 60) + (time.minute() * 60) + time.second());
497         }
498
499         return 0;
500 }
501
502 bool FileAnalyzer::checkFile_CDDA(QFile &file)
503 {
504         file.reset();
505         QByteArray data = file.read(128);
506         
507         int i = data.indexOf("RIFF");
508         int j = data.indexOf("CDDA");
509         int k = data.indexOf("fmt ");
510
511         return ((i >= 0) && (j >= 0) && (k >= 0) && (k > j) && (j > i));
512 }
513
514 void FileAnalyzer::retrieveCover(AudioFileModel &audioFile, const QString &filePath)
515 {
516         qDebug("Retrieving cover from: %s", filePath.toUtf8().constData());
517         QString extension;
518
519         switch(m_currentCover)
520         {
521         case coverPng:
522                 extension = QString::fromLatin1("png");
523                 break;
524         case coverGif:
525                 extension = QString::fromLatin1("gif");
526                 break;
527         default:
528                 extension = QString::fromLatin1("jpg");
529                 break;
530         }
531         
532         QProcess process;
533         process.setProcessChannelMode(QProcess::MergedChannels);
534         process.setReadChannel(QProcess::StandardOutput);
535         process.start(m_mediaInfoBin, QStringList() << "-f" << QDir::toNativeSeparators(filePath));
536         
537         if(!process.waitForStarted())
538         {
539                 qWarning("MediaInfo process failed to create!");
540                 qWarning("Error message: \"%s\"\n", process.errorString().toLatin1().constData());
541                 process.kill();
542                 process.waitForFinished(-1);
543                 return;
544         }
545
546         while(process.state() != QProcess::NotRunning)
547         {
548                 if(m_abortFlag)
549                 {
550                         process.kill();
551                         qWarning("Process was aborted on user request!");
552                         break;
553                 }
554                 
555                 if(!process.waitForReadyRead())
556                 {
557                         if(process.state() == QProcess::Running)
558                         {
559                                 qWarning("MediaInfo time out. Killing process and skipping file!");
560                                 process.kill();
561                                 process.waitForFinished(-1);
562                                 return;
563                         }
564                 }
565
566                 while(process.canReadLine())
567                 {
568                         QString line = QString::fromUtf8(process.readLine().constData()).simplified();
569                         if(!line.isEmpty())
570                         {
571                                 int index = line.indexOf(':');
572                                 if(index > 0)
573                                 {
574                                         QString key = line.left(index-1).trimmed();
575                                         QString val = line.mid(index+1).trimmed();
576                                         if(!key.isEmpty() && !val.isEmpty())
577                                         {
578                                                 if(!key.compare("Cover_Data", Qt::CaseInsensitive))
579                                                 {
580                                                         if(val.indexOf(" ") > 0)
581                                                         {
582                                                                 val = val.split(" ", QString::SkipEmptyParts, Qt::CaseInsensitive).first();
583                                                         }
584                                                         QByteArray coverData = QByteArray::fromBase64(val.toLatin1());
585                                                         QFile coverFile(QString("%1/%2.%3").arg(lamexp_temp_folder2(), lamexp_rand_str(), extension));
586                                                         if(coverFile.open(QIODevice::WriteOnly))
587                                                         {
588                                                                 coverFile.write(coverData);
589                                                                 coverFile.close();
590                                                                 audioFile.setFileCover(coverFile.fileName(), true);
591                                                         }
592                                                         break;
593                                                 }
594                                         }
595                                 }
596                         }
597                 }
598         }
599
600         process.waitForFinished();
601         if(process.state() != QProcess::NotRunning)
602         {
603                 process.kill();
604                 process.waitForFinished(-1);
605         }
606 }
607
608 bool FileAnalyzer::analyzeAvisynthFile(const QString &filePath, AudioFileModel &info)
609 {
610         QProcess process;
611         process.setProcessChannelMode(QProcess::MergedChannels);
612         process.setReadChannel(QProcess::StandardOutput);
613         process.start(m_avs2wavBin, QStringList() << QDir::toNativeSeparators(filePath) << "?");
614
615         if(!process.waitForStarted())
616         {
617                 qWarning("AVS2WAV process failed to create!");
618                 qWarning("Error message: \"%s\"\n", process.errorString().toLatin1().constData());
619                 process.kill();
620                 process.waitForFinished(-1);
621                 return false;
622         }
623
624         bool bInfoHeaderFound = false;
625
626         while(process.state() != QProcess::NotRunning)
627         {
628                 if(m_abortFlag)
629                 {
630                         process.kill();
631                         qWarning("Process was aborted on user request!");
632                         break;
633                 }
634                 
635                 if(!process.waitForReadyRead())
636                 {
637                         if(process.state() == QProcess::Running)
638                         {
639                                 qWarning("AVS2WAV time out. Killing process and skipping file!");
640                                 process.kill();
641                                 process.waitForFinished(-1);
642                                 return false;
643                         }
644                 }
645
646                 QByteArray data;
647
648                 while(process.canReadLine())
649                 {
650                         QString line = QString::fromUtf8(process.readLine().constData()).simplified();
651                         if(!line.isEmpty())
652                         {
653                                 int index = line.indexOf(':');
654                                 if(index > 0)
655                                 {
656                                         QString key = line.left(index).trimmed();
657                                         QString val = line.mid(index+1).trimmed();
658
659                                         if(bInfoHeaderFound && !key.isEmpty() && !val.isEmpty())
660                                         {
661                                                 if(key.compare("TotalSeconds", Qt::CaseInsensitive) == 0)
662                                                 {
663                                                         bool ok = false;
664                                                         unsigned int duration = val.toUInt(&ok);
665                                                         if(ok) info.setFileDuration(duration);
666                                                 }
667                                                 if(key.compare("SamplesPerSec", Qt::CaseInsensitive) == 0)
668                                                 {
669                                                         bool ok = false;
670                                                         unsigned int samplerate = val.toUInt(&ok);
671                                                         if(ok) info.setFormatAudioSamplerate (samplerate);
672                                                 }
673                                                 if(key.compare("Channels", Qt::CaseInsensitive) == 0)
674                                                 {
675                                                         bool ok = false;
676                                                         unsigned int channels = val.toUInt(&ok);
677                                                         if(ok) info.setFormatAudioChannels(channels);
678                                                 }
679                                                 if(key.compare("BitsPerSample", Qt::CaseInsensitive) == 0)
680                                                 {
681                                                         bool ok = false;
682                                                         unsigned int bitdepth = val.toUInt(&ok);
683                                                         if(ok) info.setFormatAudioBitdepth(bitdepth);
684                                                 }                                       
685                                         }
686                                 }
687                                 else
688                                 {
689                                         if(line.contains("[Audio Info]", Qt::CaseInsensitive))
690                                         {
691                                                 info.setFormatAudioType("Avisynth");
692                                                 info.setFormatContainerType("Avisynth");
693                                                 bInfoHeaderFound = true;
694                                         }
695                                 }
696                         }
697                 }
698         }
699         
700         process.waitForFinished();
701         if(process.state() != QProcess::NotRunning)
702         {
703                 process.kill();
704                 process.waitForFinished(-1);
705         }
706
707         //Check exit code
708         switch(process.exitCode())
709         {
710         case 0:
711                 qDebug("Avisynth script was analyzed successfully.");
712                 return true;
713                 break;
714         case -5:
715                 qWarning("It appears that Avisynth is not installed on the system!");
716                 return false;
717                 break;
718         default:
719                 qWarning("Failed to open the Avisynth script, bad AVS file?");
720                 return false;
721                 break;
722         }
723 }
724
725 ////////////////////////////////////////////////////////////
726 // Public Functions
727 ////////////////////////////////////////////////////////////
728
729 unsigned int FileAnalyzer::filesAccepted(void)
730 {
731         return m_filesAccepted;
732 }
733
734 unsigned int FileAnalyzer::filesRejected(void)
735 {
736         return m_filesRejected;
737 }
738
739 unsigned int FileAnalyzer::filesDenied(void)
740 {
741         return m_filesDenied;
742 }
743
744 unsigned int FileAnalyzer::filesDummyCDDA(void)
745 {
746         return m_filesDummyCDDA;
747 }
748
749 unsigned int FileAnalyzer::filesCueSheet(void)
750 {
751         return m_filesCueSheet;
752 }
753
754 ////////////////////////////////////////////////////////////
755 // EVENTS
756 ////////////////////////////////////////////////////////////
757
758 /*NONE*/