2010-11-06 23:04:47 +01:00
|
|
|
///////////////////////////////////////////////////////////////////////////////
|
|
|
|
// LameXP - Audio Encoder Front-End
|
2012-01-02 00:52:27 +01:00
|
|
|
// Copyright (C) 2004-2012 LoRd_MuldeR <MuldeR2@GMX.de>
|
2010-11-06 23:04:47 +01:00
|
|
|
//
|
|
|
|
// 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 "Thread_FileAnalyzer.h"
|
|
|
|
|
|
|
|
#include "Global.h"
|
|
|
|
#include "LockedFile.h"
|
|
|
|
#include "Model_AudioFile.h"
|
2012-05-04 04:01:10 +02:00
|
|
|
#include "Thread_FileAnalyzer_Task.h"
|
2010-11-06 23:04:47 +01:00
|
|
|
|
|
|
|
#include <QDir>
|
|
|
|
#include <QFileInfo>
|
|
|
|
#include <QProcess>
|
|
|
|
#include <QDate>
|
|
|
|
#include <QTime>
|
2010-11-22 21:45:00 +01:00
|
|
|
#include <QDebug>
|
2011-11-19 14:06:39 +01:00
|
|
|
#include <QImage>
|
2012-05-04 04:01:10 +02:00
|
|
|
#include <QThreadPool>
|
2012-05-05 03:55:27 +02:00
|
|
|
#include <QTime>
|
2012-01-14 01:11:58 +01:00
|
|
|
|
2010-11-06 23:04:47 +01:00
|
|
|
////////////////////////////////////////////////////////////
|
|
|
|
// Constructor
|
|
|
|
////////////////////////////////////////////////////////////
|
|
|
|
|
|
|
|
FileAnalyzer::FileAnalyzer(const QStringList &inputFiles)
|
2010-12-18 15:15:17 +01:00
|
|
|
:
|
2012-05-04 04:01:10 +02:00
|
|
|
m_abortFlag(false),
|
2010-12-18 15:15:17 +01:00
|
|
|
m_inputFiles(inputFiles),
|
2012-05-04 04:01:10 +02:00
|
|
|
m_templateFile(NULL)
|
2010-11-06 23:04:47 +01:00
|
|
|
{
|
|
|
|
m_bSuccess = false;
|
2011-05-16 21:02:24 +02:00
|
|
|
m_bAborted = false;
|
2010-11-06 23:04:47 +01:00
|
|
|
}
|
|
|
|
|
2012-01-14 01:11:58 +01:00
|
|
|
FileAnalyzer::~FileAnalyzer(void)
|
|
|
|
{
|
|
|
|
if(m_templateFile)
|
|
|
|
{
|
|
|
|
QString templatePath = m_templateFile->filePath();
|
|
|
|
LAMEXP_DELETE(m_templateFile);
|
|
|
|
if(QFile::exists(templatePath)) QFile::remove(templatePath);
|
|
|
|
}
|
2012-05-04 04:01:10 +02:00
|
|
|
|
|
|
|
AnalyzeTask::reset();
|
2012-01-14 01:11:58 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
////////////////////////////////////////////////////////////
|
|
|
|
// Static data
|
|
|
|
////////////////////////////////////////////////////////////
|
|
|
|
|
|
|
|
const char *FileAnalyzer::g_tags_gen[] =
|
|
|
|
{
|
2012-01-14 20:28:43 +01:00
|
|
|
"ID",
|
2012-01-14 01:11:58 +01:00
|
|
|
"Format",
|
|
|
|
"Format_Profile",
|
|
|
|
"Format_Version",
|
|
|
|
"Duration",
|
|
|
|
"Title", "Track",
|
|
|
|
"Track/Position",
|
|
|
|
"Artist", "Performer",
|
|
|
|
"Album",
|
|
|
|
"Genre",
|
|
|
|
"Released_Date", "Recorded_Date",
|
|
|
|
"Comment",
|
|
|
|
"Cover",
|
|
|
|
"Cover_Type",
|
|
|
|
"Cover_Mime",
|
|
|
|
"Cover_Data",
|
|
|
|
NULL
|
|
|
|
};
|
|
|
|
|
|
|
|
const char *FileAnalyzer::g_tags_aud[] =
|
|
|
|
{
|
2012-01-14 20:28:43 +01:00
|
|
|
"ID",
|
2012-04-20 22:39:19 +02:00
|
|
|
"Source",
|
2012-01-14 01:11:58 +01:00
|
|
|
"Format",
|
|
|
|
"Format_Profile",
|
|
|
|
"Format_Version",
|
|
|
|
"Channel(s)",
|
|
|
|
"SamplingRate",
|
2012-03-08 01:34:00 +01:00
|
|
|
"BitDepth",
|
2012-01-14 01:11:58 +01:00
|
|
|
"BitRate",
|
|
|
|
"BitRate_Mode",
|
|
|
|
NULL
|
|
|
|
};
|
|
|
|
|
2010-11-06 23:04:47 +01:00
|
|
|
////////////////////////////////////////////////////////////
|
|
|
|
// Thread Main
|
|
|
|
////////////////////////////////////////////////////////////
|
|
|
|
|
|
|
|
void FileAnalyzer::run()
|
|
|
|
{
|
2012-05-06 04:57:00 +02:00
|
|
|
m_abortFlag = false;
|
|
|
|
|
2011-05-16 21:02:24 +02:00
|
|
|
m_bAborted = false;
|
2012-05-06 04:57:00 +02:00
|
|
|
m_bSuccess = false;
|
|
|
|
|
|
|
|
int nFiles = m_inputFiles.count();
|
|
|
|
|
|
|
|
emit progressMaxChanged(nFiles);
|
|
|
|
emit progressValChanged(0);
|
2010-11-11 19:37:16 +01:00
|
|
|
|
2010-11-06 23:04:47 +01:00
|
|
|
m_inputFiles.sort();
|
2011-04-11 21:57:16 +02:00
|
|
|
|
2012-01-14 01:11:58 +01:00
|
|
|
if(!m_templateFile)
|
|
|
|
{
|
|
|
|
if(!createTemplate())
|
|
|
|
{
|
|
|
|
qWarning("Failed to create template file!");
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2012-05-04 04:01:10 +02:00
|
|
|
AnalyzeTask::reset();
|
|
|
|
QThreadPool *pool = new QThreadPool();
|
2012-05-06 04:57:00 +02:00
|
|
|
QThread::msleep(333);
|
|
|
|
|
2012-05-12 02:51:24 +02:00
|
|
|
pool->setMaxThreadCount(qBound(2, ((QThread::idealThreadCount() * 3) / 2), 12));
|
2012-05-04 04:01:10 +02:00
|
|
|
|
|
|
|
while(!(m_inputFiles.isEmpty() || m_bAborted))
|
2010-11-06 23:04:47 +01:00
|
|
|
{
|
2012-05-04 04:01:10 +02:00
|
|
|
while(!(m_inputFiles.isEmpty() || m_bAborted))
|
2010-11-07 23:06:30 +01:00
|
|
|
{
|
2012-05-25 02:24:44 +02:00
|
|
|
if(!AnalyzeTask::waitForFreeSlot(&m_abortFlag))
|
2010-11-08 00:24:54 +01:00
|
|
|
{
|
2012-05-25 02:24:44 +02:00
|
|
|
qWarning("Timeout in AnalyzeTask::waitForFreeSlot() !!!");
|
2010-11-08 00:24:54 +01:00
|
|
|
}
|
2010-11-18 22:37:35 +01:00
|
|
|
|
2012-05-04 04:01:10 +02:00
|
|
|
if(m_abortFlag)
|
2010-11-06 23:04:47 +01:00
|
|
|
{
|
2012-05-04 04:01:10 +02:00
|
|
|
MessageBeep(MB_ICONERROR);
|
|
|
|
m_bAborted = true;
|
2012-05-25 02:24:44 +02:00
|
|
|
break;
|
2010-11-06 23:04:47 +01:00
|
|
|
}
|
2012-05-12 02:51:24 +02:00
|
|
|
|
|
|
|
if(!m_bAborted)
|
2012-05-06 04:57:00 +02:00
|
|
|
{
|
2012-05-25 02:24:44 +02:00
|
|
|
const QString currentFile = QDir::fromNativeSeparators(m_inputFiles.takeFirst());
|
|
|
|
|
|
|
|
AnalyzeTask *task = new AnalyzeTask(currentFile, m_templateFile->filePath(), &m_abortFlag);
|
|
|
|
connect(task, SIGNAL(fileSelected(QString)), this, SIGNAL(fileSelected(QString)), Qt::DirectConnection);
|
|
|
|
connect(task, SIGNAL(progressValChanged(unsigned int)), this, SIGNAL(progressValChanged(unsigned int)), Qt::DirectConnection);
|
|
|
|
connect(task, SIGNAL(progressMaxChanged(unsigned int)), this, SIGNAL(progressMaxChanged(unsigned int)), Qt::DirectConnection);
|
|
|
|
connect(task, SIGNAL(fileAnalyzed(AudioFileModel)), this, SIGNAL(fileAnalyzed(AudioFileModel)), Qt::DirectConnection);
|
|
|
|
|
|
|
|
pool->start(task);
|
|
|
|
|
2012-05-08 01:12:26 +02:00
|
|
|
if(int count = AnalyzeTask::getAdditionalFiles(m_inputFiles))
|
|
|
|
{
|
|
|
|
emit progressMaxChanged(nFiles += count);
|
|
|
|
}
|
2012-05-06 04:57:00 +02:00
|
|
|
}
|
2010-11-06 23:04:47 +01:00
|
|
|
}
|
|
|
|
|
2012-05-05 03:55:27 +02:00
|
|
|
//One of the Analyze tasks may have gathered additional files from a playlist!
|
2012-05-04 04:01:10 +02:00
|
|
|
if(!m_bAborted)
|
2010-11-06 23:04:47 +01:00
|
|
|
{
|
2012-05-04 04:01:10 +02:00
|
|
|
pool->waitForDone();
|
2012-05-08 01:12:26 +02:00
|
|
|
if(int count = AnalyzeTask::getAdditionalFiles(m_inputFiles))
|
|
|
|
{
|
|
|
|
emit progressMaxChanged(nFiles += count);
|
|
|
|
}
|
2010-11-06 23:04:47 +01:00
|
|
|
}
|
|
|
|
}
|
2010-11-08 00:24:54 +01:00
|
|
|
|
2012-05-04 04:01:10 +02:00
|
|
|
pool->waitForDone();
|
|
|
|
LAMEXP_DELETE(pool);
|
2012-05-05 03:55:27 +02:00
|
|
|
|
2012-05-04 04:01:10 +02:00
|
|
|
if(m_bAborted)
|
2010-11-06 23:04:47 +01:00
|
|
|
{
|
2012-05-04 04:01:10 +02:00
|
|
|
qWarning("Operation cancelled by user!");
|
2012-01-14 20:28:43 +01:00
|
|
|
return;
|
2010-11-06 23:04:47 +01:00
|
|
|
}
|
2012-05-04 16:40:02 +02:00
|
|
|
|
2012-05-04 04:01:10 +02:00
|
|
|
qDebug("All files added.\n");
|
|
|
|
m_bSuccess = true;
|
2011-03-20 23:32:11 +01:00
|
|
|
}
|
|
|
|
|
2012-05-04 04:01:10 +02:00
|
|
|
////////////////////////////////////////////////////////////
|
|
|
|
// Privtae Functions
|
|
|
|
////////////////////////////////////////////////////////////
|
2011-05-21 21:08:10 +02:00
|
|
|
|
2012-01-14 01:11:58 +01:00
|
|
|
bool FileAnalyzer::createTemplate(void)
|
|
|
|
{
|
|
|
|
if(m_templateFile)
|
|
|
|
{
|
|
|
|
qWarning("Template file already exists!");
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
|
|
|
QString templatePath = QString("%1/%2.txt").arg(lamexp_temp_folder2(), lamexp_rand_str());
|
|
|
|
|
|
|
|
QFile templateFile(templatePath);
|
|
|
|
if(!templateFile.open(QIODevice::WriteOnly))
|
|
|
|
{
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
templateFile.write("General;");
|
|
|
|
for(size_t i = 0; g_tags_gen[i]; i++)
|
|
|
|
{
|
|
|
|
templateFile.write(QString("Gen_%1=%%1%\\n").arg(g_tags_gen[i]).toLatin1().constData());
|
|
|
|
}
|
2012-01-14 20:28:43 +01:00
|
|
|
templateFile.write("\\n\r\n");
|
2012-01-14 01:11:58 +01:00
|
|
|
|
|
|
|
templateFile.write("Audio;");
|
|
|
|
for(size_t i = 0; g_tags_aud[i]; i++)
|
|
|
|
{
|
|
|
|
templateFile.write(QString("Aud_%1=%%1%\\n").arg(g_tags_aud[i]).toLatin1().constData());
|
|
|
|
}
|
2012-01-14 20:28:43 +01:00
|
|
|
templateFile.write("\\n\r\n");
|
2012-01-14 01:11:58 +01:00
|
|
|
|
|
|
|
bool success = (templateFile.error() == QFile::NoError);
|
|
|
|
templateFile.close();
|
|
|
|
|
|
|
|
if(!success)
|
|
|
|
{
|
|
|
|
QFile::remove(templatePath);
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
try
|
|
|
|
{
|
|
|
|
m_templateFile = new LockedFile(templatePath);
|
|
|
|
}
|
|
|
|
catch(...)
|
|
|
|
{
|
|
|
|
qWarning("Failed to lock template file!");
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
2011-01-30 21:49:32 +01:00
|
|
|
////////////////////////////////////////////////////////////
|
|
|
|
// Public Functions
|
|
|
|
////////////////////////////////////////////////////////////
|
|
|
|
|
2010-11-11 19:37:16 +01:00
|
|
|
unsigned int FileAnalyzer::filesAccepted(void)
|
|
|
|
{
|
2012-05-04 04:01:10 +02:00
|
|
|
return AnalyzeTask::filesAccepted();
|
2010-11-11 19:37:16 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
unsigned int FileAnalyzer::filesRejected(void)
|
|
|
|
{
|
2012-05-04 04:01:10 +02:00
|
|
|
return AnalyzeTask::filesRejected();
|
2010-11-11 19:37:16 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
unsigned int FileAnalyzer::filesDenied(void)
|
|
|
|
{
|
2012-05-04 04:01:10 +02:00
|
|
|
return AnalyzeTask::filesDenied();
|
2010-11-11 19:37:16 +01:00
|
|
|
}
|
2010-11-06 23:04:47 +01:00
|
|
|
|
2011-03-19 15:35:17 +01:00
|
|
|
unsigned int FileAnalyzer::filesDummyCDDA(void)
|
|
|
|
{
|
2012-05-04 04:01:10 +02:00
|
|
|
return AnalyzeTask::filesDummyCDDA();
|
2011-03-19 15:35:17 +01:00
|
|
|
}
|
|
|
|
|
2011-05-17 01:14:50 +02:00
|
|
|
unsigned int FileAnalyzer::filesCueSheet(void)
|
|
|
|
{
|
2012-05-04 04:01:10 +02:00
|
|
|
return AnalyzeTask::filesCueSheet();
|
2011-05-17 01:14:50 +02:00
|
|
|
}
|
|
|
|
|
2010-11-06 23:04:47 +01:00
|
|
|
////////////////////////////////////////////////////////////
|
|
|
|
// EVENTS
|
|
|
|
////////////////////////////////////////////////////////////
|
|
|
|
|
2010-11-08 00:24:54 +01:00
|
|
|
/*NONE*/
|