The information whether an encoder supports "native" resampling is provided via AbstractEncoderInfo class + enable "native" resampling for QAAC encoder.
This commit is contained in:
parent
87a6e5cc18
commit
de243d258f
@ -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
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
|
@ -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))
|
||||
|
@ -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;
|
||||
|
||||
|
@ -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;
|
||||
|
||||
|
@ -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;
|
||||
|
||||
|
@ -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());
|
||||
|
@ -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;
|
||||
|
||||
|
@ -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
|
||||
*/
|
||||
|
@ -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
|
||||
|
@ -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;
|
||||
|
||||
|
@ -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;
|
||||
|
||||
|
@ -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;
|
||||
|
||||
|
@ -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;
|
||||
|
@ -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);
|
||||
|
@ -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;
|
||||
|
||||
|
@ -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;
|
||||
|
@ -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;
|
||||
};
|
||||
|
@ -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;
|
||||
|
||||
|
@ -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;
|
||||
|
@ -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);
|
||||
|
Loading…
Reference in New Issue
Block a user