2011-05-15 01:45:27 +02:00
|
|
|
///////////////////////////////////////////////////////////////////////////////
|
|
|
|
// LameXP - Audio Encoder Front-End
|
2012-01-02 00:52:27 +01:00
|
|
|
// Copyright (C) 2004-2012 LoRd_MuldeR <MuldeR2@GMX.de>
|
2011-05-15 01:45:27 +02: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_CueSplitter.h"
|
|
|
|
|
|
|
|
#include "Global.h"
|
|
|
|
#include "LockedFile.h"
|
|
|
|
#include "Model_AudioFile.h"
|
2011-05-16 18:05:50 +02:00
|
|
|
#include "Model_CueSheet.h"
|
2011-05-15 18:53:44 +02:00
|
|
|
#include "Registry_Decoder.h"
|
|
|
|
#include "Decoder_Abstract.h"
|
2011-05-15 01:45:27 +02:00
|
|
|
|
|
|
|
#include <QDir>
|
|
|
|
#include <QFileInfo>
|
|
|
|
#include <QProcess>
|
|
|
|
#include <QDate>
|
|
|
|
#include <QTime>
|
|
|
|
#include <QDebug>
|
|
|
|
|
|
|
|
#include <math.h>
|
2011-06-21 22:07:22 +02:00
|
|
|
#include <float.h>
|
|
|
|
#include <limits>
|
2011-05-15 01:45:27 +02:00
|
|
|
|
|
|
|
////////////////////////////////////////////////////////////
|
|
|
|
// Constructor
|
|
|
|
////////////////////////////////////////////////////////////
|
|
|
|
|
2011-05-16 18:05:50 +02:00
|
|
|
CueSplitter::CueSplitter(const QString &outputDir, const QString &baseName, CueSheetModel *model, const QList<AudioFileModel> &inputFilesInfo)
|
2011-05-15 01:45:27 +02:00
|
|
|
:
|
2011-05-16 18:05:50 +02:00
|
|
|
m_model(model),
|
2011-05-15 01:45:27 +02:00
|
|
|
m_outputDir(outputDir),
|
|
|
|
m_baseName(baseName),
|
|
|
|
m_soxBin(lamexp_lookup_tool("sox.exe"))
|
|
|
|
{
|
|
|
|
if(m_soxBin.isEmpty())
|
|
|
|
{
|
|
|
|
qFatal("Invalid path to SoX binary. Tool not initialized properly.");
|
|
|
|
}
|
|
|
|
|
2011-05-15 18:53:44 +02:00
|
|
|
m_decompressedFiles.clear();
|
|
|
|
m_tempFiles.clear();
|
2011-05-15 15:14:33 +02:00
|
|
|
|
2011-05-18 00:36:51 +02:00
|
|
|
qDebug("\n[CueSplitter]");
|
2011-05-15 01:45:27 +02:00
|
|
|
|
2011-05-16 18:05:50 +02:00
|
|
|
int nInputFiles = inputFilesInfo.count();
|
2011-05-15 01:45:27 +02:00
|
|
|
for(int i = 0; i < nInputFiles; i++)
|
|
|
|
{
|
2011-05-16 18:05:50 +02:00
|
|
|
m_inputFilesInfo.insert(inputFilesInfo[i].filePath(), inputFilesInfo[i]);
|
2011-05-18 00:36:51 +02:00
|
|
|
qDebug("File %02d: <%s>", i, inputFilesInfo[i].filePath().toUtf8().constData());
|
2011-05-15 01:45:27 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
qDebug("All input files added.");
|
|
|
|
m_bSuccess = false;
|
|
|
|
}
|
|
|
|
|
2011-05-15 18:53:44 +02:00
|
|
|
CueSplitter::~CueSplitter(void)
|
|
|
|
{
|
|
|
|
while(!m_tempFiles.isEmpty())
|
|
|
|
{
|
|
|
|
lamexp_remove_file(m_tempFiles.takeFirst());
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2011-05-15 01:45:27 +02:00
|
|
|
////////////////////////////////////////////////////////////
|
|
|
|
// Thread Main
|
|
|
|
////////////////////////////////////////////////////////////
|
|
|
|
|
|
|
|
void CueSplitter::run()
|
|
|
|
{
|
|
|
|
m_bSuccess = false;
|
2011-05-16 18:05:50 +02:00
|
|
|
m_bAborted = false;
|
2011-05-15 18:53:44 +02:00
|
|
|
m_abortFlag = false;
|
2011-05-15 15:14:33 +02:00
|
|
|
m_nTracksSuccess = 0;
|
|
|
|
m_nTracksSkipped = 0;
|
2011-05-15 18:53:44 +02:00
|
|
|
m_decompressedFiles.clear();
|
|
|
|
m_activeFile.clear();
|
2011-05-15 01:45:27 +02:00
|
|
|
|
|
|
|
if(!QDir(m_outputDir).exists())
|
|
|
|
{
|
|
|
|
qWarning("Output directory \"%s\" does not exist!", m_outputDir.toUtf8().constData());
|
|
|
|
return;
|
|
|
|
}
|
2011-05-15 18:53:44 +02:00
|
|
|
|
2011-05-16 18:05:50 +02:00
|
|
|
QStringList inputFileList = m_inputFilesInfo.keys();
|
2011-05-15 18:53:44 +02:00
|
|
|
int nInputFiles = inputFileList.count();
|
|
|
|
|
2012-05-06 23:58:18 +02:00
|
|
|
emit progressMaxChanged(nInputFiles);
|
|
|
|
emit progressValChanged(0);
|
|
|
|
|
2011-05-15 18:53:44 +02:00
|
|
|
//Decompress all input files
|
|
|
|
for(int i = 0; i < nInputFiles; i++)
|
|
|
|
{
|
2011-05-16 18:05:50 +02:00
|
|
|
AudioFileModel &inputFileInfo = m_inputFilesInfo[inputFileList.at(i)];
|
2011-05-15 18:53:44 +02:00
|
|
|
if(inputFileInfo.formatContainerType().compare("Wave", Qt::CaseInsensitive) || inputFileInfo.formatAudioType().compare("PCM", Qt::CaseInsensitive))
|
|
|
|
{
|
|
|
|
AbstractDecoder *decoder = DecoderRegistry::lookup(inputFileInfo.formatContainerType(), inputFileInfo.formatContainerProfile(), inputFileInfo.formatAudioType(), inputFileInfo.formatAudioProfile(), inputFileInfo.formatAudioVersion());
|
|
|
|
if(decoder)
|
|
|
|
{
|
2011-05-29 16:57:38 +02:00
|
|
|
m_activeFile = shortName(QFileInfo(inputFileList.at(i)).fileName());
|
2012-05-06 23:58:18 +02:00
|
|
|
|
2011-05-15 18:53:44 +02:00
|
|
|
emit fileSelected(m_activeFile);
|
2012-05-06 23:58:18 +02:00
|
|
|
emit progressValChanged(i+1);
|
|
|
|
|
2011-05-15 18:53:44 +02:00
|
|
|
QString tempFile = QString("%1/~%2.wav").arg(m_outputDir, lamexp_rand_str());
|
|
|
|
connect(decoder, SIGNAL(statusUpdated(int)), this, SLOT(handleUpdate(int)), Qt::DirectConnection);
|
2012-05-06 23:58:18 +02:00
|
|
|
|
2011-05-15 18:53:44 +02:00
|
|
|
if(decoder->decode(inputFileList.at(i), tempFile, &m_abortFlag))
|
|
|
|
{
|
|
|
|
m_decompressedFiles.insert(inputFileList.at(i), tempFile);
|
|
|
|
m_tempFiles.append(tempFile);
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
qWarning("Failed to decompress file: <%s>", inputFileList.at(i).toLatin1().constData());
|
|
|
|
lamexp_remove_file(tempFile);
|
|
|
|
}
|
2012-05-06 23:58:18 +02:00
|
|
|
|
2011-05-15 18:53:44 +02:00
|
|
|
m_activeFile.clear();
|
|
|
|
LAMEXP_DELETE(decoder);
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
qWarning("Unsupported input file: <%s>", inputFileList.at(i).toLatin1().constData());
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
m_decompressedFiles.insert(inputFileList.at(i), inputFileList.at(i));
|
|
|
|
}
|
2012-05-06 23:58:18 +02:00
|
|
|
|
2011-05-16 18:05:50 +02:00
|
|
|
if(m_abortFlag)
|
|
|
|
{
|
|
|
|
m_bAborted = true;
|
|
|
|
qWarning("The user has requested to abort the process!");
|
|
|
|
return;
|
|
|
|
}
|
2011-05-15 18:53:44 +02:00
|
|
|
}
|
2011-05-15 01:45:27 +02:00
|
|
|
|
2011-05-16 18:05:50 +02:00
|
|
|
int nFiles = m_model->getFileCount();
|
2012-05-08 01:12:26 +02:00
|
|
|
int nTracksTotal = 0, nTracksComplete = 0;
|
2012-05-06 23:58:18 +02:00
|
|
|
|
|
|
|
for(int i = 0; i < nFiles; i++)
|
|
|
|
{
|
|
|
|
nTracksTotal += m_model->getTrackCount(i);
|
|
|
|
}
|
|
|
|
|
|
|
|
emit progressMaxChanged(nTracksTotal);
|
|
|
|
emit progressValChanged(0);
|
|
|
|
|
2011-05-16 18:05:50 +02:00
|
|
|
QString albumPerformer = m_model->getAlbumPerformer();
|
|
|
|
QString albumTitle = m_model->getAlbumTitle();
|
2011-09-23 21:30:55 +02:00
|
|
|
QString albumGenre = m_model->getAlbumGenre();
|
|
|
|
unsigned int albumYear = m_model->getAlbumYear();
|
2011-05-15 18:53:44 +02:00
|
|
|
|
2011-05-29 16:57:38 +02:00
|
|
|
//Now split all files
|
2011-05-16 18:05:50 +02:00
|
|
|
for(int i = 0; i < nFiles; i++)
|
2011-05-15 01:45:27 +02:00
|
|
|
{
|
2011-05-16 18:05:50 +02:00
|
|
|
int nTracks = m_model->getTrackCount(i);
|
|
|
|
QString trackFile = m_model->getFileName(i);
|
|
|
|
int maxProgress = 0;
|
|
|
|
|
2011-05-29 16:57:38 +02:00
|
|
|
//Process all tracks
|
2011-05-16 18:05:50 +02:00
|
|
|
for(int j = 0; j < nTracks; j++)
|
2011-05-15 01:45:27 +02:00
|
|
|
{
|
2012-05-06 23:58:18 +02:00
|
|
|
emit progressValChanged(++nTracksComplete);
|
2011-05-16 18:05:50 +02:00
|
|
|
int trackNo = m_model->getTrackNo(i, j);
|
|
|
|
double trackOffset = std::numeric_limits<double>::quiet_NaN();
|
|
|
|
double trackLength = std::numeric_limits<double>::quiet_NaN();
|
|
|
|
m_model->getTrackIndex(i, j, &trackOffset, &trackLength);
|
|
|
|
|
|
|
|
if((trackNo < 0) || _isnan(trackOffset) || _isnan(trackLength))
|
|
|
|
{
|
|
|
|
qWarning("Failed to fetch information for track #%d of file #%d!", j, i);
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
|
2011-05-29 16:57:38 +02:00
|
|
|
//Setup meta info
|
2011-05-16 18:05:50 +02:00
|
|
|
AudioFileModel trackMetaInfo(QString().sprintf("cue://File%02d/Track%02d", i, j));
|
|
|
|
trackMetaInfo.setFileName(m_model->getTrackTitle(i, j));
|
|
|
|
trackMetaInfo.setFileArtist(m_model->getTrackPerformer(i, j));
|
2011-09-23 21:30:55 +02:00
|
|
|
trackMetaInfo.setFileGenre(m_model->getTrackGenre(i, j));
|
|
|
|
trackMetaInfo.setFileYear(m_model->getTrackYear(i, j));
|
2011-05-16 18:05:50 +02:00
|
|
|
trackMetaInfo.setFilePosition(trackNo);
|
2011-09-24 00:15:50 +02:00
|
|
|
|
2011-09-23 21:30:55 +02:00
|
|
|
//Apply album meta data on files
|
2011-09-24 00:15:50 +02:00
|
|
|
if(trackMetaInfo.fileName().trimmed().isEmpty())
|
|
|
|
{
|
|
|
|
trackMetaInfo.setFileName(QString().sprintf("Track %02d", trackNo));
|
|
|
|
}
|
2011-05-16 18:05:50 +02:00
|
|
|
if(!albumTitle.isEmpty())
|
|
|
|
{
|
|
|
|
trackMetaInfo.setFileAlbum(albumTitle);
|
|
|
|
}
|
|
|
|
if(!albumPerformer.isEmpty() && trackMetaInfo.fileArtist().isEmpty())
|
|
|
|
{
|
|
|
|
trackMetaInfo.setFileArtist(albumPerformer);
|
|
|
|
}
|
2011-09-23 21:30:55 +02:00
|
|
|
if(!albumGenre.isEmpty() && trackMetaInfo.fileGenre().isEmpty())
|
|
|
|
{
|
|
|
|
trackMetaInfo.setFileGenre(albumGenre);
|
|
|
|
}
|
|
|
|
if((albumYear > 0) && (trackMetaInfo.fileYear() == 0))
|
|
|
|
{
|
|
|
|
trackMetaInfo.setFileYear(albumYear);
|
|
|
|
}
|
2011-05-16 18:05:50 +02:00
|
|
|
if(_finite(trackLength))
|
|
|
|
{
|
|
|
|
trackMetaInfo.setFileDuration(static_cast<unsigned int>(abs(trackLength)));
|
|
|
|
}
|
2011-05-15 01:45:27 +02:00
|
|
|
|
2011-05-29 16:57:38 +02:00
|
|
|
//Generate output file name
|
|
|
|
QString trackTitle = trackMetaInfo.fileName().isEmpty() ? QString().sprintf("Track %02d", trackNo) : trackMetaInfo.fileName();
|
2011-08-04 20:35:40 +02:00
|
|
|
QString outputFile = QString("%1/[%2] %3 - %4.wav").arg(m_outputDir, QString().sprintf("%02d", trackNo), lamexp_clean_filename(m_baseName), lamexp_clean_filename(trackTitle));
|
2011-05-16 18:05:50 +02:00
|
|
|
for(int n = 2; QFileInfo(outputFile).exists(); n++)
|
|
|
|
{
|
2011-08-04 20:35:40 +02:00
|
|
|
outputFile = QString("%1/[%2] %3 - %4 (%5).wav").arg(m_outputDir, QString().sprintf("%02d", trackNo), lamexp_clean_filename(m_baseName), lamexp_clean_filename(trackTitle), QString::number(n));
|
2011-05-16 18:05:50 +02:00
|
|
|
}
|
2011-05-15 01:45:27 +02:00
|
|
|
|
2011-05-29 16:57:38 +02:00
|
|
|
//Call split function
|
|
|
|
emit fileSelected(shortName(QFileInfo(outputFile).fileName()));
|
2011-05-16 18:05:50 +02:00
|
|
|
splitFile(outputFile, trackNo, trackFile, trackOffset, trackLength, trackMetaInfo, maxProgress);
|
|
|
|
|
|
|
|
if(m_abortFlag)
|
|
|
|
{
|
|
|
|
m_bAborted = true;
|
|
|
|
qWarning("The user has requested to abort the process!");
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
}
|
2011-05-15 01:45:27 +02:00
|
|
|
}
|
|
|
|
|
2011-05-16 18:05:50 +02:00
|
|
|
qDebug("All files were split.\n");
|
|
|
|
m_bSuccess = true;
|
2011-05-15 15:14:33 +02:00
|
|
|
}
|
|
|
|
|
2011-05-15 18:53:44 +02:00
|
|
|
////////////////////////////////////////////////////////////
|
|
|
|
// Slots
|
|
|
|
////////////////////////////////////////////////////////////
|
|
|
|
|
|
|
|
void CueSplitter::handleUpdate(int progress)
|
|
|
|
{
|
|
|
|
emit fileSelected(QString("%1 [%2%]").arg(m_activeFile, QString::number(progress)));
|
|
|
|
}
|
|
|
|
|
2011-05-15 01:45:27 +02:00
|
|
|
////////////////////////////////////////////////////////////
|
|
|
|
// Privtae Functions
|
|
|
|
////////////////////////////////////////////////////////////
|
|
|
|
|
2011-05-16 18:05:50 +02:00
|
|
|
void CueSplitter::splitFile(const QString &output, const int trackNo, const QString &file, const double offset, const double length, const AudioFileModel &metaInfo, int &maxProgress)
|
2011-05-15 01:45:27 +02:00
|
|
|
{
|
2011-05-15 18:53:44 +02:00
|
|
|
qDebug("[Track %02d]", trackNo);
|
2011-05-15 01:45:27 +02:00
|
|
|
qDebug("File: <%s>", file.toUtf8().constData());
|
2011-05-17 20:06:01 +02:00
|
|
|
qDebug("Offset: <%f> <%s>", offset, indexToString(offset).toLatin1().constData());
|
|
|
|
qDebug("Length: <%f> <%s>", length, indexToString(length).toLatin1().constData());
|
2011-05-15 01:45:27 +02:00
|
|
|
qDebug("Artist: <%s>", metaInfo.fileArtist().toUtf8().constData());
|
|
|
|
qDebug("Title: <%s>", metaInfo.fileName().toUtf8().constData());
|
2011-05-15 18:53:44 +02:00
|
|
|
|
|
|
|
if(!m_decompressedFiles.contains(file))
|
2011-05-15 01:45:27 +02:00
|
|
|
{
|
2011-05-15 18:53:44 +02:00
|
|
|
qWarning("Unknown or unsupported input file, skipping!");
|
2011-05-15 15:14:33 +02:00
|
|
|
m_nTracksSkipped++;
|
2011-05-15 01:45:27 +02:00
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2011-05-29 16:57:38 +02:00
|
|
|
QString baseName = shortName(QFileInfo(output).fileName());
|
2011-05-15 18:53:44 +02:00
|
|
|
QString decompressedInput = m_decompressedFiles[file];
|
|
|
|
qDebug("Input: <%s>", decompressedInput.toUtf8().constData());
|
|
|
|
|
2011-05-16 18:05:50 +02:00
|
|
|
emit fileSelected(QString("%1 [%2%]").arg(baseName, QString::number(maxProgress)));
|
|
|
|
|
2011-05-15 15:14:33 +02:00
|
|
|
AudioFileModel outFileInfo(metaInfo);
|
|
|
|
outFileInfo.setFilePath(output);
|
2011-05-15 18:53:44 +02:00
|
|
|
outFileInfo.setFormatContainerType("Wave");
|
|
|
|
outFileInfo.setFormatAudioType("PCM");
|
2011-05-15 15:14:33 +02:00
|
|
|
|
2011-05-15 01:45:27 +02:00
|
|
|
QStringList args;
|
|
|
|
args << "-S" << "-V3";
|
|
|
|
args << "--guard" << "--temp" << ".";
|
2011-05-15 18:53:44 +02:00
|
|
|
args << QDir::toNativeSeparators(decompressedInput);
|
2011-05-15 01:45:27 +02:00
|
|
|
args << QDir::toNativeSeparators(output);
|
|
|
|
|
2011-05-15 18:53:44 +02:00
|
|
|
//Add trim parameters, if needed
|
2011-05-17 20:06:01 +02:00
|
|
|
if(_finite(offset))
|
2011-05-15 01:45:27 +02:00
|
|
|
{
|
2011-05-15 15:14:33 +02:00
|
|
|
args << "trim";
|
|
|
|
args << indexToString(offset);
|
2011-05-17 20:06:01 +02:00
|
|
|
|
2011-05-16 18:05:50 +02:00
|
|
|
if(_finite(length))
|
2011-05-15 15:14:33 +02:00
|
|
|
{
|
|
|
|
args << indexToString(length);
|
|
|
|
}
|
2011-05-15 01:45:27 +02:00
|
|
|
}
|
|
|
|
|
2011-05-15 15:14:33 +02:00
|
|
|
QRegExp rxProgress("In:(\\d+)(\\.\\d+)*%", Qt::CaseInsensitive);
|
|
|
|
QRegExp rxChannels("Channels\\s*:\\s*(\\d+)", Qt::CaseInsensitive);
|
|
|
|
QRegExp rxSamplerate("Sample Rate\\s*:\\s*(\\d+)", Qt::CaseInsensitive);
|
|
|
|
QRegExp rxPrecision("Precision\\s*:\\s*(\\d+)-bit", Qt::CaseInsensitive);
|
|
|
|
QRegExp rxDuration("Duration\\s*:\\s*(\\d\\d):(\\d\\d):(\\d\\d).(\\d\\d)", Qt::CaseInsensitive);
|
|
|
|
|
2011-05-15 01:45:27 +02:00
|
|
|
QProcess process;
|
|
|
|
process.setProcessChannelMode(QProcess::MergedChannels);
|
|
|
|
process.setReadChannel(QProcess::StandardOutput);
|
|
|
|
process.setWorkingDirectory(m_outputDir);
|
|
|
|
process.start(m_soxBin, args);
|
|
|
|
|
|
|
|
if(!process.waitForStarted())
|
|
|
|
{
|
|
|
|
qWarning("SoX process failed to create!");
|
|
|
|
qWarning("Error message: \"%s\"\n", process.errorString().toLatin1().constData());
|
|
|
|
process.kill();
|
|
|
|
process.waitForFinished(-1);
|
2011-05-15 15:14:33 +02:00
|
|
|
m_nTracksSkipped++;
|
2011-05-15 01:45:27 +02:00
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
while(process.state() != QProcess::NotRunning)
|
|
|
|
{
|
|
|
|
if(m_abortFlag)
|
|
|
|
{
|
|
|
|
process.kill();
|
2011-05-16 18:05:50 +02:00
|
|
|
qWarning("Process was aborted on user request!");
|
2011-05-15 01:45:27 +02:00
|
|
|
break;
|
|
|
|
}
|
2011-06-14 13:06:27 +02:00
|
|
|
process.waitForReadyRead(m_processTimeoutInterval);
|
2011-05-15 01:45:27 +02:00
|
|
|
if(!process.bytesAvailable() && process.state() == QProcess::Running)
|
|
|
|
{
|
|
|
|
process.kill();
|
|
|
|
qWarning("SoX process timed out <-- killing!");
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
while(process.bytesAvailable() > 0)
|
|
|
|
{
|
|
|
|
QByteArray line = process.readLine();
|
|
|
|
QString text = QString::fromUtf8(line.constData()).simplified();
|
2011-05-15 15:14:33 +02:00
|
|
|
if(rxProgress.lastIndexIn(text) >= 0)
|
2011-05-15 01:45:27 +02:00
|
|
|
{
|
|
|
|
bool ok = false;
|
2011-05-15 15:14:33 +02:00
|
|
|
int progress = rxProgress.cap(1).toInt(&ok);
|
2011-05-15 01:45:27 +02:00
|
|
|
if(ok)
|
|
|
|
{
|
2011-11-08 15:12:31 +01:00
|
|
|
maxProgress = qMax(maxProgress, progress);
|
2011-05-16 18:05:50 +02:00
|
|
|
emit fileSelected(QString("%1 [%2%]").arg(baseName, QString::number(maxProgress)));
|
2011-05-15 01:45:27 +02:00
|
|
|
}
|
|
|
|
}
|
2011-05-15 15:14:33 +02:00
|
|
|
else if(rxChannels.lastIndexIn(text) >= 0)
|
|
|
|
{
|
|
|
|
bool ok = false;
|
|
|
|
unsigned int channels = rxChannels.cap(1).toUInt(&ok);
|
|
|
|
if(ok) outFileInfo.setFormatAudioChannels(channels);
|
|
|
|
}
|
|
|
|
else if(rxSamplerate.lastIndexIn(text) >= 0)
|
|
|
|
{
|
|
|
|
bool ok = false;
|
|
|
|
unsigned int samplerate = rxSamplerate.cap(1).toUInt(&ok);
|
|
|
|
if(ok) outFileInfo.setFormatAudioSamplerate(samplerate);
|
|
|
|
}
|
|
|
|
else if(rxPrecision.lastIndexIn(text) >= 0)
|
|
|
|
{
|
|
|
|
bool ok = false;
|
|
|
|
unsigned int precision = rxPrecision.cap(1).toUInt(&ok);
|
|
|
|
if(ok) outFileInfo.setFormatAudioBitdepth(precision);
|
|
|
|
}
|
|
|
|
else if(rxDuration.lastIndexIn(text) >= 0)
|
|
|
|
{
|
|
|
|
bool ok1 = false, ok2 = false, ok3 = false;
|
|
|
|
unsigned int hh = rxDuration.cap(1).toUInt(&ok1);
|
|
|
|
unsigned int mm = rxDuration.cap(2).toUInt(&ok2);
|
|
|
|
unsigned int ss = rxDuration.cap(3).toUInt(&ok3);
|
|
|
|
if(ok1 && ok2 && ok3)
|
|
|
|
{
|
|
|
|
unsigned intputLen = (hh * 3600) + (mm * 60) + ss;
|
|
|
|
if(length == std::numeric_limits<double>::infinity())
|
|
|
|
{
|
|
|
|
qDebug("Duration updated from SoX info!");
|
2011-05-15 18:53:44 +02:00
|
|
|
int duration = intputLen - static_cast<int>(floor(offset + 0.5));
|
|
|
|
if(duration < 0) qWarning("Track is out of bounds: Track offset exceeds input file duration!");
|
2011-11-08 15:12:31 +01:00
|
|
|
outFileInfo.setFileDuration(qMax(0, duration));
|
2011-05-15 15:14:33 +02:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
unsigned int trackEnd = static_cast<unsigned int>(floor(offset + 0.5)) + static_cast<unsigned int>(floor(length + 0.5));
|
|
|
|
if(trackEnd > intputLen) qWarning("Track is out of bounds: End of track exceeds input file duration!");
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2011-05-15 01:45:27 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2011-05-15 15:14:33 +02:00
|
|
|
process.waitForFinished();
|
2011-05-15 01:45:27 +02:00
|
|
|
if(process.state() != QProcess::NotRunning)
|
|
|
|
{
|
|
|
|
process.kill();
|
|
|
|
process.waitForFinished(-1);
|
|
|
|
}
|
|
|
|
|
2011-12-22 00:06:34 +01:00
|
|
|
if(process.exitCode() != EXIT_SUCCESS || QFileInfo(output).size() == 0)
|
2011-05-15 01:45:27 +02:00
|
|
|
{
|
2011-05-15 15:14:33 +02:00
|
|
|
qWarning("Splitting has failed !!!");
|
|
|
|
m_nTracksSkipped++;
|
2011-05-15 01:45:27 +02:00
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
emit fileSplit(outFileInfo);
|
2011-05-15 15:14:33 +02:00
|
|
|
m_nTracksSuccess++;
|
2011-05-15 01:45:27 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
QString CueSplitter::indexToString(const double index) const
|
|
|
|
{
|
2011-05-18 00:36:51 +02:00
|
|
|
if(!_finite(index) || (index < 0.0) || (index > 86400.0))
|
2011-05-15 01:45:27 +02:00
|
|
|
{
|
|
|
|
return QString();
|
|
|
|
}
|
2011-05-17 20:06:01 +02:00
|
|
|
|
2011-05-18 00:36:51 +02:00
|
|
|
QTime time = QTime().addMSecs(static_cast<int>(floor(0.5 + (index * 1000.0))));
|
|
|
|
return time.toString(time.hour() ? "H:mm:ss.zzz" : "m:ss.zzz");
|
2011-05-15 01:45:27 +02:00
|
|
|
}
|
|
|
|
|
2011-05-29 16:57:38 +02:00
|
|
|
QString CueSplitter::shortName(const QString &longName) const
|
|
|
|
{
|
|
|
|
static const int maxLen = 54;
|
|
|
|
|
|
|
|
if(longName.length() > maxLen)
|
|
|
|
{
|
|
|
|
return QString("%1...%2").arg(longName.left(maxLen/2).trimmed(), longName.right(maxLen/2).trimmed());
|
|
|
|
}
|
|
|
|
|
|
|
|
return longName;
|
|
|
|
}
|
|
|
|
|
2011-05-15 01:45:27 +02:00
|
|
|
////////////////////////////////////////////////////////////
|
|
|
|
// EVENTS
|
|
|
|
////////////////////////////////////////////////////////////
|
|
|
|
|
|
|
|
/*NONE*/
|