First step for Cue Sheet splitting: Call the FileAnalyzer thread in order to analyze all source files.

This commit is contained in:
LoRd_MuldeR 2011-05-14 18:34:34 +02:00
parent 49dd3f0446
commit 564cad5047
8 changed files with 428 additions and 26 deletions

View File

@ -170,6 +170,11 @@
<property name="margin"> <property name="margin">
<number>9</number> <number>9</number>
</property> </property>
<item>
<layout class="QVBoxLayout" name="verticalLayout_4">
<property name="spacing">
<number>2</number>
</property>
<item> <item>
<widget class="QTreeView" name="treeView"> <widget class="QTreeView" name="treeView">
<property name="alternatingRowColors"> <property name="alternatingRowColors">
@ -183,6 +188,265 @@
</property> </property>
</widget> </widget>
</item> </item>
<item>
<layout class="QHBoxLayout" name="horizontalLayout_6">
<item>
<widget class="QFrame" name="frame_4">
<property name="minimumSize">
<size>
<width>16</width>
<height>16</height>
</size>
</property>
<property name="maximumSize">
<size>
<width>16</width>
<height>16</height>
</size>
</property>
<property name="palette">
<palette>
<active>
<colorrole role="Base">
<brush brushstyle="SolidPattern">
<color alpha="255">
<red>255</red>
<green>255</green>
<blue>255</blue>
</color>
</brush>
</colorrole>
<colorrole role="Window">
<brush brushstyle="SolidPattern">
<color alpha="255">
<red>0</red>
<green>0</green>
<blue>255</blue>
</color>
</brush>
</colorrole>
</active>
<inactive>
<colorrole role="Base">
<brush brushstyle="SolidPattern">
<color alpha="255">
<red>255</red>
<green>255</green>
<blue>255</blue>
</color>
</brush>
</colorrole>
<colorrole role="Window">
<brush brushstyle="SolidPattern">
<color alpha="255">
<red>0</red>
<green>0</green>
<blue>255</blue>
</color>
</brush>
</colorrole>
</inactive>
<disabled>
<colorrole role="Base">
<brush brushstyle="SolidPattern">
<color alpha="255">
<red>0</red>
<green>0</green>
<blue>255</blue>
</color>
</brush>
</colorrole>
<colorrole role="Window">
<brush brushstyle="SolidPattern">
<color alpha="255">
<red>0</red>
<green>0</green>
<blue>255</blue>
</color>
</brush>
</colorrole>
</disabled>
</palette>
</property>
<property name="autoFillBackground">
<bool>true</bool>
</property>
<property name="frameShape">
<enum>QFrame::StyledPanel</enum>
</property>
<property name="frameShadow">
<enum>QFrame::Plain</enum>
</property>
</widget>
</item>
<item>
<spacer name="horizontalSpacer_4">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="sizeType">
<enum>QSizePolicy::Fixed</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>4</width>
<height>20</height>
</size>
</property>
</spacer>
</item>
<item>
<widget class="QLabel" name="label_3">
<property name="text">
<string>Existing Source File</string>
</property>
</widget>
</item>
<item>
<spacer name="horizontalSpacer_3">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="sizeType">
<enum>QSizePolicy::Fixed</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>12</width>
<height>20</height>
</size>
</property>
</spacer>
</item>
<item>
<widget class="QFrame" name="frame_3">
<property name="minimumSize">
<size>
<width>16</width>
<height>16</height>
</size>
</property>
<property name="maximumSize">
<size>
<width>16</width>
<height>16</height>
</size>
</property>
<property name="palette">
<palette>
<active>
<colorrole role="Base">
<brush brushstyle="SolidPattern">
<color alpha="255">
<red>255</red>
<green>255</green>
<blue>255</blue>
</color>
</brush>
</colorrole>
<colorrole role="Window">
<brush brushstyle="SolidPattern">
<color alpha="255">
<red>170</red>
<green>0</green>
<blue>0</blue>
</color>
</brush>
</colorrole>
</active>
<inactive>
<colorrole role="Base">
<brush brushstyle="SolidPattern">
<color alpha="255">
<red>255</red>
<green>255</green>
<blue>255</blue>
</color>
</brush>
</colorrole>
<colorrole role="Window">
<brush brushstyle="SolidPattern">
<color alpha="255">
<red>170</red>
<green>0</green>
<blue>0</blue>
</color>
</brush>
</colorrole>
</inactive>
<disabled>
<colorrole role="Base">
<brush brushstyle="SolidPattern">
<color alpha="255">
<red>170</red>
<green>0</green>
<blue>0</blue>
</color>
</brush>
</colorrole>
<colorrole role="Window">
<brush brushstyle="SolidPattern">
<color alpha="255">
<red>170</red>
<green>0</green>
<blue>0</blue>
</color>
</brush>
</colorrole>
</disabled>
</palette>
</property>
<property name="autoFillBackground">
<bool>true</bool>
</property>
<property name="frameShape">
<enum>QFrame::StyledPanel</enum>
</property>
<property name="frameShadow">
<enum>QFrame::Plain</enum>
</property>
</widget>
</item>
<item>
<spacer name="horizontalSpacer_5">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="sizeType">
<enum>QSizePolicy::Fixed</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>4</width>
<height>20</height>
</size>
</property>
</spacer>
</item>
<item>
<widget class="QLabel" name="label_2">
<property name="text">
<string>Missing Source File (Tracks will be skipped!)</string>
</property>
</widget>
</item>
<item>
<spacer name="horizontalSpacer_2">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>40</width>
<height>20</height>
</size>
</property>
</spacer>
</item>
</layout>
</item>
</layout>
</item>
<item> <item>
<widget class="QGroupBox" name="groupBoxArtwork"> <widget class="QGroupBox" name="groupBoxArtwork">
<property name="contextMenuPolicy"> <property name="contextMenuPolicy">
@ -316,7 +580,6 @@
<tabstop>abortButton</tabstop> <tabstop>abortButton</tabstop>
<tabstop>editOutputDir</tabstop> <tabstop>editOutputDir</tabstop>
<tabstop>browseButton</tabstop> <tabstop>browseButton</tabstop>
<tabstop>treeView</tabstop>
</tabstops> </tabstops>
<resources> <resources>
<include location="../res/Icons.qrc"/> <include location="../res/Icons.qrc"/>
@ -351,6 +614,8 @@
<include location="../res/Images.qrc"/> <include location="../res/Images.qrc"/>
<include location="../res/Images.qrc"/> <include location="../res/Images.qrc"/>
<include location="../res/Images.qrc"/> <include location="../res/Images.qrc"/>
<include location="../res/Images.qrc"/>
<include location="../res/Images.qrc"/>
</resources> </resources>
<connections> <connections>
<connection> <connection>

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.0 KiB

After

Width:  |  Height:  |  Size: 3.5 KiB

View File

@ -30,7 +30,7 @@
#define VER_LAMEXP_MINOR_LO 2 #define VER_LAMEXP_MINOR_LO 2
#define VER_LAMEXP_TYPE Alpha #define VER_LAMEXP_TYPE Alpha
#define VER_LAMEXP_PATCH 14 #define VER_LAMEXP_PATCH 14
#define VER_LAMEXP_BUILD 513 #define VER_LAMEXP_BUILD 515
/////////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////////
// Tools versions // Tools versions

View File

@ -23,7 +23,9 @@
#include "Global.h" #include "Global.h"
#include "Model_CueSheet.h" #include "Model_CueSheet.h"
#include "Model_AudioFile.h"
#include "Dialog_WorkingBanner.h" #include "Dialog_WorkingBanner.h"
#include "Thread_FileAnalyzer.h"
#include <QFileInfo> #include <QFileInfo>
#include <QMessageBox> #include <QMessageBox>
@ -96,6 +98,8 @@ int CueImportDialog::exec(const QString &cueFile)
QFileInfo cueFileInfo(cueFile); QFileInfo cueFileInfo(cueFile);
m_outputDir = QFileInfo(cueFile).canonicalPath(); m_outputDir = QFileInfo(cueFile).canonicalPath();
setWindowTitle(QString("%1: %2").arg(windowTitle().split(":", QString::SkipEmptyParts).first().trimmed(), cueFileInfo.fileName()));
if(!cueFileInfo.exists() || !cueFileInfo.isFile() || m_outputDir.isEmpty()) if(!cueFileInfo.exists() || !cueFileInfo.isFile() || m_outputDir.isEmpty())
{ {
QString text = QString("<nobr>%1</nobr><br><nobr>%2</nobr><br><br><nobr>%3</nobr>").arg(tr("Failed to load the Cue Sheet file:"), QDir::toNativeSeparators(cueFile), tr("The specified file could not be found!")).replace("-", "&minus;"); QString text = QString("<nobr>%1</nobr><br><nobr>%2</nobr><br><br><nobr>%3</nobr>").arg(tr("Failed to load the Cue Sheet file:"), QDir::toNativeSeparators(cueFile), tr("The specified file could not be found!")).replace("-", "&minus;");
@ -156,5 +160,67 @@ void CueImportDialog::browseButtonClicked(void)
void CueImportDialog::importButtonClicked(void) void CueImportDialog::importButtonClicked(void)
{ {
QMessageBox::information(this, "Not implemenred", "Sorry, not yet. Please try again in a later version!"); static const __int64 oneGigabyte = 1073741824i64;
static const __int64 minimumFreeDiskspaceMultiplier = 2i64;
static const char *writeTestBuffer = "LAMEXP_WRITE_TEST";
QFile writeTest(QString("%1/~%2.txt").arg(m_outputDir, lamexp_rand_str()));
if(!(writeTest.open(QIODevice::ReadWrite) && (writeTest.write(writeTestBuffer) == strlen(writeTestBuffer))))
{
QMessageBox::warning(this, tr("LameXP"), QString("<nobr>%2</nobr>").arg(tr("Error: The selected output directory is not writable!")));
return;
}
else
{
writeTest.close();
writeTest.remove();
}
qint64 currentFreeDiskspace = lamexp_free_diskspace(m_outputDir);
if(currentFreeDiskspace < (oneGigabyte * minimumFreeDiskspaceMultiplier))
{
QMessageBox::warning(this, tr("Low Diskspace Warning"), QString("<nobr>%1</nobr><br><nobr>%2</nobr>").arg(tr("There are less than %1 GB of free diskspace available in the selected output directory.").arg(QString::number(minimumFreeDiskspaceMultiplier)), tr("It is highly recommend to free up more diskspace before proceeding with the import!")));
return;
}
importCueSheet();
}
void CueImportDialog::analyzedFile(const AudioFileModel &file)
{
qWarning("Received results for: %s", file.filePath().toLatin1().constData());
m_fileInfo.insert(file.filePath(), file);
}
////////////////////////////////////////////////////////////
// Private FUnctions
////////////////////////////////////////////////////////////
void CueImportDialog::importCueSheet(void)
{
QStringList files;
int nFiles = m_model->getFileCount();
//Fetch all files that are referenced in the Cue Sheet
for(int i = 0; i < nFiles; i++)
{
files << m_model->getFileName(i);
}
//Analyze all source files
analyzeFiles(files);
}
void CueImportDialog::analyzeFiles(QStringList &files)
{
m_fileInfo.clear();
WorkingBanner *progress = new WorkingBanner(dynamic_cast<QWidget*>(parent()));
FileAnalyzer *analyzer = new FileAnalyzer(files);
connect(analyzer, SIGNAL(fileSelected(QString)), progress, SLOT(setText(QString)), Qt::QueuedConnection);
connect(analyzer, SIGNAL(fileAnalyzed(AudioFileModel)), this, SLOT(analyzedFile(AudioFileModel)), Qt::QueuedConnection);
progress->show(tr("Adding file(s), please wait..."), analyzer);
progress->close();
LAMEXP_DELETE(progress);
} }

View File

@ -45,8 +45,13 @@ private slots:
void browseButtonClicked(void); void browseButtonClicked(void);
void importButtonClicked(void); void importButtonClicked(void);
void modelChanged(void); void modelChanged(void);
void analyzedFile(const AudioFileModel &file);
private: private:
void importCueSheet(void);
void analyzeFiles(QStringList &files);
CueSheetModel *m_model; CueSheetModel *m_model;
QMap<QString, AudioFileModel> m_fileInfo;
QString m_outputDir; QString m_outputDir;
}; };

View File

@ -1025,6 +1025,7 @@ void MainWindow::encodeButtonClicked(void)
{ {
static const __int64 oneGigabyte = 1073741824i64; static const __int64 oneGigabyte = 1073741824i64;
static const __int64 minimumFreeDiskspaceMultiplier = 2i64; static const __int64 minimumFreeDiskspaceMultiplier = 2i64;
static const char *writeTestBuffer = "LAMEXP_WRITE_TEST";
ABORT_IF_BUSY; ABORT_IF_BUSY;
@ -1081,8 +1082,8 @@ void MainWindow::encodeButtonClicked(void)
if(!m_settings->outputToSourceDir()) if(!m_settings->outputToSourceDir())
{ {
QFile writeTest(QString("%1/~%2.txt").arg(m_settings->outputDir(), QUuid::createUuid().toString())); QFile writeTest(QString("%1/~%2.txt").arg(m_settings->outputDir(), lamexp_rand_str()));
if(!writeTest.open(QIODevice::ReadWrite)) if(!(writeTest.open(QIODevice::ReadWrite) && (writeTest.write(writeTestBuffer) == strlen(writeTestBuffer))))
{ {
QMessageBox::warning(this, tr("LameXP"), QString("%1<br><nobr>%2</nobr><br><br>%3").arg(tr("Cannot write to the selected output directory."), m_settings->outputDir(), tr("Please choose a different directory!"))); QMessageBox::warning(this, tr("LameXP"), QString("%1<br><nobr>%2</nobr><br><br>%3").arg(tr("Cannot write to the selected output directory."), m_settings->outputDir(), tr("Please choose a different directory!")));
tabWidget->setCurrentIndex(1); tabWidget->setCurrentIndex(1);

View File

@ -260,6 +260,19 @@ QVariant CueSheetModel::data(const QModelIndex &index, int role) const
} }
} }
} }
else if(role == Qt::ToolTipRole)
{
CueSheetItem *item = reinterpret_cast<CueSheetItem*>(index.internalPointer());
if(CueSheetFile *filePtr = dynamic_cast<CueSheetFile*>(item))
{
return QDir::toNativeSeparators(filePtr->fileName());
}
else if(CueSheetTrack *trackPtr = dynamic_cast<CueSheetTrack*>(item))
{
return QDir::toNativeSeparators(trackPtr->parent()->fileName());
}
}
else if(role == Qt::FontRole) else if(role == Qt::FontRole)
{ {
QFont font("Monospace"); QFont font("Monospace");
@ -278,7 +291,7 @@ QVariant CueSheetModel::data(const QModelIndex &index, int role) const
CueSheetItem *item = reinterpret_cast<CueSheetItem*>(index.internalPointer()); CueSheetItem *item = reinterpret_cast<CueSheetItem*>(index.internalPointer());
if(CueSheetFile *filePtr = dynamic_cast<CueSheetFile*>(item)) if(CueSheetFile *filePtr = dynamic_cast<CueSheetFile*>(item))
{ {
return QFileInfo(filePtr->fileName()).exists() ? QColor("mediumblue") : QColor("darkred"); return (QFileInfo(filePtr->fileName()).size() > 4) ? QColor("mediumblue") : QColor("darkred");
} }
} }
else if((index.column() == 3)) else if((index.column() == 3))
@ -304,6 +317,52 @@ void CueSheetModel::clearData(void)
endResetModel(); endResetModel();
} }
////////////////////////////////////////////////////////////
// External API
////////////////////////////////////////////////////////////
int CueSheetModel::getFileCount(void)
{
return m_files.count();
}
QString CueSheetModel::getFileName(int fileIndex)
{
if(fileIndex < 0 || fileIndex >= m_files.count())
{
return QString();
}
return m_files.at(fileIndex)->fileName();
}
int CueSheetModel::getTrackCount(int fileIndex)
{
if(fileIndex < 0 || fileIndex >= m_files.count())
{
return -1;
}
return m_files.at(fileIndex)->trackCount();
}
void CueSheetModel::getTrackIndex(int fileIndex, int trackIndex, double *startIndex, double *duration)
{
*startIndex = std::numeric_limits<double>::quiet_NaN();
*duration = std::numeric_limits<double>::quiet_NaN();
if(fileIndex >= 0 && fileIndex < m_files.count())
{
CueSheetFile *currentFile = m_files.at(fileIndex);
if(trackIndex >= 0 && trackIndex < currentFile->trackCount())
{
CueSheetTrack *currentTrack = currentFile->track(trackIndex);
*startIndex = currentTrack->startIndex();
*duration = currentTrack->duration();
}
}
}
//////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////
// Cue Sheet Parser // Cue Sheet Parser
//////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////
@ -359,12 +418,12 @@ int CueSheetModel::parseCueFile(QFile &cueFile, const QDir &baseDir, QCoreApplic
QString albumPerformer; QString albumPerformer;
//Loop over the Cue Sheet until all lines were processed //Loop over the Cue Sheet until all lines were processed
while(true) for(int lines = 0; lines < INT_MAX; lines++)
{ {
if(application) if(application)
{ {
application->processEvents(); application->processEvents();
Sleep(10); if(lines < 128) Sleep(10);
} }
QByteArray lineData = cueFile.readLine(); QByteArray lineData = cueFile.readLine();
@ -379,7 +438,7 @@ int CueSheetModel::parseCueFile(QFile &cueFile, const QDir &baseDir, QCoreApplic
/* --- FILE --- */ /* --- FILE --- */
if(rxFile.indexIn(line) >= 0) if(rxFile.indexIn(line) >= 0)
{ {
qDebug("File: <%s> <%s>", rxFile.cap(1).toUtf8().constData(), rxFile.cap(2).toUtf8().constData()); qDebug("%03d File: <%s> <%s>", lines, rxFile.cap(1).toUtf8().constData(), rxFile.cap(2).toUtf8().constData());
if(currentFile) if(currentFile)
{ {
if(currentTrack) if(currentTrack)
@ -413,12 +472,12 @@ int CueSheetModel::parseCueFile(QFile &cueFile, const QDir &baseDir, QCoreApplic
if(!rxFile.cap(2).compare("WAVE", Qt::CaseInsensitive) || !rxFile.cap(2).compare("MP3", Qt::CaseInsensitive) || !rxFile.cap(2).compare("AIFF", Qt::CaseInsensitive)) if(!rxFile.cap(2).compare("WAVE", Qt::CaseInsensitive) || !rxFile.cap(2).compare("MP3", Qt::CaseInsensitive) || !rxFile.cap(2).compare("AIFF", Qt::CaseInsensitive))
{ {
currentFile = new CueSheetFile(baseDir.absoluteFilePath(rxFile.cap(1))); currentFile = new CueSheetFile(baseDir.absoluteFilePath(rxFile.cap(1)));
qDebug("File path: <%s>", currentFile->fileName().toUtf8().constData()); qDebug("%03d File path: <%s>", lines, currentFile->fileName().toUtf8().constData());
} }
else else
{ {
bUnsupportedTrack = true; bUnsupportedTrack = true;
qWarning("Skipping unsupported file of type '%s'.", rxFile.cap(2).toUtf8().constData()); qWarning("%03d Skipping unsupported file of type '%s'.", lines, rxFile.cap(2).toUtf8().constData());
currentFile = NULL; currentFile = NULL;
} }
bPreamble = false; bPreamble = false;
@ -431,7 +490,7 @@ int CueSheetModel::parseCueFile(QFile &cueFile, const QDir &baseDir, QCoreApplic
{ {
if(currentFile) if(currentFile)
{ {
qDebug(" Track: <%s> <%s>", rxTrack.cap(1).toUtf8().constData(), rxTrack.cap(2).toUtf8().constData()); qDebug("%03d Track: <%s> <%s>", lines, rxTrack.cap(1).toUtf8().constData(), rxTrack.cap(2).toUtf8().constData());
if(currentTrack) if(currentTrack)
{ {
if(currentTrack->isValid()) if(currentTrack->isValid())
@ -453,7 +512,7 @@ int CueSheetModel::parseCueFile(QFile &cueFile, const QDir &baseDir, QCoreApplic
else else
{ {
bUnsupportedTrack = true; bUnsupportedTrack = true;
qWarning(" Skipping unsupported track of type '%s'.", rxTrack.cap(2).toUtf8().constData()); qWarning("%03d Skipping unsupported track of type '%s'.", lines, rxTrack.cap(2).toUtf8().constData());
currentTrack = NULL; currentTrack = NULL;
} }
} }
@ -470,7 +529,7 @@ int CueSheetModel::parseCueFile(QFile &cueFile, const QDir &baseDir, QCoreApplic
{ {
if(currentFile && currentTrack) if(currentFile && currentTrack)
{ {
qDebug(" Index: <%s> <%s>", rxIndex.cap(1).toUtf8().constData(), rxIndex.cap(2).toUtf8().constData()); qDebug("%03d Index: <%s> <%s>", lines, rxIndex.cap(1).toUtf8().constData(), rxIndex.cap(2).toUtf8().constData());
if(rxIndex.cap(1).toInt() == 1) if(rxIndex.cap(1).toInt() == 1)
{ {
currentTrack->setStartIndex(parseTimeIndex(rxIndex.cap(2))); currentTrack->setStartIndex(parseTimeIndex(rxIndex.cap(2)));
@ -488,7 +547,7 @@ int CueSheetModel::parseCueFile(QFile &cueFile, const QDir &baseDir, QCoreApplic
} }
else if(currentFile && currentTrack) else if(currentFile && currentTrack)
{ {
qDebug(" Title: <%s>", rxTitle.cap(1).toUtf8().constData()); qDebug("%03d Title: <%s>", lines, rxTitle.cap(1).toUtf8().constData());
currentTrack->setTitle(rxTitle.cap(1)); currentTrack->setTitle(rxTitle.cap(1));
} }
continue; continue;
@ -503,7 +562,7 @@ int CueSheetModel::parseCueFile(QFile &cueFile, const QDir &baseDir, QCoreApplic
} }
else if(currentFile && currentTrack) else if(currentFile && currentTrack)
{ {
qDebug(" Title: <%s>", rxPerformer.cap(1).toUtf8().constData()); qDebug("%03d Title: <%s>", lines, rxPerformer.cap(1).toUtf8().constData());
currentTrack->setPerformer(rxPerformer.cap(1)); currentTrack->setPerformer(rxPerformer.cap(1));
} }
continue; continue;

View File

@ -57,6 +57,12 @@ public:
QModelIndex parent(const QModelIndex &child) const; QModelIndex parent(const QModelIndex &child) const;
void clearData(void); void clearData(void);
//External API
int CueSheetModel::getFileCount(void);
QString getFileName(int fileIndex);
int getTrackCount(int fileIndex);
void getTrackIndex(int fileIndex, int trackIndex, double *startIndex, double *duration);
//Cue Sheet functions //Cue Sheet functions
int loadCueSheet(const QString &cueFile, QCoreApplication *application = NULL); int loadCueSheet(const QString &cueFile, QCoreApplication *application = NULL);