The information whether an encoder supports "native" resampling is provided via AbstractEncoderInfo class + enable "native" resampling for QAAC encoder.

This commit is contained in:
LoRd_MuldeR 2016-01-30 17:51:10 +01:00
parent 87a6e5cc18
commit de243d258f
20 changed files with 132 additions and 50 deletions

View File

@ -35,7 +35,7 @@
#define VER_LAMEXP_MINOR_LO 4
#define VER_LAMEXP_TYPE Alpha
#define VER_LAMEXP_PATCH 1
#define VER_LAMEXP_BUILD 1857
#define VER_LAMEXP_BUILD 1858
#define VER_LAMEXP_CONFG 1818
///////////////////////////////////////////////////////////////////////////////

View File

@ -569,10 +569,9 @@ void ProcessingDialog::startNextJob(void)
m_runningThreads++;
AudioFileModel currentFile = updateMetaInfo(m_pendingJobs.takeFirst());
bool nativeResampling = false;
//Create encoder instance
AbstractEncoder *encoder = EncoderRegistry::createInstance(m_settings->compressionEncoder(), m_settings, &nativeResampling);
AbstractEncoder *encoder = EncoderRegistry::createInstance(m_settings->compressionEncoder(), m_settings);
//Create processing thread
ProcessThread *thread = new ProcessThread
@ -589,11 +588,19 @@ void ProcessingDialog::startNextJob(void)
{
thread->addFilter(new DownmixFilter());
}
if((m_settings->samplingRate() > 0) && !nativeResampling)
if(m_settings->samplingRate() > 0)
{
if(SettingsModel::samplingRates[m_settings->samplingRate()] != currentFile.techInfo().audioSamplerate() || currentFile.techInfo().audioSamplerate() == 0)
const int targetRate = SettingsModel::samplingRates[qBound(1, m_settings->samplingRate(), 6)];
if((targetRate != currentFile.techInfo().audioSamplerate()) || (currentFile.techInfo().audioSamplerate() == 0))
{
thread->addFilter(new ResampleFilter(SettingsModel::samplingRates[m_settings->samplingRate()]));
if (encoder->toEncoderInfo()->isResamplingSupported())
{
encoder->setSamplingRate(targetRate);
}
else
{
thread->addFilter(new ResampleFilter(targetRate));
}
}
}
if((m_settings->toneAdjustBass() != 0) || (m_settings->toneAdjustTreble() != 0))

View File

@ -114,6 +114,11 @@ class AACEncoderInfo : public AbstractEncoderInfo
static const char* s_extension = "mp4";
return s_extension;
}
virtual bool isResamplingSupported(void) const
{
return false;
}
}
static const g_aacEncoderInfo;

View File

@ -120,6 +120,11 @@ class FDKAACEncoderInfo : public AbstractEncoderInfo
static const char* s_extension = "mp4";
return s_extension;
}
virtual bool isResamplingSupported(void) const
{
return false;
}
}
static const g_fdkAacEncoderInfo;

View File

@ -117,6 +117,11 @@ class FHGAACEncoderInfo : public AbstractEncoderInfo
static const char* s_extension = "mp4";
return s_extension;
}
virtual bool isResamplingSupported(void) const
{
return false;
}
}
static const g_fhgAacEncoderInfo;

View File

@ -125,6 +125,11 @@ class QAACEncoderInfo : public AbstractEncoderInfo
static const char* s_extension = "mp4";
return s_extension;
}
virtual bool isResamplingSupported(void) const
{
return true;
}
}
static const g_qaacEncoderInfo;
@ -187,6 +192,12 @@ bool QAACEncoder::encode(const QString &sourceFile, const AudioFileModel_MetaInf
break;
}
if (m_configSamplingRate > 0)
{
args << "-native-resampler" << "bats,127";
args << "--rate" << QString::number(m_configSamplingRate);
}
if(!m_configCustomParams.isEmpty()) args << m_configCustomParams.split(" ", QString::SkipEmptyParts);
if(!metaInfo.title().isEmpty()) args << "--title" << cleanTag(metaInfo.title());

View File

@ -113,6 +113,11 @@ class AC3EncoderInfo : public AbstractEncoderInfo
static const char* s_extension = "ac3";
return s_extension;
}
virtual bool isResamplingSupported(void) const
{
return false;
}
}
static const g_aftenEncoderInfo;

View File

@ -33,6 +33,7 @@ AbstractEncoder::AbstractEncoder(void)
m_configBitrate = 0;
m_configRCMode = 0;
m_configCustomParams.clear();
m_configSamplingRate = 0;
}
AbstractEncoder::~AbstractEncoder(void)
@ -43,9 +44,38 @@ AbstractEncoder::~AbstractEncoder(void)
* Setters
*/
void AbstractEncoder::setBitrate(int bitrate) { m_configBitrate = qMax(0, bitrate); }
void AbstractEncoder::setRCMode(int mode) { m_configRCMode = qMax(0, mode); }
void AbstractEncoder::setCustomParams(const QString &customParams) { m_configCustomParams = customParams.trimmed(); }
void AbstractEncoder::setRCMode(const int &mode)
{
if (!toEncoderInfo()->isModeSupported(qMax(0, mode)))
{
MUTILS_THROW("This RC mode is not supported by the encoder!");
}
m_configRCMode = qMax(0, mode);
}
void AbstractEncoder::setBitrate(const int &bitrate)
{
if (qMax(0, bitrate) >= toEncoderInfo()->valueCount(bitrate))
{
MUTILS_THROW("The specified bitrate/quality is out of range!");
}
m_configBitrate = qMax(0, bitrate);
}
void AbstractEncoder::setCustomParams(const QString &customParams)
{
m_configCustomParams = customParams.trimmed();
}
void AbstractEncoder::setSamplingRate(const int &value)
{
if (!toEncoderInfo()->isResamplingSupported())
{
MUTILS_THROW("This encoder does *not* support native resampling!");
}
m_configSamplingRate = qBound(0, value, 48000);
};
/*
* Default implementation
@ -75,6 +105,7 @@ const bool AbstractEncoder::needsTimingInfo(void)
return false;
}
/*
* Helper functions
*/

View File

@ -49,6 +49,7 @@ public:
value_type_t;
virtual bool isModeSupported(int mode) const = 0; //Returns whether the encoder does support the current RC mode
virtual bool isResamplingSupported(void) const = 0; //Returns whether the encoder has "native" resampling support
virtual int valueCount(int mode) const = 0; //The number of bitrate/quality values for current RC mode
virtual int valueAt(int mode, int index) const = 0; //The bitrate/quality value at 'index' for the current RC mode
virtual int valueType(int mode) const = 0; //The display type of the values for the current RC mode
@ -73,8 +74,9 @@ public:
virtual const bool needsTimingInfo(void);
//Common setter methods
virtual void setBitrate(int bitrate);
virtual void setRCMode(int mode);
virtual void setBitrate(const int &bitrate);
virtual void setRCMode(const int &mode);
virtual void setSamplingRate(const int &value);
virtual void setCustomParams(const QString &customParams);
//Encoder info
@ -88,6 +90,7 @@ public:
protected:
int m_configBitrate; //Bitrate *or* VBR-quality-level
int m_configRCMode; //Rate-control mode
int m_configSamplingRate; //Target sampling rate
QString m_configCustomParams; //Custom parameters, if any
//Helper functions

View File

@ -115,6 +115,11 @@ class DCAEncoderInfo : public AbstractEncoderInfo
static const char* s_extension = "dts";
return s_extension;
}
virtual bool isResamplingSupported(void) const
{
return false;
}
}
static const g_dcaEncoderInfo;

View File

@ -109,6 +109,11 @@ public:
static const char* s_extension = "flac";
return s_extension;
}
virtual bool isResamplingSupported(void) const
{
return false;
}
}
static const g_flacEncoderInfo;

View File

@ -109,6 +109,11 @@ class MACEncoderInfo : public AbstractEncoderInfo
static const char* s_extension = "ape";
return s_extension;
}
virtual bool isResamplingSupported(void) const
{
return false;
}
}
static const g_macEncoderInfo;

View File

@ -114,6 +114,11 @@ class MP3EncoderInfo : public AbstractEncoderInfo
static const char* s_extension = "mp3";
return s_extension;
}
virtual bool isResamplingSupported(void) const
{
return true;
}
}
static const g_mp3EncoderInfo;
@ -334,11 +339,6 @@ void MP3Encoder::setBitrateLimits(int minimumBitrate, int maximumBitrate)
m_configBitrateMaximum = maximumBitrate;
}
void MP3Encoder::setSamplingRate(int value)
{
m_configSamplingRate = value;
}
void MP3Encoder::setChannelMode(int value)
{
m_configChannelMode = value;

View File

@ -41,7 +41,6 @@ public:
//Advanced options
virtual void setAlgoQuality(int value);
virtual void setBitrateLimits(int minimumBitrate, int maximumBitrate);
virtual void setSamplingRate(int value);
virtual void setChannelMode(int value);
//Encoder info
@ -53,7 +52,6 @@ private:
int m_algorithmQuality;
int m_configBitrateMaximum;
int m_configBitrateMinimum;
int m_configSamplingRate;
int m_configChannelMode;
int clipBitrate(int bitrate);

View File

@ -110,6 +110,11 @@ class OpusEncoderInfo : public AbstractEncoderInfo
static const char* s_extension = "opus";
return s_extension;
}
virtual bool isResamplingSupported(void) const
{
return false;
}
}
static const g_opusEncoderInfo;

View File

@ -111,6 +111,11 @@ class VorbisEncoderInfo : public AbstractEncoderInfo
static const char* s_extension = "ogg";
return s_extension;
}
virtual bool isResamplingSupported(void) const
{
return true;
}
}
static const g_vorbisEncoderInfo;
@ -275,11 +280,6 @@ void VorbisEncoder::setBitrateLimits(int minimumBitrate, int maximumBitrate)
m_configBitrateMaximum = maximumBitrate;
}
void VorbisEncoder::setSamplingRate(int value)
{
m_configSamplingRate = value;
}
const AbstractEncoderInfo *VorbisEncoder::getEncoderInfo(void)
{
return &g_vorbisEncoderInfo;

View File

@ -37,7 +37,6 @@ public:
virtual bool encode(const QString &sourceFile, const AudioFileModel_MetaInfo &metaInfo, const unsigned int duration, 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 void setBitrateLimits(int minimumBitrate, int maximumBitrate);
virtual void setSamplingRate(int value);
//Encoder info
virtual const AbstractEncoderInfo *toEncoderInfo(void) const { return getEncoderInfo(); }
@ -47,5 +46,4 @@ private:
const QString m_binary;
int m_configBitrateMaximum;
int m_configBitrateMinimum;
int m_configSamplingRate;
};

View File

@ -111,6 +111,11 @@ public:
static const char* s_extension = "wav";
return s_extension;
}
virtual bool isResamplingSupported(void) const
{
return false;
}
}
static const g_waveEncoderInfo;

View File

@ -45,11 +45,10 @@
// Create encoder instance
////////////////////////////////////////////////////////////
AbstractEncoder *EncoderRegistry::createInstance(const int encoderId, const SettingsModel *settings, bool *nativeResampling)
AbstractEncoder *EncoderRegistry::createInstance(const int encoderId, const SettingsModel *settings)
{
int rcMode = -1;
AbstractEncoder *encoder = NULL;
*nativeResampling = false;
//Create new encoder instance and apply encoder-specific settings
switch(encoderId)
@ -57,17 +56,12 @@ AbstractEncoder *EncoderRegistry::createInstance(const int encoderId, const Sett
/*-------- MP3Encoder /*--------*/
case SettingsModel::MP3Encoder:
{
MP3Encoder *mp3Encoder = new MP3Encoder();
MP3Encoder *const mp3Encoder = new MP3Encoder();
mp3Encoder->setAlgoQuality(settings->lameAlgoQuality());
if(settings->bitrateManagementEnabled())
{
mp3Encoder->setBitrateLimits(settings->bitrateManagementMinRate(), settings->bitrateManagementMaxRate());
}
if(settings->samplingRate() > 0)
{
mp3Encoder->setSamplingRate(SettingsModel::samplingRates[settings->samplingRate()]);
*nativeResampling = true;
}
mp3Encoder->setChannelMode(settings->lameChannelMode());
encoder = mp3Encoder;
}
@ -75,16 +69,11 @@ AbstractEncoder *EncoderRegistry::createInstance(const int encoderId, const Sett
/*-------- VorbisEncoder /*--------*/
case SettingsModel::VorbisEncoder:
{
VorbisEncoder *vorbisEncoder = new VorbisEncoder();
VorbisEncoder *const vorbisEncoder = new VorbisEncoder();
if(settings->bitrateManagementEnabled())
{
vorbisEncoder->setBitrateLimits(settings->bitrateManagementMinRate(), settings->bitrateManagementMaxRate());
}
if(settings->samplingRate() > 0)
{
vorbisEncoder->setSamplingRate(SettingsModel::samplingRates[settings->samplingRate()]);
*nativeResampling = true;
}
encoder = vorbisEncoder;
}
break;
@ -95,28 +84,28 @@ AbstractEncoder *EncoderRegistry::createInstance(const int encoderId, const Sett
{
case SettingsModel::AAC_ENCODER_QAAC:
{
QAACEncoder *aacEncoder = new QAACEncoder();
QAACEncoder *const aacEncoder = new QAACEncoder();
aacEncoder->setProfile(settings->aacEncProfile());
encoder = aacEncoder;
}
break;
case SettingsModel::AAC_ENCODER_FHG:
{
FHGAACEncoder *aacEncoder = new FHGAACEncoder();
FHGAACEncoder *const aacEncoder = new FHGAACEncoder();
aacEncoder->setProfile(settings->aacEncProfile());
encoder = aacEncoder;
}
break;
case SettingsModel::AAC_ENCODER_FDK:
{
FDKAACEncoder *aacEncoder = new FDKAACEncoder();
FDKAACEncoder *const aacEncoder = new FDKAACEncoder();
aacEncoder->setProfile(settings->aacEncProfile());
encoder = aacEncoder;
}
break;
case SettingsModel::AAC_ENCODER_NERO:
{
AACEncoder *aacEncoder = new AACEncoder();
AACEncoder *const aacEncoder = new AACEncoder();
aacEncoder->setEnable2Pass(settings->neroAACEnable2Pass());
aacEncoder->setProfile(settings->aacEncProfile());
encoder = aacEncoder;
@ -131,7 +120,7 @@ AbstractEncoder *EncoderRegistry::createInstance(const int encoderId, const Sett
/*-------- AC3Encoder /*--------*/
case SettingsModel::AC3Encoder:
{
AC3Encoder *ac3Encoder = new AC3Encoder();
AC3Encoder *const ac3Encoder = new AC3Encoder();
ac3Encoder->setAudioCodingMode(settings->aftenAudioCodingMode());
ac3Encoder->setDynamicRangeCompression(settings->aftenDynamicRangeCompression());
ac3Encoder->setExponentSearchSize(settings->aftenExponentSearchSize());
@ -142,14 +131,14 @@ AbstractEncoder *EncoderRegistry::createInstance(const int encoderId, const Sett
/*-------- FLACEncoder /*--------*/
case SettingsModel::FLACEncoder:
{
FLACEncoder *flacEncoder = new FLACEncoder();
FLACEncoder *const flacEncoder = new FLACEncoder();
encoder = flacEncoder;
}
break;
/*-------- OpusEncoder --------*/
case SettingsModel::OpusEncoder:
{
OpusEncoder *opusEncoder = new OpusEncoder();
OpusEncoder *const opusEncoder = new OpusEncoder();
opusEncoder->setOptimizeFor(settings->opusOptimizeFor());
opusEncoder->setEncodeComplexity(settings->opusComplexity());
opusEncoder->setFrameSize(settings->opusFramesize());
@ -159,21 +148,21 @@ AbstractEncoder *EncoderRegistry::createInstance(const int encoderId, const Sett
/*-------- DCAEncoder --------*/
case SettingsModel::DCAEncoder:
{
DCAEncoder *dcaEncoder = new DCAEncoder();
DCAEncoder *const dcaEncoder = new DCAEncoder();
encoder = dcaEncoder;
}
break;
/*-------- MACEncoder --------*/
case SettingsModel::MACEncoder:
{
MACEncoder *macEncoder = new MACEncoder();
MACEncoder *const macEncoder = new MACEncoder();
encoder = macEncoder;
}
break;
/*-------- PCMEncoder --------*/
case SettingsModel::PCMEncoder:
{
WaveEncoder *waveEncoder = new WaveEncoder();
WaveEncoder *const waveEncoder = new WaveEncoder();
encoder = waveEncoder;
}
break;

View File

@ -34,7 +34,7 @@ class EncoderRegistry : public QObject
Q_OBJECT
public:
static AbstractEncoder *createInstance(const int encoderId, const SettingsModel *settings, bool *nativeResampling);
static AbstractEncoder *createInstance(const int encoderId, const SettingsModel *settings);
static const AbstractEncoderInfo *getEncoderInfo(const int encoderId);
static void saveEncoderMode(SettingsModel *settings, const int encoderId, const int rcMode);