diff --git a/src/Config.h b/src/Config.h index d6da79dc..28275e37 100644 --- a/src/Config.h +++ b/src/Config.h @@ -34,7 +34,7 @@ #define VER_LAMEXP_MINOR_LO 9 #define VER_LAMEXP_TYPE Alpha #define VER_LAMEXP_PATCH 1 -#define VER_LAMEXP_BUILD 1348 +#define VER_LAMEXP_BUILD 1349 #define VER_LAMEXP_CONFG 1348 /////////////////////////////////////////////////////////////////////////////// diff --git a/src/Dialog_MainWindow.cpp b/src/Dialog_MainWindow.cpp index 78ec6f11..c6afdf2d 100644 --- a/src/Dialog_MainWindow.cpp +++ b/src/Dialog_MainWindow.cpp @@ -3291,41 +3291,30 @@ void MainWindow::playlistEnabledChanged(void) */ void MainWindow::updateEncoder(int id) { - qWarning("\nupdateEncoder(%d)", id); + /*qWarning("\nupdateEncoder(%d)", id);*/ m_settings->compressionEncoder(id); const AbstractEncoderInfo *info = EncoderRegistry::getEncoderInfo(id); - qWarning("info->isModeSupported(SettingsModel::VBRMode) = %s", info->isModeSupported(SettingsModel::VBRMode) ? "YES" : "NO"); - qWarning("info->isModeSupported(SettingsModel::ABRMode) = %s", info->isModeSupported(SettingsModel::ABRMode) ? "YES" : "NO"); - qWarning("info->isModeSupported(SettingsModel::CBRMode) = %s", info->isModeSupported(SettingsModel::CBRMode) ? "YES" : "NO"); - //Update UI controls - ui->radioButtonModeQuality->setEnabled(info->isModeSupported(SettingsModel::VBRMode)); + ui->radioButtonModeQuality ->setEnabled(info->isModeSupported(SettingsModel::VBRMode)); ui->radioButtonModeAverageBitrate->setEnabled(info->isModeSupported(SettingsModel::ABRMode)); - ui->radioButtonConstBitrate->setEnabled(info->isModeSupported(SettingsModel::CBRMode)); + ui->radioButtonConstBitrate ->setEnabled(info->isModeSupported(SettingsModel::CBRMode)); //Initialize checkbox state - if(ui->radioButtonModeQuality->isEnabled()) ui->radioButtonModeQuality->setChecked(true); + if(ui->radioButtonModeQuality->isEnabled()) ui->radioButtonModeQuality->setChecked(true); else if(ui->radioButtonModeAverageBitrate->isEnabled()) ui->radioButtonModeAverageBitrate->setChecked(true); - else if(ui->radioButtonConstBitrate->isEnabled()) ui->radioButtonConstBitrate->setChecked(true); + else if(ui->radioButtonConstBitrate->isEnabled()) ui->radioButtonConstBitrate->setChecked(true); else throw "It appears that the encoder does not support *any* RC mode!"; //Apply current RC mode const int currentRCMode = EncoderRegistry::loadEncoderMode(m_settings, id); switch(currentRCMode) { - case SettingsModel::VBRMode: - if(ui->radioButtonModeQuality->isEnabled()) ui->radioButtonModeQuality->setChecked(true); - break; - case SettingsModel::ABRMode: - if(ui->radioButtonModeAverageBitrate->isEnabled()) ui->radioButtonModeAverageBitrate->setChecked(true); - break; - case SettingsModel::CBRMode: - if(ui->radioButtonConstBitrate->isEnabled()) ui->radioButtonConstBitrate->setChecked(true); - break; - default: - throw "updateEncoder(): Unknown rc-mode encountered!"; + case SettingsModel::VBRMode: if(ui->radioButtonModeQuality->isEnabled()) ui->radioButtonModeQuality->setChecked(true); break; + case SettingsModel::ABRMode: if(ui->radioButtonModeAverageBitrate->isEnabled()) ui->radioButtonModeAverageBitrate->setChecked(true); break; + case SettingsModel::CBRMode: if(ui->radioButtonConstBitrate->isEnabled()) ui->radioButtonConstBitrate->setChecked(true); break; + default: throw "updateEncoder(): Unknown rc-mode encountered!"; } //Display encoder description @@ -3340,7 +3329,7 @@ void MainWindow::updateEncoder(int id) } //Update RC mode! - updateRCMode(currentRCMode); + updateRCMode(m_modeButtonGroup->checkedId()); } /* @@ -3348,6 +3337,8 @@ void MainWindow::updateEncoder(int id) */ void MainWindow::updateRCMode(int id) { + /*qWarning("updateRCMode(%d)", id);*/ + //Store new RC mode const int currentEncoder = m_encoderButtonGroup->checkedId(); EncoderRegistry::saveEncoderMode(m_settings, currentEncoder, id); @@ -3356,6 +3347,14 @@ void MainWindow::updateRCMode(int id) const AbstractEncoderInfo *info = EncoderRegistry::getEncoderInfo(currentEncoder); const int valueCount = info->valueCount(id); + //Sanity check + if(!info->isModeSupported(id)) + { + qWarning("Attempting to use an unsupported RC mode (%d) with current encoder (%d)!", id, currentEncoder); + ui->labelBitrate->setText("(ERROR)"); + return; + } + //Update slider min/max values if(valueCount > 0) { @@ -3373,9 +3372,9 @@ void MainWindow::updateRCMode(int id) //Now update bitrate/quality value! if(valueCount > 0) { - const int currentValue = qBound(0, EncoderRegistry::loadEncoderValue(m_settings, currentEncoder, id), valueCount-1); - ui->sliderBitrate->setValue(currentValue); - updateBitrate(currentValue); + const int currentValue = EncoderRegistry::loadEncoderValue(m_settings, currentEncoder, id); + ui->sliderBitrate->setValue(qBound(0, currentValue, valueCount-1)); + updateBitrate(qBound(0, currentValue, valueCount-1)); } else { @@ -3389,15 +3388,25 @@ void MainWindow::updateRCMode(int id) */ void MainWindow::updateBitrate(int value) { + /*qWarning("updateBitrate(%d)", value);*/ + //Load current encoder and RC mode const int currentEncoder = m_encoderButtonGroup->checkedId(); - const int currentRCMode = EncoderRegistry::loadEncoderMode(m_settings, currentEncoder); + const int currentRCMode = m_modeButtonGroup->checkedId(); //Fetch encoder info const AbstractEncoderInfo *info = EncoderRegistry::getEncoderInfo(currentEncoder); const int valueCount = info->valueCount(currentRCMode); - //Store new bitrate valie + //Sanity check + if(!info->isModeSupported(currentRCMode)) + { + qWarning("Attempting to use an unsupported RC mode (%d) with current encoder (%d)!", currentRCMode, currentEncoder); + ui->labelBitrate->setText("(ERROR)"); + return; + } + + //Store new bitrate value if(valueCount > 0) { EncoderRegistry::saveEncoderValue(m_settings, currentEncoder, currentRCMode, qBound(0, value, valueCount-1)); diff --git a/src/Encoder_AC3.cpp b/src/Encoder_AC3.cpp index 5b99993f..5d75941b 100644 --- a/src/Encoder_AC3.cpp +++ b/src/Encoder_AC3.cpp @@ -29,6 +29,90 @@ static const int g_ac3BitratesLUT[20] = {32, 40, 48, 56, 64, 80, 96, 112, 128, 160, 192, 224, 256, 320, 384, 448, 512, 576, 640, -1}; +/////////////////////////////////////////////////////////////////////////////// +// Encoder Info +/////////////////////////////////////////////////////////////////////////////// + +class AC3EncoderInfo : public AbstractEncoderInfo +{ + virtual bool isModeSupported(int mode) const + { + switch(mode) + { + case SettingsModel::VBRMode: + case SettingsModel::CBRMode: + return true; + break; + case SettingsModel::ABRMode: + return false; + break; + default: + throw "Bad RC mode specified!"; + } + } + + virtual int valueCount(int mode) const + { + switch(mode) + { + case SettingsModel::VBRMode: + return 65; + break; + case SettingsModel::ABRMode: + return 0; + break; + case SettingsModel::CBRMode: + return 19; + break; + default: + throw "Bad RC mode specified!"; + } + } + + virtual int valueAt(int mode, int index) const + { + switch(mode) + { + case SettingsModel::VBRMode: + return qBound(0, index * 16, 1023); + break; + case SettingsModel::ABRMode: + case SettingsModel::CBRMode: + return g_ac3BitratesLUT[qBound(0, index, 18)]; + break; + default: + throw "Bad RC mode specified!"; + } + } + + virtual int valueType(int mode) const + { + switch(mode) + { + case SettingsModel::VBRMode: + return TYPE_QUALITY_LEVEL; + break; + case SettingsModel::ABRMode: + case SettingsModel::CBRMode: + return TYPE_BITRATE; + break; + default: + throw "Bad RC mode specified!"; + } + } + + virtual const char *description(void) const + { + static const char* s_description = "Aften: A/52 Audio Encoder"; + return s_description; + } +} +static const g_aftenEncoderInfo; + +/////////////////////////////////////////////////////////////////////////////// +// Encoder implementation +/////////////////////////////////////////////////////////////////////////////// + AC3Encoder::AC3Encoder(void) : m_binary(lamexp_lookup_tool("aften.exe")) @@ -56,10 +140,10 @@ bool AC3Encoder::encode(const QString &sourceFile, const AudioFileModel &metaInf switch(m_configRCMode) { case SettingsModel::VBRMode: - args << "-q" << QString::number(qMax(0, qMin(1023, m_configBitrate * 64))); + args << "-q" << QString::number(qBound(0, m_configBitrate * 16, 1023)); break; case SettingsModel::CBRMode: - args << "-b" << QString::number(g_ac3BitratesLUT[qMax(0, qMin(18, m_configBitrate))]); + args << "-b" << QString::number(g_ac3BitratesLUT[qBound(0, m_configBitrate, 18)]); break; default: throw "Bad rate-control mode!"; @@ -205,3 +289,8 @@ bool AC3Encoder::isFormatSupported(const QString &containerType, const QString & return false; } + +const AbstractEncoderInfo *AC3Encoder::getEncoderInfo(void) +{ + return &g_aftenEncoderInfo; +} diff --git a/src/Encoder_AC3.h b/src/Encoder_AC3.h index b7227026..b397b17a 100644 --- a/src/Encoder_AC3.h +++ b/src/Encoder_AC3.h @@ -45,6 +45,9 @@ public: virtual void setExponentSearchSize(int value); virtual void setFastBitAllocation(bool value); + //Encoder info + static const AbstractEncoderInfo *getEncoderInfo(void); + private: const QString m_binary; int m_configAudioCodingMode; diff --git a/src/Encoder_DCA.cpp b/src/Encoder_DCA.cpp index a1ba76fd..2a74d148 100644 --- a/src/Encoder_DCA.cpp +++ b/src/Encoder_DCA.cpp @@ -28,6 +28,93 @@ #include #include +static int index2bitrate(const int index) +{ + return (index < 8) ? ((index + 1) * 32) : ((index < 12) ? ((index - 3) * 64) : ((index < 24) ? (index - 7) * 128 : (index - 15) * 256)); +} + +/////////////////////////////////////////////////////////////////////////////// +// Encoder Info +/////////////////////////////////////////////////////////////////////////////// + +class DCAEncoderInfo : public AbstractEncoderInfo +{ + virtual bool isModeSupported(int mode) const + { + switch(mode) + { + case SettingsModel::VBRMode: + case SettingsModel::ABRMode: + return false; + break; + case SettingsModel::CBRMode: + return true; + break; + default: + throw "Bad RC mode specified!"; + } + } + + virtual int valueCount(int mode) const + { + switch(mode) + { + case SettingsModel::VBRMode: + case SettingsModel::ABRMode: + return 0; + break; + case SettingsModel::CBRMode: + return 32; + break; + default: + throw "Bad RC mode specified!"; + } + } + + virtual int valueAt(int mode, int index) const + { + switch(mode) + { + case SettingsModel::VBRMode: + case SettingsModel::ABRMode: + return 0; + break; + case SettingsModel::CBRMode: + return qBound(32, index2bitrate(index), 4096); + break; + default: + throw "Bad RC mode specified!"; + } + } + + virtual int valueType(int mode) const + { + switch(mode) + { + case SettingsModel::VBRMode: + return TYPE_QUALITY_LEVEL; + break; + case SettingsModel::ABRMode: + case SettingsModel::CBRMode: + return TYPE_BITRATE; + break; + default: + throw "Bad RC mode specified!"; + } + } + + virtual const char *description(void) const + { + static const char* s_description = "dcaenc-2 by Alexander E. Patrakov"; + return s_description; + } +} +static const g_dcaEncoderInfo; + +/////////////////////////////////////////////////////////////////////////////// +// Encoder implementation +/////////////////////////////////////////////////////////////////////////////// + DCAEncoder::DCAEncoder(void) : m_binary(lamexp_lookup_tool("dcaenc.exe")) @@ -47,11 +134,9 @@ bool DCAEncoder::encode(const QString &sourceFile, const AudioFileModel &metaInf QProcess process; QStringList args; - int bitrate = qBound(32, m_configBitrate * 32, 6144); - args << "-i" << QDir::toNativeSeparators(sourceFile); args << "-o" << QDir::toNativeSeparators(outputFile); - args << "-b" << QString::number(bitrate); + args << "-b" << QString::number(qBound(32, index2bitrate(m_configBitrate), 4096)); if(!startProcess(process, m_binary, args)) { @@ -156,3 +241,8 @@ const unsigned int *DCAEncoder::supportedBitdepths(void) static const unsigned int supportedBPS[] = {16, 32, NULL}; return supportedBPS; } + +const AbstractEncoderInfo *DCAEncoder::getEncoderInfo(void) +{ + return &g_dcaEncoderInfo; +} diff --git a/src/Encoder_DCA.h b/src/Encoder_DCA.h index 6e126d7d..b3f97524 100644 --- a/src/Encoder_DCA.h +++ b/src/Encoder_DCA.h @@ -40,6 +40,9 @@ public: virtual const unsigned int *supportedBitdepths(void); virtual const unsigned int *supportedSamplerates(void); + //Encoder info + static const AbstractEncoderInfo *getEncoderInfo(void); + private: const QString m_binary; int clipBitrate(int bitrate); diff --git a/src/Encoder_FLAC.cpp b/src/Encoder_FLAC.cpp index a16ccc68..eec73576 100644 --- a/src/Encoder_FLAC.cpp +++ b/src/Encoder_FLAC.cpp @@ -27,6 +27,88 @@ #include #include +/////////////////////////////////////////////////////////////////////////////// +// Encoder Info +/////////////////////////////////////////////////////////////////////////////// + +class FLACEncoderInfo : public AbstractEncoderInfo +{ +public: + virtual bool isModeSupported(int mode) const + { + switch(mode) + { + case SettingsModel::VBRMode: + return true; + break; + case SettingsModel::ABRMode: + case SettingsModel::CBRMode: + return false; + break; + default: + throw "Bad RC mode specified!"; + } + } + + virtual int valueCount(int mode) const + { + switch(mode) + { + case SettingsModel::VBRMode: + return 9; + break; + case SettingsModel::ABRMode: + case SettingsModel::CBRMode: + return 0; + break; + default: + throw "Bad RC mode specified!"; + } + } + + virtual int valueAt(int mode, int index) const + { + switch(mode) + { + case SettingsModel::VBRMode: + return qBound(0, index, 8); + break; + case SettingsModel::ABRMode: + case SettingsModel::CBRMode: + return -1; + break; + default: + throw "Bad RC mode specified!"; + } + } + + virtual int valueType(int mode) const + { + switch(mode) + { + case SettingsModel::VBRMode: + return TYPE_COMPRESSION_LEVEL; + break; + case SettingsModel::ABRMode: + case SettingsModel::CBRMode: + return -1; + default: + throw "Bad RC mode specified!"; + } + } + + virtual const char *description(void) const + { + static const char* s_description = "Free Lossless Audio Codec (FLAC)"; + return s_description; + } +} +static const g_flacEncoderInfo; + +/////////////////////////////////////////////////////////////////////////////// +// Encoder implementation +/////////////////////////////////////////////////////////////////////////////// + FLACEncoder::FLACEncoder(void) : m_binary(lamexp_lookup_tool("flac.exe")) @@ -46,7 +128,7 @@ bool FLACEncoder::encode(const QString &sourceFile, const AudioFileModel &metaIn QProcess process; QStringList args; - args << QString("-%1").arg(QString::number(qMax(0, qMin(8, m_configBitrate)))); + args << QString("-%1").arg(QString::number(qBound(0, m_configBitrate, 8))); args << "--channel-map=none"; if(!metaInfo.fileName().isEmpty()) args << "-T" << QString("title=%1").arg(cleanTag(metaInfo.fileName())); @@ -162,3 +244,8 @@ const unsigned int *FLACEncoder::supportedBitdepths(void) static const unsigned int supportedBPS[] = {16, 24, NULL}; return supportedBPS; } + +const AbstractEncoderInfo *FLACEncoder::getEncoderInfo(void) +{ + return &g_flacEncoderInfo; +} diff --git a/src/Encoder_FLAC.h b/src/Encoder_FLAC.h index d2c58423..068e53a4 100644 --- a/src/Encoder_FLAC.h +++ b/src/Encoder_FLAC.h @@ -39,6 +39,9 @@ public: virtual const unsigned int *supportedChannelCount(void); virtual const unsigned int *supportedBitdepths(void); + //Encoder info + static const AbstractEncoderInfo *getEncoderInfo(void); + private: const QString m_binary; }; diff --git a/src/Encoder_MP3.cpp b/src/Encoder_MP3.cpp index f818b75a..16bfcbc1 100644 --- a/src/Encoder_MP3.cpp +++ b/src/Encoder_MP3.cpp @@ -107,9 +107,8 @@ class MP3EncoderInfo : public AbstractEncoderInfo static const char* s_description = "LAME MP3 Encoder"; return s_description; } -}; - -static const MP3EncoderInfo g_mp3EncoderInfo; +} +static const g_mp3EncoderInfo; /////////////////////////////////////////////////////////////////////////////// // Encoder implementation diff --git a/src/Encoder_Opus.cpp b/src/Encoder_Opus.cpp index 94a44fdc..756f9aab 100644 --- a/src/Encoder_Opus.cpp +++ b/src/Encoder_Opus.cpp @@ -97,9 +97,8 @@ class OpusEncoderInfo : public AbstractEncoderInfo static const char* s_description = "Opus-Tools OpusEnc (libopus)"; return s_description; } -}; - -static const OpusEncoderInfo g_opusEncoderInfo; +} +static const g_opusEncoderInfo; /////////////////////////////////////////////////////////////////////////////// // Encoder implementation diff --git a/src/Encoder_Vorbis.cpp b/src/Encoder_Vorbis.cpp index b6024569..e4548239 100644 --- a/src/Encoder_Vorbis.cpp +++ b/src/Encoder_Vorbis.cpp @@ -104,9 +104,8 @@ class VorbisEncoderInfo : public AbstractEncoderInfo static const char* s_description = "OggEnc2 Vorbis Encoder (aoTuV)"; return s_description; } -}; - -static const VorbisEncoderInfo g_vorbisEncoderInfo; +} +static const g_vorbisEncoderInfo; /////////////////////////////////////////////////////////////////////////////// // Encoder implementation diff --git a/src/Encoder_Wave.cpp b/src/Encoder_Wave.cpp index 85531312..bb44673b 100644 --- a/src/Encoder_Wave.cpp +++ b/src/Encoder_Wave.cpp @@ -99,9 +99,8 @@ public: static const char* s_description = "Wave Audio (PCM)"; return s_description; } -}; - -static const WaveEncoderInfo g_waveEncoderInfo; +} +static const g_waveEncoderInfo; /////////////////////////////////////////////////////////////////////////////// // Encoder implementation