Updated Changelog.
[LameXP.git] / src / Thread_FileAnalyzer.cpp
blob2f7f4b9101cb472e296025ce40d3889fef292576
1 ///////////////////////////////////////////////////////////////////////////////
2 // LameXP - Audio Encoder Front-End
3 // Copyright (C) 2004-2012 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 "Thread_FileAnalyzer.h"
24 #include "Global.h"
25 #include "LockedFile.h"
26 #include "Model_AudioFile.h"
27 #include "Thread_FileAnalyzer_Task.h"
29 #include <QDir>
30 #include <QFileInfo>
31 #include <QProcess>
32 #include <QDate>
33 #include <QTime>
34 #include <QDebug>
35 #include <QImage>
36 #include <QThreadPool>
37 #include <QTime>
39 ////////////////////////////////////////////////////////////
40 // Constructor
41 ////////////////////////////////////////////////////////////
43 FileAnalyzer::FileAnalyzer(const QStringList &inputFiles)
45 m_abortFlag(false),
46 m_inputFiles(inputFiles),
47 m_templateFile(NULL)
49 m_bSuccess = false;
50 m_bAborted = false;
53 FileAnalyzer::~FileAnalyzer(void)
55 if(m_templateFile)
57 QString templatePath = m_templateFile->filePath();
58 LAMEXP_DELETE(m_templateFile);
59 if(QFile::exists(templatePath)) QFile::remove(templatePath);
62 AnalyzeTask::reset();
65 ////////////////////////////////////////////////////////////
66 // Static data
67 ////////////////////////////////////////////////////////////
69 const char *FileAnalyzer::g_tags_gen[] =
71 "ID",
72 "Format",
73 "Format_Profile",
74 "Format_Version",
75 "Duration",
76 "Title", "Track",
77 "Track/Position",
78 "Artist", "Performer",
79 "Album",
80 "Genre",
81 "Released_Date", "Recorded_Date",
82 "Comment",
83 "Cover",
84 "Cover_Type",
85 "Cover_Mime",
86 "Cover_Data",
87 NULL
90 const char *FileAnalyzer::g_tags_aud[] =
92 "ID",
93 "Source",
94 "Format",
95 "Format_Profile",
96 "Format_Version",
97 "Channel(s)",
98 "SamplingRate",
99 "BitDepth",
100 "BitRate",
101 "BitRate_Mode",
102 NULL
105 ////////////////////////////////////////////////////////////
106 // Thread Main
107 ////////////////////////////////////////////////////////////
109 void FileAnalyzer::run()
111 qWarning("--- FileAnalyzer::run() ---");
113 m_abortFlag = false;
115 m_bAborted = false;
116 m_bSuccess = false;
118 int nFiles = m_inputFiles.count();
120 emit progressMaxChanged(nFiles);
121 emit progressValChanged(0);
123 m_inputFiles.sort();
125 if(!m_templateFile)
127 if(!createTemplate())
129 qWarning("Failed to create template file!");
130 return;
134 AnalyzeTask::reset();
135 QThreadPool *pool = new QThreadPool();
136 QThread::msleep(333);
138 pool->setMaxThreadCount(qBound(2, ((QThread::idealThreadCount() * 3) / 2), 12));
140 while(!(m_inputFiles.isEmpty() || m_bAborted))
142 while(!(m_inputFiles.isEmpty() || m_bAborted))
144 if(!AnalyzeTask::waitForFreeSlot(&m_abortFlag))
146 qWarning("Timeout in AnalyzeTask::waitForFreeSlot() !!!");
149 if(m_abortFlag)
151 MessageBeep(MB_ICONERROR);
152 m_bAborted = true;
153 break;
156 if(!m_bAborted)
158 const QString currentFile = QDir::fromNativeSeparators(m_inputFiles.takeFirst());
160 AnalyzeTask *task = new AnalyzeTask(currentFile, m_templateFile->filePath(), &m_abortFlag);
161 connect(task, SIGNAL(fileSelected(QString)), this, SIGNAL(fileSelected(QString)), Qt::DirectConnection);
162 connect(task, SIGNAL(progressValChanged(unsigned int)), this, SIGNAL(progressValChanged(unsigned int)), Qt::DirectConnection);
163 connect(task, SIGNAL(progressMaxChanged(unsigned int)), this, SIGNAL(progressMaxChanged(unsigned int)), Qt::DirectConnection);
164 connect(task, SIGNAL(fileAnalyzed(AudioFileModel)), this, SIGNAL(fileAnalyzed(AudioFileModel)), Qt::DirectConnection);
166 pool->start(task);
168 if(int count = AnalyzeTask::getAdditionalFiles(m_inputFiles))
170 emit progressMaxChanged(nFiles += count);
175 //One of the Analyze tasks may have gathered additional files from a playlist!
176 if(!m_bAborted)
178 pool->waitForDone();
179 if(int count = AnalyzeTask::getAdditionalFiles(m_inputFiles))
181 emit progressMaxChanged(nFiles += count);
186 pool->waitForDone();
187 LAMEXP_DELETE(pool);
189 if(m_bAborted)
191 qWarning("Operation cancelled by user!");
192 return;
195 qDebug("All files added.\n");
196 m_bSuccess = true;
199 ////////////////////////////////////////////////////////////
200 // Privtae Functions
201 ////////////////////////////////////////////////////////////
203 bool FileAnalyzer::createTemplate(void)
205 if(m_templateFile)
207 qWarning("Template file already exists!");
208 return true;
211 QString templatePath = QString("%1/%2.txt").arg(lamexp_temp_folder2(), lamexp_rand_str());
213 QFile templateFile(templatePath);
214 if(!templateFile.open(QIODevice::WriteOnly))
216 return false;
219 templateFile.write("General;");
220 for(size_t i = 0; g_tags_gen[i]; i++)
222 templateFile.write(QString("Gen_%1=%%1%\\n").arg(g_tags_gen[i]).toLatin1().constData());
224 templateFile.write("\\n\r\n");
226 templateFile.write("Audio;");
227 for(size_t i = 0; g_tags_aud[i]; i++)
229 templateFile.write(QString("Aud_%1=%%1%\\n").arg(g_tags_aud[i]).toLatin1().constData());
231 templateFile.write("\\n\r\n");
233 bool success = (templateFile.error() == QFile::NoError);
234 templateFile.close();
236 if(!success)
238 QFile::remove(templatePath);
239 return false;
244 m_templateFile = new LockedFile(templatePath);
246 catch(...)
248 qWarning("Failed to lock template file!");
249 return false;
252 return true;
255 ////////////////////////////////////////////////////////////
256 // Public Functions
257 ////////////////////////////////////////////////////////////
259 unsigned int FileAnalyzer::filesAccepted(void)
261 return AnalyzeTask::filesAccepted();
264 unsigned int FileAnalyzer::filesRejected(void)
266 return AnalyzeTask::filesRejected();
269 unsigned int FileAnalyzer::filesDenied(void)
271 return AnalyzeTask::filesDenied();
274 unsigned int FileAnalyzer::filesDummyCDDA(void)
276 return AnalyzeTask::filesDummyCDDA();
279 unsigned int FileAnalyzer::filesCueSheet(void)
281 return AnalyzeTask::filesCueSheet();
284 ////////////////////////////////////////////////////////////
285 // EVENTS
286 ////////////////////////////////////////////////////////////
288 /*NONE*/