Fixed AC-3 encoding with sources that have more than 6 channels.
This commit is contained in:
parent
c772b9bc2d
commit
3f4be5c846
@ -30,7 +30,7 @@
|
|||||||
#define VER_LAMEXP_MINOR_LO 4
|
#define VER_LAMEXP_MINOR_LO 4
|
||||||
#define VER_LAMEXP_TYPE Alpha
|
#define VER_LAMEXP_TYPE Alpha
|
||||||
#define VER_LAMEXP_PATCH 13
|
#define VER_LAMEXP_PATCH 13
|
||||||
#define VER_LAMEXP_BUILD 862
|
#define VER_LAMEXP_BUILD 865
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////////////////////////////
|
||||||
// Tool versions (minimum expected versions!)
|
// Tool versions (minimum expected versions!)
|
||||||
|
@ -179,6 +179,12 @@ QString AC3Encoder::extension(void)
|
|||||||
return "ac3";
|
return "ac3";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const unsigned int *AC3Encoder::supportedChannelCount(void)
|
||||||
|
{
|
||||||
|
static const unsigned int supportedChannels[] = {1, 2, 3, 4, 5, 6, NULL};
|
||||||
|
return supportedChannels;
|
||||||
|
}
|
||||||
|
|
||||||
const unsigned int *AC3Encoder::supportedSamplerates(void)
|
const unsigned int *AC3Encoder::supportedSamplerates(void)
|
||||||
{
|
{
|
||||||
static const unsigned int supportedRates[] = {48000, 44100, 32000, NULL};
|
static const unsigned int supportedRates[] = {48000, 44100, 32000, NULL};
|
||||||
|
@ -36,6 +36,7 @@ public:
|
|||||||
virtual bool encode(const QString &sourceFile, const AudioFileModel &metaInfo, const QString &outputFile, volatile bool *abortFlag);
|
virtual bool encode(const QString &sourceFile, const AudioFileModel &metaInfo, const QString &outputFile, volatile bool *abortFlag);
|
||||||
virtual bool isFormatSupported(const QString &containerType, const QString &containerProfile, const QString &formatType, const QString &formatProfile, const QString &formatVersion);
|
virtual bool isFormatSupported(const QString &containerType, const QString &containerProfile, const QString &formatType, const QString &formatProfile, const QString &formatVersion);
|
||||||
virtual QString extension(void);
|
virtual QString extension(void);
|
||||||
|
virtual const unsigned int *supportedChannelCount(void);
|
||||||
virtual const unsigned int *supportedSamplerates(void);
|
virtual const unsigned int *supportedSamplerates(void);
|
||||||
|
|
||||||
//Advanced options
|
//Advanced options
|
||||||
|
@ -23,6 +23,8 @@
|
|||||||
|
|
||||||
#include "Tool_Abstract.h"
|
#include "Tool_Abstract.h"
|
||||||
|
|
||||||
|
class AudioFileModel;
|
||||||
|
|
||||||
class AbstractFilter : public AbstractTool
|
class AbstractFilter : public AbstractTool
|
||||||
{
|
{
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
@ -32,6 +34,6 @@ public:
|
|||||||
~AbstractFilter(void);
|
~AbstractFilter(void);
|
||||||
|
|
||||||
//Internal decoder API
|
//Internal decoder API
|
||||||
virtual bool apply(const QString &sourceFile, const QString &outputFile, volatile bool *abortFlag) = 0;
|
virtual bool apply(const QString &sourceFile, const QString &outputFile, AudioFileModel *formatInfo, volatile bool *abortFlag) = 0;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -22,6 +22,8 @@
|
|||||||
#include "Filter_Downmix.h"
|
#include "Filter_Downmix.h"
|
||||||
|
|
||||||
#include "Global.h"
|
#include "Global.h"
|
||||||
|
#include "Tool_WaveProperties.h"
|
||||||
|
#include "Model_AudioFile.h"
|
||||||
|
|
||||||
#include <QDir>
|
#include <QDir>
|
||||||
#include <QProcess>
|
#include <QProcess>
|
||||||
@ -41,16 +43,16 @@ DownmixFilter::~DownmixFilter(void)
|
|||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
bool DownmixFilter::apply(const QString &sourceFile, const QString &outputFile, volatile bool *abortFlag)
|
bool DownmixFilter::apply(const QString &sourceFile, const QString &outputFile, AudioFileModel *formatInfo, volatile bool *abortFlag)
|
||||||
{
|
{
|
||||||
unsigned int channels = detectChannels(sourceFile, abortFlag);
|
unsigned int channels = formatInfo->formatAudioChannels(); //detectChannels(sourceFile, abortFlag);
|
||||||
emit messageLogged(QString().sprintf("--> Number of channels is: %d\n", channels));
|
emit messageLogged(QString().sprintf("--> Number of channels is: %d\n", channels));
|
||||||
|
|
||||||
if((channels == 1) || (channels == 2))
|
if((channels == 1) || (channels == 2))
|
||||||
{
|
{
|
||||||
messageLogged("Skipping downmix!");
|
messageLogged("Skipping downmix!");
|
||||||
qDebug("Dowmmix not required for Mono or Stereo input, skipping!");
|
qDebug("Dowmmix not required for Mono or Stereo input, skipping!");
|
||||||
return false;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
QProcess process;
|
QProcess process;
|
||||||
@ -152,69 +154,6 @@ bool DownmixFilter::apply(const QString &sourceFile, const QString &outputFile,
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
formatInfo->setFormatAudioChannels(2);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
unsigned int DownmixFilter::detectChannels(const QString &sourceFile, volatile bool *abortFlag)
|
|
||||||
{
|
|
||||||
unsigned int channels = 0;
|
|
||||||
|
|
||||||
QProcess process;
|
|
||||||
QStringList args;
|
|
||||||
|
|
||||||
args << "--i" << sourceFile;
|
|
||||||
|
|
||||||
if(!startProcess(process, m_binary, args))
|
|
||||||
{
|
|
||||||
return channels;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool bTimeout = false;
|
|
||||||
bool bAborted = false;
|
|
||||||
|
|
||||||
QRegExp regExp("Channels\\s*:\\s*(\\d+)", Qt::CaseInsensitive);
|
|
||||||
|
|
||||||
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;
|
|
||||||
unsigned int temp = regExp.cap(1).toUInt(&ok);
|
|
||||||
if(ok) channels = temp;
|
|
||||||
}
|
|
||||||
if(!text.isEmpty())
|
|
||||||
{
|
|
||||||
emit messageLogged(text);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
process.waitForFinished();
|
|
||||||
if(process.state() != QProcess::NotRunning)
|
|
||||||
{
|
|
||||||
process.kill();
|
|
||||||
process.waitForFinished(-1);
|
|
||||||
}
|
|
||||||
|
|
||||||
return channels;
|
|
||||||
}
|
|
||||||
|
@ -23,15 +23,16 @@
|
|||||||
|
|
||||||
#include "Filter_Abstract.h"
|
#include "Filter_Abstract.h"
|
||||||
|
|
||||||
|
class WaveProperties;
|
||||||
|
|
||||||
class DownmixFilter : public AbstractFilter
|
class DownmixFilter : public AbstractFilter
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
DownmixFilter(void);
|
DownmixFilter(void);
|
||||||
~DownmixFilter(void);
|
~DownmixFilter(void);
|
||||||
|
|
||||||
virtual bool apply(const QString &sourceFile, const QString &outputFile, volatile bool *abortFlag);
|
virtual bool apply(const QString &sourceFile, const QString &outputFile, AudioFileModel *formatInfo, volatile bool *abortFlag);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
const QString m_binary;
|
const QString m_binary;
|
||||||
unsigned int detectChannels(const QString &sourceFile, volatile bool *abortFlag);
|
|
||||||
};
|
};
|
||||||
|
@ -44,7 +44,7 @@ NormalizeFilter::~NormalizeFilter(void)
|
|||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
bool NormalizeFilter::apply(const QString &sourceFile, const QString &outputFile, volatile bool *abortFlag)
|
bool NormalizeFilter::apply(const QString &sourceFile, const QString &outputFile, AudioFileModel *formatInfo, volatile bool *abortFlag)
|
||||||
{
|
{
|
||||||
QProcess process;
|
QProcess process;
|
||||||
QStringList args;
|
QStringList args;
|
||||||
|
@ -29,7 +29,7 @@ public:
|
|||||||
NormalizeFilter(int peakVolume = -50, int equalizationMode = 0);
|
NormalizeFilter(int peakVolume = -50, int equalizationMode = 0);
|
||||||
~NormalizeFilter(void);
|
~NormalizeFilter(void);
|
||||||
|
|
||||||
virtual bool apply(const QString &sourceFile, const QString &outputFile, volatile bool *abortFlag);
|
virtual bool apply(const QString &sourceFile, const QString &outputFile, AudioFileModel *formatInfo, volatile bool *abortFlag);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
const QString m_binary;
|
const QString m_binary;
|
||||||
|
@ -22,6 +22,7 @@
|
|||||||
#include "Filter_Resample.h"
|
#include "Filter_Resample.h"
|
||||||
|
|
||||||
#include "Global.h"
|
#include "Global.h"
|
||||||
|
#include "Model_AudioFile.h"
|
||||||
|
|
||||||
#include <QDir>
|
#include <QDir>
|
||||||
#include <QProcess>
|
#include <QProcess>
|
||||||
@ -54,11 +55,18 @@ ResampleFilter::~ResampleFilter(void)
|
|||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
bool ResampleFilter::apply(const QString &sourceFile, const QString &outputFile, volatile bool *abortFlag)
|
bool ResampleFilter::apply(const QString &sourceFile, const QString &outputFile, AudioFileModel *formatInfo, volatile bool *abortFlag)
|
||||||
{
|
{
|
||||||
QProcess process;
|
QProcess process;
|
||||||
QStringList args;
|
QStringList args;
|
||||||
|
|
||||||
|
if((m_samplingRate == formatInfo->formatAudioSamplerate()) && (m_bitDepth == formatInfo->formatAudioBitdepth()))
|
||||||
|
{
|
||||||
|
messageLogged("Skipping resample filter!");
|
||||||
|
qDebug("Resampling filter target samplerate/bitdepth is equals to the format of the input file, skipping!");
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
process.setWorkingDirectory(QFileInfo(outputFile).canonicalPath());
|
process.setWorkingDirectory(QFileInfo(outputFile).canonicalPath());
|
||||||
|
|
||||||
args << "-V3" << "-S";
|
args << "-V3" << "-S";
|
||||||
@ -145,5 +153,8 @@ bool ResampleFilter::apply(const QString &sourceFile, const QString &outputFile,
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if(m_samplingRate) formatInfo->setFormatAudioSamplerate(m_samplingRate);
|
||||||
|
if(m_bitDepth) formatInfo->setFormatAudioBitdepth(m_bitDepth);
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
@ -29,7 +29,7 @@ public:
|
|||||||
ResampleFilter(int samplingRate = 0, int bitDepth = 0);
|
ResampleFilter(int samplingRate = 0, int bitDepth = 0);
|
||||||
~ResampleFilter(void);
|
~ResampleFilter(void);
|
||||||
|
|
||||||
virtual bool apply(const QString &sourceFile, const QString &outputFile, volatile bool *abortFlag);
|
virtual bool apply(const QString &sourceFile, const QString &outputFile, AudioFileModel *formatInfo, volatile bool *abortFlag);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
const QString m_binary;
|
const QString m_binary;
|
||||||
|
@ -45,7 +45,7 @@ ToneAdjustFilter::~ToneAdjustFilter(void)
|
|||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
bool ToneAdjustFilter::apply(const QString &sourceFile, const QString &outputFile, volatile bool *abortFlag)
|
bool ToneAdjustFilter::apply(const QString &sourceFile, const QString &outputFile, AudioFileModel *formatInfo, volatile bool *abortFlag)
|
||||||
{
|
{
|
||||||
QProcess process;
|
QProcess process;
|
||||||
QStringList args;
|
QStringList args;
|
||||||
|
@ -29,7 +29,7 @@ public:
|
|||||||
ToneAdjustFilter(int bass = 0, int treble = 0);
|
ToneAdjustFilter(int bass = 0, int treble = 0);
|
||||||
~ToneAdjustFilter(void);
|
~ToneAdjustFilter(void);
|
||||||
|
|
||||||
virtual bool apply(const QString &sourceFile, const QString &outputFile, volatile bool *abortFlag);
|
virtual bool apply(const QString &sourceFile, const QString &outputFile, AudioFileModel *formatInfo, volatile bool *abortFlag);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
const QString m_binary;
|
const QString m_binary;
|
||||||
|
@ -177,7 +177,7 @@ void ProcessThread::processFile()
|
|||||||
//------------------------------------
|
//------------------------------------
|
||||||
if(bSuccess && !m_aborted && IS_WAVE(m_audioFile))
|
if(bSuccess && !m_aborted && IS_WAVE(m_audioFile))
|
||||||
{
|
{
|
||||||
if(m_encoder->supportedSamplerates() || m_encoder->supportedBitdepths() || m_encoder->supportedChannelCount())
|
if(m_encoder->supportedSamplerates() || m_encoder->supportedBitdepths() || m_encoder->supportedChannelCount() || !m_filters.isEmpty())
|
||||||
{
|
{
|
||||||
m_currentStep = AnalyzeStep;
|
m_currentStep = AnalyzeStep;
|
||||||
bSuccess = m_propDetect->detect(sourceFile, &m_audioFile, &m_aborted);
|
bSuccess = m_propDetect->detect(sourceFile, &m_audioFile, &m_aborted);
|
||||||
@ -215,7 +215,7 @@ void ProcessThread::processFile()
|
|||||||
connect(poFilter, SIGNAL(statusUpdated(int)), this, SLOT(handleUpdate(int)), Qt::DirectConnection);
|
connect(poFilter, SIGNAL(statusUpdated(int)), this, SLOT(handleUpdate(int)), Qt::DirectConnection);
|
||||||
connect(poFilter, SIGNAL(messageLogged(QString)), this, SLOT(handleMessage(QString)), Qt::DirectConnection);
|
connect(poFilter, SIGNAL(messageLogged(QString)), this, SLOT(handleMessage(QString)), Qt::DirectConnection);
|
||||||
|
|
||||||
if(poFilter->apply(sourceFile, tempFile, &m_aborted))
|
if(poFilter->apply(sourceFile, tempFile, &m_audioFile, &m_aborted))
|
||||||
{
|
{
|
||||||
sourceFile = tempFile;
|
sourceFile = tempFile;
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user