Example #1
0
bool ALACDecoder::decode(const QString &sourceFile, const QString &outputFile, volatile bool *abortFlag)
{
    QProcess process;
    QStringList args;

    args << "--decode";
    args << "-o" << QDir::toNativeSeparators(outputFile);
    args << QDir::toNativeSeparators(sourceFile);

    if(!startProcess(process, m_binary, args))
    {
        return false;
    }

    bool bTimeout = false;
    bool bAborted = false;
    int prevProgress = -1;

    //The ALAC Decoder doesn't actually send any status updates :-[
    //emit statusUpdated(20 + (QUuid::createUuid().data1 % 60));
    QRegExp regExp("\\[(\\d+)\\.(\\d)%\\]");

    while(process.state() != QProcess::NotRunning)
    {
        if(*abortFlag)
        {
            process.kill();
            bAborted = true;
            emit messageLogged("\nABORTED BY USER !!!");
            break;
        }
        process.waitForReadyRead(m_processTimeoutInterval);
        if(!process.bytesAvailable() && process.state() == QProcess::Running)
        {
            process.kill();
            qWarning("ALAC process timed out <-- killing!");
            emit messageLogged("\nPROCESS TIMEOUT !!!");
            bTimeout = true;
            break;
        }
        while(process.bytesAvailable() > 0)
        {
            QByteArray line = process.readLine();
            QString text = QString::fromUtf8(line.constData()).simplified();
            if(regExp.lastIndexIn(text) >= 0)
            {
                bool ok[2] = {false, false};
                int intVal[2] = {0, 0};
                intVal[0] = regExp.cap(1).toInt(&ok[0]);
                intVal[1] = regExp.cap(2).toInt(&ok[1]);
                if(ok[0] && ok[1])
                {
                    int progress = qRound(static_cast<double>(intVal[0]) + (static_cast<double>(intVal[1]) / 10.0));
                    if(progress > prevProgress)
                    {
                        emit statusUpdated(progress);
                        prevProgress = qMin(progress + 2, 99);
                    }
                }
            }
            else if(!text.isEmpty())
            {
                emit messageLogged(text);
            }
        }
    }

    process.waitForFinished();
    if(process.state() != QProcess::NotRunning)
    {
        process.kill();
        process.waitForFinished(-1);
    }

    emit statusUpdated(100);
    emit messageLogged(QString().sprintf("\nExited with code: 0x%04X", process.exitCode()));

    if(bTimeout || bAborted || process.exitCode() != EXIT_SUCCESS || QFileInfo(outputFile).size() == 0)
    {
        return false;
    }

    return true;
}
Example #2
0
bool AACEncoder::encode(const QString &sourceFile, const AudioFileModel &metaInfo, const QString &outputFile, volatile bool *abortFlag)
{
	const unsigned int fileDuration = metaInfo.fileDuration();
	
	QProcess process;
	QStringList args;
	const QString baseName = QFileInfo(outputFile).fileName();

	switch(m_configRCMode)
	{
	case SettingsModel::VBRMode:
		args << "-q" << QString().sprintf("%.2f", qBound(0.0, static_cast<double>(m_configBitrate) / 20.0, 1.0));
		break;
	case SettingsModel::ABRMode:
		args << "-br" << QString::number(qMax(32, qMin(500, (m_configBitrate * 8))) * 1000);
		break;
	case SettingsModel::CBRMode:
		args << "-cbr" << QString::number(qMax(32, qMin(500, (m_configBitrate * 8))) * 1000);
		break;
	default:
		throw "Bad rate-control mode!";
		break;
	}

	if(m_configEnable2Pass && (m_configRCMode == SettingsModel::ABRMode))
	{
		args << "-2pass";
	}
	
	switch(m_configProfile)
	{
	case 1:
		args << "-lc"; //Forces use of LC AAC profile
		break;
	case 2:
		args << "-he"; //Forces use of HE AAC profile
		break;
	case 3:
		args << "-hev2"; //Forces use of HEv2 AAC profile
		break;
	}

	if(!m_configCustomParams.isEmpty()) args << m_configCustomParams.split(" ", QString::SkipEmptyParts);

	args << "-if" << QDir::toNativeSeparators(sourceFile);
	args << "-of" << QDir::toNativeSeparators(outputFile);

	if(!startProcess(process, m_binary_enc, args))
	{
		return false;
	}

	bool bTimeout = false;
	bool bAborted = false;
	int prevProgress = -1;


	QRegExp regExp("Processed\\s+(\\d+)\\s+seconds");
	QRegExp regExp_pass1("First\\s+pass:\\s+processed\\s+(\\d+)\\s+seconds");
	QRegExp regExp_pass2("Second\\s+pass:\\s+processed\\s+(\\d+)\\s+seconds");

	while(process.state() != QProcess::NotRunning)
	{
		if(*abortFlag)
		{
			process.kill();
			bAborted = true;
			emit messageLogged("\nABORTED BY USER !!!");
			break;
		}
		process.waitForReadyRead(m_processTimeoutInterval);
		if(!process.bytesAvailable() && process.state() == QProcess::Running)
		{
			process.kill();
			qWarning("NeroAacEnc process timed out <-- killing!");
			emit messageLogged("\nPROCESS TIMEOUT !!!");
			bTimeout = true;
			break;
		}
		while(process.bytesAvailable() > 0)
		{
			QByteArray line = process.readLine();
			QString text = QString::fromUtf8(line.constData()).simplified();
			if(regExp_pass1.lastIndexIn(text) >= 0)
			{
				bool ok = false;
				int progress = regExp_pass1.cap(1).toInt(&ok);
				if(ok && (fileDuration > 0))
				{
					int newProgress = qRound((static_cast<double>(progress) / static_cast<double>(fileDuration)) * 50.0);
					if(newProgress > prevProgress)
					{
						emit statusUpdated(newProgress);
						prevProgress = qMin(newProgress + 2, 99);
					}
				}
			}
			else if(regExp_pass2.lastIndexIn(text) >= 0)
			{
				bool ok = false;
				int progress = regExp_pass2.cap(1).toInt(&ok);
				if(ok && (fileDuration > 0))
				{
					int newProgress = qRound((static_cast<double>(progress) / static_cast<double>(fileDuration)) * 50.0) + 50;
					if(newProgress > prevProgress)
					{
						emit statusUpdated(newProgress);
						prevProgress = qMin(newProgress + 2, 99);
					}
				}
			}
			else if(regExp.lastIndexIn(text) >= 0)
			{
				bool ok = false;
				int progress = regExp.cap(1).toInt(&ok);
				if(ok && (fileDuration > 0))
				{
					int newProgress = qRound((static_cast<double>(progress) / static_cast<double>(fileDuration)) * 100.0);
					if(newProgress > prevProgress)
					{
						emit statusUpdated(newProgress);
						prevProgress = qMin(newProgress + 2, 99);
					}
				}
			}
			else if(!text.isEmpty())
			{
				emit messageLogged(text);
			}
		}
	}

	process.waitForFinished();
	if(process.state() != QProcess::NotRunning)
	{
		process.kill();
		process.waitForFinished(-1);
	}
	
	emit statusUpdated(100);
	emit messageLogged(QString().sprintf("\nExited with code: 0x%04X", process.exitCode()));

	if(bTimeout || bAborted || process.exitCode() != EXIT_SUCCESS)
	{
		return false;
	}

	emit messageLogged("\n-------------------------------\n");
	
	args.clear();
	args << QDir::toNativeSeparators(outputFile);

	if(!metaInfo.fileName().isEmpty()) args << QString("-meta:title=%1").arg(cleanTag(metaInfo.fileName()));
	if(!metaInfo.fileArtist().isEmpty()) args << QString("-meta:artist=%1").arg(cleanTag(metaInfo.fileArtist()));
	if(!metaInfo.fileAlbum().isEmpty()) args << QString("-meta:album=%1").arg(cleanTag(metaInfo.fileAlbum()));
	if(!metaInfo.fileGenre().isEmpty()) args << QString("-meta:genre=%1").arg(cleanTag(metaInfo.fileGenre()));
	if(!metaInfo.fileComment().isEmpty()) args << QString("-meta:comment=%1").arg(cleanTag(metaInfo.fileComment()));
	if(metaInfo.fileYear()) args << QString("-meta:year=%1").arg(QString::number(metaInfo.fileYear()));
	if(metaInfo.filePosition()) args << QString("-meta:track=%1").arg(QString::number(metaInfo.filePosition()));
	if(!metaInfo.fileCover().isEmpty()) args << QString("-add-cover:%1:%2").arg("front", metaInfo.fileCover());
	
	if(!startProcess(process, m_binary_tag, args))
	{
		return false;
	}

	bTimeout = false;

	while(process.state() != QProcess::NotRunning)
	{
		if(*abortFlag)
		{
			process.kill();
			bAborted = true;
			emit messageLogged("\nABORTED BY USER !!!");
			break;
		}
		process.waitForReadyRead(m_processTimeoutInterval);
		if(!process.bytesAvailable() && process.state() == QProcess::Running)
		{
			process.kill();
			qWarning("NeroAacTag process timed out <-- killing!");
			emit messageLogged("\nPROCESS TIMEOUT !!!");
			bTimeout = true;
			break;
		}
		while(process.bytesAvailable() > 0)
		{
			QByteArray line = process.readLine();
			QString text = QString::fromUtf8(line.constData()).simplified();
			if(!text.isEmpty())
			{
				emit messageLogged(text);
			}
		}
	}

	process.waitForFinished();
	if(process.state() != QProcess::NotRunning)
	{
		process.kill();
		process.waitForFinished(-1);
	}
		
	emit messageLogged(QString().sprintf("\nExited with code: 0x%04X", process.exitCode()));

	if(bTimeout || bAborted || process.exitCode() != EXIT_SUCCESS)
	{
		return false;
	}

	return true;
}
Example #3
0
bool ADPCMDecoder::decode(const QString &sourceFile, const QString &outputFile, volatile bool *abortFlag)
{
	QProcess process;
	QStringList args;

	process.setWorkingDirectory(QFileInfo(outputFile).canonicalPath());

	args << "-V3" << "-S" << "--temp" << ".";
	args << QDir::toNativeSeparators(sourceFile);
	args << "-e" << "signed-integer";
	args << QDir::toNativeSeparators(outputFile);

	if(!startProcess(process, m_binary, args))
	{
		return false;
	}

	bool bTimeout = false;
	bool bAborted = false;

	QRegExp regExp("In:(\\d+)(\\.\\d+)*%");

	while(process.state() != QProcess::NotRunning)
	{
		if(*abortFlag)
		{
			process.kill();
			bAborted = true;
			emit messageLogged("\nABORTED BY USER !!!");
			break;
		}
		process.waitForReadyRead(m_processTimeoutInterval);
		if(!process.bytesAvailable() && process.state() == QProcess::Running)
		{
			process.kill();
			qWarning("Sox process timed out <-- killing!");
			emit messageLogged("\nPROCESS TIMEOUT !!!");
			bTimeout = true;
			break;
		}
		while(process.bytesAvailable() > 0)
		{
			QByteArray line = process.readLine();
			QString text = QString::fromUtf8(line.constData()).simplified();
			if(regExp.lastIndexIn(text) >= 0)
			{
				bool ok = false;
				int progress = regExp.cap(1).toInt(&ok);
				if(ok) emit statusUpdated(progress);
			}
			else if(!text.isEmpty())
			{
				emit messageLogged(text);
			}
		}
	}

	process.waitForFinished();
	if(process.state() != QProcess::NotRunning)
	{
		process.kill();
		process.waitForFinished(-1);
	}
	
	emit statusUpdated(100);
	emit messageLogged(QString().sprintf("\nExited with code: 0x%04X", process.exitCode()));

	if(bTimeout || bAborted || process.exitCode() != EXIT_SUCCESS || QFileInfo(outputFile).size() == 0)
	{
		return false;
	}
	
	return true;
}
bool QAACEncoder::encode(const QString &sourceFile, const AudioFileModel_MetaInfo &metaInfo, const unsigned int duration, const QString &outputFile, volatile bool *abortFlag)
{
    QProcess process;
    QStringList args;

    process.setWorkingDirectory(QFileInfo(outputFile).canonicalPath());

    QProcessEnvironment env = QProcessEnvironment::systemEnvironment();
    env.insert("PATH", QDir::toNativeSeparators(QString("%1;%1/QTfiles;%2").arg(QDir(QCoreApplication::applicationDirPath()).canonicalPath(), lamexp_temp_folder2())));
    process.setProcessEnvironment(env);

    if(m_configRCMode != SettingsModel::VBRMode)
    {
        switch(m_configProfile)
        {
        case 2:
        case 3:
            args << "--he"; //Forces use of HE AAC profile (there is no explicit HEv2 switch for QAAC)
            break;
        }
    }

    switch(m_configRCMode)
    {
    case SettingsModel::CBRMode:
        args << "--cbr" << QString::number(qBound(8, index2bitrate(m_configBitrate), 576));
        break;
    case SettingsModel::ABRMode:
        args << "--abr" << QString::number(qBound(8, index2bitrate(m_configBitrate), 576));
        break;
    case SettingsModel::VBRMode:
        args << "--tvbr" << QString::number(g_qaacVBRQualityLUT[qBound(0, m_configBitrate , 14)]);
        break;
    default:
        THROW("Bad rate-control mode!");
        break;
    }

    if(!m_configCustomParams.isEmpty()) args << m_configCustomParams.split(" ", QString::SkipEmptyParts);

    if(!metaInfo.title().isEmpty()) args << "--title" << cleanTag(metaInfo.title());
    if(!metaInfo.artist().isEmpty()) args << "--artist" << cleanTag(metaInfo.artist());
    if(!metaInfo.album().isEmpty()) args << "--album" << cleanTag(metaInfo.album());
    if(!metaInfo.genre().isEmpty()) args << "--genre" << cleanTag(metaInfo.genre());
    if(!metaInfo.comment().isEmpty()) args << "--comment" << cleanTag( metaInfo.comment());
    if(metaInfo.year()) args << "--date" << QString::number(metaInfo.year());
    if(metaInfo.position()) args << "--track" << QString::number(metaInfo.position());
    if(!metaInfo.cover().isEmpty()) args << "--artwork" << metaInfo.cover();

    args << "-d" << ".";
    args << "-o" << QDir::toNativeSeparators(outputFile);
    args << QDir::toNativeSeparators(sourceFile);

    if(!startProcess(process, m_binary_qaac, args))
    {
        return false;
    }

    bool bTimeout = false;
    bool bAborted = false;
    int prevProgress = -1;

    QRegExp regExp("\\[(\\d+)\\.(\\d)%\\]");

    while(process.state() != QProcess::NotRunning)
    {
        if(*abortFlag)
        {
            process.kill();
            bAborted = true;
            emit messageLogged("\nABORTED BY USER !!!");
            break;
        }
        process.waitForReadyRead(m_processTimeoutInterval);
        if(!process.bytesAvailable() && process.state() == QProcess::Running)
        {
            process.kill();
            qWarning("QAAC process timed out <-- killing!");
            emit messageLogged("\nPROCESS TIMEOUT !!!");
            bTimeout = true;
            break;
        }
        while(process.bytesAvailable() > 0)
        {
            QByteArray line = process.readLine();
            QString text = QString::fromUtf8(line.constData()).simplified();
            if(regExp.lastIndexIn(text) >= 0)
            {
                bool ok = false;
                int progress = regExp.cap(1).toInt(&ok);
                if(ok && (progress > prevProgress))
                {
                    emit statusUpdated(progress);
                    prevProgress = qMin(progress + 2, 99);
                }
            }
            else if(!text.isEmpty())
            {
                emit messageLogged(text);
            }
        }
    }

    process.waitForFinished();
    if(process.state() != QProcess::NotRunning)
    {
        process.kill();
        process.waitForFinished(-1);
    }

    emit statusUpdated(100);
    emit messageLogged(QString().sprintf("\nExited with code: 0x%04X", process.exitCode()));

    if(bTimeout || bAborted || process.exitCode() != EXIT_SUCCESS)
    {
        return false;
    }

    return true;
}
bool OpusEncoder::encode(const QString &sourceFile, const AudioFileModel_MetaInfo &metaInfo, const unsigned int duration, const QString &outputFile, volatile bool *abortFlag)
{
	QProcess process;
	QStringList args;

	switch(m_configRCMode)
	{
	case SettingsModel::VBRMode:
		args << "--vbr";
		break;
	case SettingsModel::ABRMode:
		args << "--cvbr";
		break;
	case SettingsModel::CBRMode:
		args << "--hard-cbr";
		break;
	default:
		THROW("Bad rate-control mode!");
		break;
	}

	args << "--comp" << QString::number(m_configEncodeComplexity);

	switch(m_configFrameSize)
	{
	case 0:
		args << "--framesize" << "2.5";
		break;
	case 1:
		args << "--framesize" << "5";
		break;
	case 2:
		args << "--framesize" << "10";
		break;
	case 3:
		args << "--framesize" << "20";
		break;
	case 4:
		args << "--framesize" << "40";
		break;
	case 5:
		args << "--framesize" << "60";
		break;
	}

	args << QString("--bitrate") << QString::number(qBound(8, (m_configBitrate + 1) * 8, 256));

	if(!metaInfo.title().isEmpty()) args << "--title" << cleanTag(metaInfo.title());
	if(!metaInfo.artist().isEmpty()) args << "--artist" << cleanTag(metaInfo.artist());
	if(!metaInfo.album().isEmpty()) args << "--album" << cleanTag(metaInfo.album());
	if(!metaInfo.genre().isEmpty()) args << "--genre" << cleanTag(metaInfo.genre());
	if(metaInfo.year()) args << "--date" << QString::number(metaInfo.year());
	if(metaInfo.position()) args << "--comment" << QString("tracknumber=%1").arg(QString::number(metaInfo.position()));
	if(!metaInfo.comment().isEmpty()) args << "--comment" << QString("comment=%1").arg(cleanTag(metaInfo.comment()));
	
	if(!m_configCustomParams.isEmpty()) args << m_configCustomParams.split(" ", QString::SkipEmptyParts);

	args << QDir::toNativeSeparators(sourceFile);
	args << QDir::toNativeSeparators(outputFile);

	if(!startProcess(process, m_binary, args))
	{
		return false;
	}

	bool bTimeout = false;
	bool bAborted = false;
	int prevProgress = -1;

	QRegExp regExp("\\((\\d+)%\\)");

	while(process.state() != QProcess::NotRunning)
	{
		if(*abortFlag)
		{
			process.kill();
			bAborted = true;
			emit messageLogged("\nABORTED BY USER !!!");
			break;
		}
		process.waitForReadyRead(m_processTimeoutInterval);
		if(!process.bytesAvailable() && process.state() == QProcess::Running)
		{
			process.kill();
			qWarning("Opus process timed out <-- killing!");
			emit messageLogged("\nPROCESS TIMEOUT !!!");
			bTimeout = true;
			break;
		}
		while(process.bytesAvailable() > 0)
		{
			QByteArray line = process.readLine();
			QString text = QString::fromUtf8(line.constData()).simplified();
			if(regExp.lastIndexIn(text) >= 0)
			{
				bool ok = false;
				int progress = regExp.cap(1).toInt(&ok);
				if(ok && (progress > prevProgress))
				{
					emit statusUpdated(progress);
					prevProgress = qMin(progress + 2, 99);
				}
			}
			else if(!text.isEmpty())
			{
				emit messageLogged(text);
			}
		}
	}

	process.waitForFinished();
	if(process.state() != QProcess::NotRunning)
	{
		process.kill();
		process.waitForFinished(-1);
	}
	
	emit statusUpdated(100);
	emit messageLogged(QString().sprintf("\nExited with code: 0x%04X", process.exitCode()));

	if(bTimeout || bAborted || process.exitCode() != EXIT_SUCCESS)
	{
		return false;
	}
	
	return true;
}
Example #6
0
bool MP3Decoder::decode(const QString &sourceFile, const QString &outputFile, volatile bool *abortFlag)
{
    QProcess process;
    QStringList args;

    args << "-v" << "--utf8" << "-w" << QDir::toNativeSeparators(outputFile);
    args << QDir::toNativeSeparators(sourceFile);

    if(!startProcess(process, m_binary, args))
    {
        return false;
    }

    bool bTimeout = false;
    bool bAborted = false;
    int prevProgress = -1;

    QRegExp regExp("\\b\\d+\\+\\d+\\s+(\\d+):(\\d+)\\.(\\d+)\\+(\\d+):(\\d+)\\.(\\d+)\\b");

    while(process.state() != QProcess::NotRunning)
    {
        if(*abortFlag)
        {
            process.kill();
            bAborted = true;
            emit messageLogged("\nABORTED BY USER !!!");
            break;
        }
        process.waitForReadyRead(m_processTimeoutInterval);
        if(!process.bytesAvailable() && process.state() == QProcess::Running)
        {
            process.kill();
            qWarning("mpg123 process timed out <-- killing!");
            emit messageLogged("\nPROCESS TIMEOUT !!!");
            bTimeout = true;
            break;
        }
        while(process.bytesAvailable() > 0)
        {
            QByteArray line = process.readLine();
            QString text = QString::fromUtf8(line.constData()).simplified();
            if(regExp.lastIndexIn(text) >= 0)
            {
                quint32 values[6];
                if (MUtils::regexp_parse_uint32(regExp, values, 6))
                {
                    const double timeDone = (60.0 * double(values[0])) + double(values[1]) + (double(values[2]) / 100.0);
                    const double timeLeft = (60.0 * double(values[3])) + double(values[4]) + (double(values[5]) / 100.0);
                    if ((timeDone >= 0.005) || (timeLeft >= 0.005))
                    {
                        const int newProgress = qRound((static_cast<double>(timeDone) / static_cast<double>(timeDone + timeLeft)) * 100.0);
                        if (newProgress > prevProgress)
                        {
                            emit statusUpdated(newProgress);
                            prevProgress = qMin(newProgress + 2, 99);
                        }
                    }
                }
            }
            else if(!text.isEmpty())
            {
                emit messageLogged(text);
            }
        }
    }

    process.waitForFinished();
    if(process.state() != QProcess::NotRunning)
    {
        process.kill();
        process.waitForFinished(-1);
    }

    emit statusUpdated(100);
    emit messageLogged(QString().sprintf("\nExited with code: 0x%04X", process.exitCode()));

    if(bTimeout || bAborted || process.exitCode() != EXIT_SUCCESS)
    {
        return false;
    }

    return true;
}
Example #7
0
bool OpusDecoder::decode(const QString &sourceFile, const QString &outputFile, volatile bool *abortFlag)
{
	QProcess process;
	QStringList args;

	if(m_disableResampling)
	{
		args << "--no-resample";
	}

	args << QDir::toNativeSeparators(sourceFile);
	args << QDir::toNativeSeparators(outputFile);

	if(!startProcess(process, m_binary, args))
	{
		return false;
	}

	bool bTimeout = false;
	bool bAborted = false;
	int prevProgress = -1;

	QRegExp regExp("\\((\\d+)%\\)");

	while(process.state() != QProcess::NotRunning)
	{
		if(*abortFlag)
		{
			process.kill();
			bAborted = true;
			emit messageLogged("\nABORTED BY USER !!!");
			break;
		}
		process.waitForReadyRead(m_processTimeoutInterval);
		if(!process.bytesAvailable() && process.state() == QProcess::Running)
		{
			process.kill();
			qWarning("opusdec process timed out <-- killing!");
			emit messageLogged("\nPROCESS TIMEOUT !!!");
			bTimeout = true;
			break;
		}
		while(process.bytesAvailable() > 0)
		{
			QByteArray line = process.readLine();
			QString text = QString::fromUtf8(line.constData()).simplified();
			if(regExp.lastIndexIn(text) >= 0)
			{
				bool ok = false;
				int progress = regExp.cap(1).toInt(&ok);
				if(ok && (progress > prevProgress))
				{
					emit statusUpdated(progress);
					prevProgress = qMin(progress + 2, 99);
				}
			}
			else if(!text.isEmpty())
			{
				emit messageLogged(text);
			}
		}
	}

	process.waitForFinished();
	if(process.state() != QProcess::NotRunning)
	{
		process.kill();
		process.waitForFinished(-1);
	}
	
	emit statusUpdated(100);
	emit messageLogged(QString().sprintf("\nExited with code: 0x%04X", process.exitCode()));

	if(bTimeout || bAborted || process.exitCode() != EXIT_SUCCESS)
	{
		return false;
	}
	
	return true;
}
Example #8
0
bool AC3Encoder::encode(const QString &sourceFile, const AudioFileModel &metaInfo, const QString &outputFile, volatile bool *abortFlag)
{
	QProcess process;
	QStringList args;

	switch(m_configRCMode)
	{
	case SettingsModel::VBRMode:
		args << "-q" << QString::number(qMax(0, qMin(1023, m_configBitrate * 64)));
		break;
	case SettingsModel::CBRMode:
		args << "-b" << QString::number(SettingsModel::ac3Bitrates[qMax(0, qMin(18, m_configBitrate))]);
		break;
	default:
		throw "Bad rate-control mode!";
		break;
	}

	if(m_configAudioCodingMode >= 1)
	{
		args << "-acmod" << QString::number(m_configAudioCodingMode - 1);
	}
	if(m_configDynamicRangeCompression != 5)
	{
		args << "-dynrng" << QString::number(m_configDynamicRangeCompression);
	}
	if(m_configExponentSearchSize != 8)
	{
		args << "-exps" << QString::number(m_configExponentSearchSize);
	}
	if(m_configFastBitAllocation)
	{
		args << "-fba" << QString::number(1);
	}

	if(!m_configCustomParams.isEmpty()) args << m_configCustomParams.split(" ", QString::SkipEmptyParts);

	args << QDir::toNativeSeparators(sourceFile);
	args << QDir::toNativeSeparators(outputFile);

	if(!startProcess(process, m_binary, args))
	{
		return false;
	}

	bool bTimeout = false;
	bool bAborted = false;
	int prevProgress = -1;

	QRegExp regExp("progress:(\\s+)(\\d+)%(\\s+)\\|");

	while(process.state() != QProcess::NotRunning)
	{
		if(*abortFlag)
		{
			process.kill();
			bAborted = true;
			emit messageLogged("\nABORTED BY USER !!!");
			break;
		}
		process.waitForReadyRead(m_processTimeoutInterval);
		if(!process.bytesAvailable() && process.state() == QProcess::Running)
		{
			process.kill();
			qWarning("Aften process timed out <-- killing!");
			emit messageLogged("\nPROCESS TIMEOUT !!!");
			bTimeout = true;
			break;
		}
		while(process.bytesAvailable() > 0)
		{
			QByteArray line = process.readLine();
			QString text = QString::fromUtf8(line.constData()).simplified();
			if(regExp.lastIndexIn(text) >= 0)
			{
				bool ok = false;
				int progress = regExp.cap(2).toInt(&ok);
				if(ok && (progress > prevProgress))
				{
					emit statusUpdated(progress);
					prevProgress = qMin(progress + 2, 99);
				}
			}
			else if(!text.isEmpty())
			{
				emit messageLogged(text);
			}
		}
	}

	process.waitForFinished();
	if(process.state() != QProcess::NotRunning)
	{
		process.kill();
		process.waitForFinished(-1);
	}
	
	emit statusUpdated(100);
	emit messageLogged(QString().sprintf("\nExited with code: 0x%04X", process.exitCode()));

	if(bTimeout || bAborted || process.exitStatus() != QProcess::NormalExit)
	{
		return false;
	}
	
	return true;
}
Example #9
0
AbstractFilter::FilterResult DownmixFilter::apply(const QString &sourceFile, const QString &outputFile, AudioFileModel_TechInfo *const formatInfo, volatile bool *abortFlag)
{
	unsigned int channels = formatInfo->audioChannels();
	emit messageLogged(QString().sprintf("--> Number of channels is: %d\n", channels));

	if(IS_VALID(channels) && (channels <= 2))
	{
		messageLogged("Skipping downmix!");
		qDebug("Dowmmix not required/possible for Mono or Stereo input, skipping!");
		return AbstractFilter::FILTER_SKIPPED;
	}

	QProcess process;
	QStringList args;

	args << "-V3" << "-S";
	args << "--guard" << "--temp" << ".";
	args << QDir::toNativeSeparators(sourceFile);
	args << QDir::toNativeSeparators(outputFile);

	switch(channels)
	{
	case 3: //3.0 (L/R/C)
		args << "remix" << "1v0.66,3v0.34" << "2v0.66,3v0.34";
		break;
	case 4: //3.1 (L/R/C/LFE)
		args << "remix" << "1v0.5,3v0.25,4v0.25" << "2v0.5,3v0.25,4v0.25";
		break;
	case 5: //5.0 (L/R/C/BL/BR)
		args << "remix" << "1v0.5,3v0.25,4v0.25" << "2v0.5,3v0.25,5v0.25";
		break;
	case 6: //5.1 (L/R/C/LFE/BL/BR)
		args << "remix" << "1v0.4,3v0.2,4v0.2,5v0.2" << "2v0.4,3v0.2,4v0.2,6v0.2";
		break;
	case 7: //7.0 (L/R/C/BL/BR/SL/SR)
		args << "remix" << "1v0.4,3v0.2,4v0.2,6v0.2" << "2v0.4,3v0.2,5v0.2,7v0.2";
		break;
	case 8: //7.1 (L/R/C/LFE/BL/BR/SL/SR)
		args << "remix" << "1v0.36,3v0.16,4v0.16,5v0.16,7v0.16" << "2v0.36,3v0.16,4v0.16,6v0.16,8v0.16";
		break;
	case 9: //8.1 (L/R/C/LFE/BL/BR/SL/SR/BC)
		args << "remix" << "1v0.308,3v0.154,4v0.154,5v0.154,7v0.154,9v0.076" << "2v0.308,3v0.154,4v0.154,6v0.154,8v0.154,9v0.076";
		break;
	default: //Unknown
		qWarning("Downmixer: Unknown channel configuration!");
		args << "channels" << QString::number(2);
		break;
	}

	if(!startProcess(process, m_binary, args, QFileInfo(outputFile).canonicalPath()))
	{
		return AbstractFilter::FILTER_FAILURE;
	}

	bool bTimeout = false;
	bool bAborted = false;

	QRegExp regExp("In:(\\d+)(\\.\\d+)*%");

	while(process.state() != QProcess::NotRunning)
	{
		if(*abortFlag)
		{
			process.kill();
			bAborted = true;
			emit messageLogged("\nABORTED BY USER !!!");
			break;
		}
		process.waitForReadyRead(m_processTimeoutInterval);
		if(!process.bytesAvailable() && process.state() == QProcess::Running)
		{
			process.kill();
			qWarning("SoX process timed out <-- killing!");
			emit messageLogged("\nPROCESS TIMEOUT !!!");
			bTimeout = true;
			break;
		}
		while(process.bytesAvailable() > 0)
		{
			QByteArray line = process.readLine();
			QString text = QString::fromUtf8(line.constData()).simplified();
			if(regExp.lastIndexIn(text) >= 0)
			{
				bool ok = false;
				int progress = regExp.cap(1).toInt(&ok);
				if(ok) emit statusUpdated(progress);
			}
			else if(!text.isEmpty())
			{
				emit messageLogged(text);
			}
		}
	}

	process.waitForFinished();
	if(process.state() != QProcess::NotRunning)
	{
		process.kill();
		process.waitForFinished(-1);
	}
	
	emit statusUpdated(100);
	emit messageLogged(QString().sprintf("\nExited with code: 0x%04X", process.exitCode()));

	if(bTimeout || bAborted || process.exitCode() != EXIT_SUCCESS || QFileInfo(outputFile).size() == 0)
	{
		return AbstractFilter::FILTER_FAILURE;
	}
	
	formatInfo->setAudioChannels(2);
	return AbstractFilter::FILTER_SUCCESS;
}
Example #10
0
bool VorbisEncoder::encode(const QString &sourceFile, const AudioFileModel &metaInfo, const QString &outputFile, volatile bool *abortFlag)
{
	QProcess process;
	QStringList args;
	const QString baseName = QFileInfo(outputFile).fileName();

	switch(m_configRCMode)
	{
	case SettingsModel::VBRMode:
		args << "-q" << QString::number(qMax(-2, qMin(10, m_configBitrate)));
		break;
	case SettingsModel::ABRMode:
		args << "-b" << QString::number(qMax(32, qMin(500, (m_configBitrate * 8))));
		break;
	default:
		throw "Bad rate-control mode!";
		break;
	}

	if((m_configBitrateMaximum > 0) && (m_configBitrateMinimum > 0) && (m_configBitrateMinimum <= m_configBitrateMaximum))
	{
		args << "--min-bitrate" << QString::number(qMin(qMax(m_configBitrateMinimum, 32), 500));
		args << "--max-bitrate" << QString::number(qMin(qMax(m_configBitrateMaximum, 32), 500));
	}

	if(m_configSamplingRate > 0)
	{
		args << "--resample" << QString::number(m_configSamplingRate) << "--converter" << QString::number(0);
	}

	if(!metaInfo.fileName().isEmpty()) args << "-t" << metaInfo.fileName();
	if(!metaInfo.fileArtist().isEmpty()) args << "-a" << metaInfo.fileArtist();
	if(!metaInfo.fileAlbum().isEmpty()) args << "-l" << metaInfo.fileAlbum();
	if(!metaInfo.fileGenre().isEmpty()) args << "-G" << metaInfo.fileGenre();
	if(!metaInfo.fileComment().isEmpty()) args << "-c" << QString("comment=%1").arg(metaInfo.fileComment());
	if(metaInfo.fileYear()) args << "-d" << QString::number(metaInfo.fileYear());
	if(metaInfo.filePosition()) args << "-N" << QString::number(metaInfo.filePosition());
	
	//args << "--tv" << QString().sprintf("Encoder=LameXP v%d.%02d.%04d [%s]", lamexp_version_major(), lamexp_version_minor(), lamexp_version_build(), lamexp_version_release());

	if(!m_configCustomParams.isEmpty()) args << m_configCustomParams.split(" ", QString::SkipEmptyParts);

	args << "-o" << QDir::toNativeSeparators(outputFile);
	args << QDir::toNativeSeparators(sourceFile);

	if(!startProcess(process, m_binary, args))
	{
		return false;
	}

	bool bTimeout = false;
	bool bAborted = false;
	int prevProgress = -1;

	QRegExp regExp("\\[.*(\\d+)[.,](\\d+)%\\]");

	while(process.state() != QProcess::NotRunning)
	{
		if(*abortFlag)
		{
			process.kill();
			bAborted = true;
			emit messageLogged("\nABORTED BY USER !!!");
			break;
		}
		process.waitForReadyRead(m_processTimeoutInterval);
		if(!process.bytesAvailable() && process.state() == QProcess::Running)
		{
			process.kill();
			qWarning("OggEnc process timed out <-- killing!");
			emit messageLogged("\nPROCESS TIMEOUT !!!");
			bTimeout = true;
			break;
		}
		while(process.bytesAvailable() > 0)
		{
			QByteArray line = process.readLine();
			QString text = QString::fromUtf8(line.constData()).simplified();
			if(regExp.lastIndexIn(text) >= 0)
			{
				bool ok = false;
				int progress = regExp.cap(1).toInt(&ok);
				if(ok && (progress > prevProgress))
				{
					emit statusUpdated(progress);
					prevProgress = qMin(progress + 2, 99);
				}
			}
			else if(!text.isEmpty())
			{
				emit messageLogged(text);
			}
		}
	}

	process.waitForFinished();
	if(process.state() != QProcess::NotRunning)
	{
		process.kill();
		process.waitForFinished(-1);
	}
	
	emit statusUpdated(100);
	emit messageLogged(QString().sprintf("\nExited with code: 0x%04X", process.exitCode()));

	if(bTimeout || bAborted || process.exitStatus() != QProcess::NormalExit)
	{
		return false;
	}
	
	return true;
}
Example #11
0
bool SpeexDecoder::decode(const QString &sourceFile, const QString &outputFile, volatile bool *abortFlag)
{
	QProcess process;
	QStringList args;

	args << "-V";
	args << QDir::toNativeSeparators(sourceFile);
	args << QDir::toNativeSeparators(outputFile);

	if(!startProcess(process, m_binary, args))
	{
		return false;
	}

	bool bTimeout = false;
	bool bAborted = false;

	QRegExp regExp("Working\\.\\.\\. (.)");

	while(process.state() != QProcess::NotRunning)
	{
		if(*abortFlag)
		{
			process.kill();
			bAborted = true;
			emit messageLogged("\nABORTED BY USER !!!");
			break;
		}
		process.waitForReadyRead(m_processTimeoutInterval);
		if(!process.bytesAvailable() && process.state() == QProcess::Running)
		{
			process.kill();
			qWarning("SpeexDec process timed out <-- killing!");
			emit messageLogged("\nPROCESS TIMEOUT !!!");
			bTimeout = true;
			break;
		}
		while(process.bytesAvailable() > 0)
		{
			QByteArray line = process.readLine();
			QString text = QString::fromUtf8(line.constData()).simplified();
			if(regExp.lastIndexIn(text) >= 0)
			{
				/* qDebug("Status: %s", regExp.cap(1).toLatin1().constData()); */
			}
			else if(!text.isEmpty())
			{
				emit messageLogged(text);
			}
		}
	}

	process.waitForFinished();
	if(process.state() != QProcess::NotRunning)
	{
		process.kill();
		process.waitForFinished(-1);
	}
	
	emit statusUpdated(100);
	emit messageLogged(QString().sprintf("\nExited with code: 0x%04X", process.exitCode()));

	if(bTimeout || bAborted || process.exitCode() != EXIT_SUCCESS || QFileInfo(outputFile).size() == 0)
	{
		return false;
	}
	
	return true;
}
Example #12
0
bool ShortenDecoder::decode(const QString &sourceFile, const QString &outputFile, volatile bool *abortFlag)
{
	QProcess process;
	QStringList args;

	args << "-x";
	args << QDir::toNativeSeparators(sourceFile);
	args << QDir::toNativeSeparators(outputFile);

	if(!startProcess(process, m_binary, args))
	{
		return false;
	}

	bool bTimeout = false;
	bool bAborted = false;

	//The Shorten Decoder doesn't actually send any status updates :-[
	emit statusUpdated(20 + (QUuid::createUuid().data1 % 80));

	while(process.state() != QProcess::NotRunning)
	{
		if(*abortFlag)
		{
			process.kill();
			bAborted = true;
			emit messageLogged("\nABORTED BY USER !!!");
			break;
		}
		process.waitForReadyRead(m_processTimeoutInterval);
		if(!process.bytesAvailable() && process.state() == QProcess::Running)
		{
			process.kill();
			qWarning("Shorten process timed out <-- killing!");
			emit messageLogged("\nPROCESS TIMEOUT !!!");
			bTimeout = true;
			break;
		}
		while(process.bytesAvailable() > 0)
		{
			QByteArray line = process.readLine();
			QString text = QString::fromUtf8(line.constData()).simplified();
			if(!text.isEmpty())
			{
				emit messageLogged(text);
			}
		}
	}

	process.waitForFinished();
	if(process.state() != QProcess::NotRunning)
	{
		process.kill();
		process.waitForFinished(-1);
	}
	
	emit statusUpdated(100);
	emit messageLogged(QString().sprintf("\nExited with code: 0x%04X", process.exitCode()));

	if(bTimeout || bAborted || process.exitStatus() != QProcess::NormalExit || QFileInfo(outputFile).size() == 0)
	{
		return false;
	}
	
	return true;
}
Example #13
0
bool FHGAACEncoder::encode(const QString &sourceFile, const AudioFileModel_MetaInfo &metaInfo, const unsigned int duration, const unsigned int channels, const QString &outputFile, volatile bool *abortFlag)
{
	QProcess process;
	QStringList args;
	
	int maxBitrate = 576;

	if(m_configRCMode == SettingsModel::CBRMode)
	{
		switch(m_configProfile)
		{
		case 1:
			args << L1S("--profile") << L1S("lc"); //Forces use of LC AAC profile
			break;
		case 2:
			maxBitrate = 128;
			args << L1S("--profile") << L1S("he"); //Forces use of HE AAC profile
			break;
		case 3:
			maxBitrate = 56;
			args << L1S("--profile") << L1S("hev2"); //Forces use of HEv2 AAC profile
			break;
		}
	}

	switch(m_configRCMode)
	{
	case SettingsModel::CBRMode:
		args << L1S("--cbr") << QString::number(qBound(8, index2bitrate(m_configBitrate), maxBitrate));
		break;
	case SettingsModel::VBRMode:
		args << L1S("--vbr") << QString::number(qBound(1, m_configBitrate + 1, 6));
		break;
	default:
		MUTILS_THROW("Bad rate-control mode!");
		break;
	}

	//args << "--dll" << m_binary_dll;

	if(!m_configCustomParams.isEmpty()) args << m_configCustomParams.split(" ", QString::SkipEmptyParts);

	args << QDir::toNativeSeparators(sourceFile);
	args << QDir::toNativeSeparators(outputFile);

	if(!startProcess(process, m_binary_enc, args))
	{
		return false;
	}

	bool bTimeout = false;
	bool bAborted = false;
	int prevProgress = -1;

	QRegExp regExp(L1S("Progress:\\s*(\\d+)%"));

	while(process.state() != QProcess::NotRunning)
	{
		if(*abortFlag)
		{
			process.kill();
			bAborted = true;
			emit messageLogged(L1S("\nABORTED BY USER !!!"));
			break;
		}
		process.waitForReadyRead(m_processTimeoutInterval);
		if(!process.bytesAvailable() && process.state() == QProcess::Running)
		{
			process.kill();
			qWarning("FhgAacEnc process timed out <-- killing!");
			emit messageLogged(L1S("\nPROCESS TIMEOUT !!!"));
			bTimeout = true;
			break;
		}
		while(process.bytesAvailable() > 0)
		{
			QByteArray line = process.readLine();
			QString text = QString::fromUtf8(line.constData()).simplified();
			if(regExp.lastIndexIn(text) >= 0)
			{
				bool ok = false;
				int progress = regExp.cap(1).toInt(&ok);
				if(ok && (progress > prevProgress))
				{
					emit statusUpdated(progress);
					prevProgress = qMin(progress + 2, 99);
				}
			}
			else if(!text.isEmpty())
			{
				emit messageLogged(text);
			}
		}
	}

	process.waitForFinished();
	if(process.state() != QProcess::NotRunning)
	{
		process.kill();
		process.waitForFinished(-1);
	}
	
	emit statusUpdated(100);
	emit messageLogged(QString().sprintf("\nExited with code: 0x%04X", process.exitCode()));

	if(bTimeout || bAborted || process.exitCode() != EXIT_SUCCESS)
	{
		return false;
	}

	return true;
}