File indexing completed on 2024-05-05 04:48:36
0001 /**************************************************************************************** 0002 * Copyright (c) 2004 Frederik Holljen <fh@ez.no> * 0003 * Copyright (c) 2004,2005 Max Howell <max.howell@methylblue.com> * 0004 * Copyright (c) 2004-2013 Mark Kretschmann <kretschmann@kde.org> * 0005 * Copyright (c) 2006,2008 Ian Monroe <ian@monroe.nu> * 0006 * Copyright (c) 2008 Jason A. Donenfeld <Jason@zx2c4.com> * 0007 * Copyright (c) 2009 Nikolaj Hald Nielsen <nhn@kde.org> * 0008 * Copyright (c) 2009 Artur Szymiec <artur.szymiec@gmail.com> * 0009 * Copyright (c) 2013 Anmol Ahuja <darthcodus@gmail.com> * 0010 * * 0011 * This program is free software; you can redistribute it and/or modify it under * 0012 * the terms of the GNU General Public License as published by the Free Software * 0013 * Foundation; either version 2 of the License, or (at your option) any later * 0014 * version. * 0015 * * 0016 * This program is distributed in the hope that it will be useful, but WITHOUT ANY * 0017 * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A * 0018 * PARTICULAR PURPOSE. See the GNU General Public License for more details. * 0019 * * 0020 * You should have received a copy of the GNU General Public License along with * 0021 * this program. If not, see <http://www.gnu.org/licenses/>. * 0022 ****************************************************************************************/ 0023 0024 #define DEBUG_PREFIX "EqualizerController" 0025 0026 #include "playback/EqualizerController.h" 0027 0028 #include "amarokconfig.h" 0029 #include "core/support/Debug.h" 0030 #include "equalizer/EqualizerPresets.h" 0031 0032 #include <KLocalizedString> 0033 0034 #include <phonon/BackendCapabilities> 0035 #include <phonon/EffectParameter> 0036 0037 EqualizerController::EqualizerController( QObject *object ) 0038 : QObject( object ) 0039 {} 0040 0041 EqualizerController::~EqualizerController() 0042 {} 0043 0044 ////////////////////////////////////////////////////////////////////////////////////////// 0045 // PUBLIC 0046 ////////////////////////////////////////////////////////////////////////////////////////// 0047 0048 void 0049 EqualizerController::initialize( const Phonon::Path &path ) 0050 { 0051 DEBUG_BLOCK 0052 m_path = path; 0053 delete m_equalizer.data(); 0054 0055 using namespace Phonon; 0056 0057 // Add an equalizer effect if available 0058 const QList<EffectDescription> effects = BackendCapabilities::availableAudioEffects(); 0059 QRegExp equalizerRegExp( QStringLiteral( "equalizer.*%1.*bands" ).arg( s_equalizerBandsNum ), 0060 Qt::CaseInsensitive ); 0061 foreach( const EffectDescription &description, effects ) 0062 { 0063 if( !description.name().contains( equalizerRegExp ) ) 0064 continue; 0065 0066 QScopedPointer<Effect> equalizer( new Effect( description, this ) ); 0067 int parameterCount = equalizer->parameters().count(); 0068 if( parameterCount == s_equalizerBandsNum || parameterCount == s_equalizerBandsNum + 1 ) 0069 { 0070 debug() << "Established Phonon equalizer effect with" << parameterCount 0071 << "parameters."; 0072 m_equalizer = equalizer.take(); // accept the effect 0073 eqUpdate(); 0074 break; 0075 } 0076 else 0077 { 0078 QStringList paramNames; 0079 foreach( const EffectParameter ¶m, equalizer->parameters() ) 0080 paramNames << param.name(); 0081 warning() << "Phonon equalizer effect" << description.name() << "with description" 0082 << description.description() << "has" << parameterCount << "parameters (" 0083 << paramNames << ") - which is unexpected. Trying other effects."; 0084 } 0085 } 0086 } 0087 0088 ////////////////////////////////////////////////////////////////////////////////////////// 0089 // PUBLIC 0090 ////////////////////////////////////////////////////////////////////////////////////////// 0091 0092 bool 0093 EqualizerController::isEqSupported() const 0094 { 0095 // If effect was created it means we have equalizer support 0096 return m_equalizer; 0097 } 0098 0099 double 0100 EqualizerController::eqMaxGain() const 0101 { 0102 if( !m_equalizer ) 0103 return 100; 0104 QList<Phonon::EffectParameter> equalizerParameters = m_equalizer->parameters(); 0105 if( equalizerParameters.isEmpty() ) 0106 return 100.0; 0107 double mScale; 0108 mScale = ( qAbs(equalizerParameters.at(0).maximumValue().toDouble() ) 0109 + qAbs( equalizerParameters.at(0).minimumValue().toDouble() ) ); 0110 mScale /= 2.0; 0111 return mScale; 0112 } 0113 0114 QStringList 0115 EqualizerController::eqBandsFreq() const 0116 { 0117 // This will extract the bands frequency values from effect parameter name 0118 // as long as they follow the rules: 0119 // eq-preamp parameter will contain 'pre-amp' string 0120 // bands parameters are described using schema 'xxxHz' 0121 QStringList bandFrequencies; 0122 if( !m_equalizer ) 0123 return bandFrequencies; 0124 QList<Phonon::EffectParameter> equalizerParameters = m_equalizer->parameters(); 0125 if( equalizerParameters.isEmpty() ) 0126 return bandFrequencies; 0127 QRegExp rx( "\\d+(?=Hz)" ); 0128 foreach( const Phonon::EffectParameter &mParam, equalizerParameters ) 0129 { 0130 if( mParam.name().contains( rx ) ) 0131 { 0132 if( rx.cap( 0 ).toInt() < 1000 ) 0133 bandFrequencies << i18n( "%0\nHz" ).arg( rx.cap( 0 ) ); 0134 else 0135 bandFrequencies << i18n( "%0\nkHz" ).arg( QString::number( rx.cap( 0 ).toInt()/1000 ) ); 0136 } 0137 else 0138 bandFrequencies << mParam.name(); 0139 } 0140 return bandFrequencies; 0141 } 0142 0143 void 0144 EqualizerController::eqUpdate() 0145 { 0146 DEBUG_BLOCK 0147 // if equalizer not present simply return 0148 if( !m_equalizer ) 0149 return; 0150 // check if equalizer should be disabled ?? 0151 QList<int> equalizerParametersCfg; 0152 if( AmarokConfig::equalizerMode() <= 0 ) 0153 { 0154 // Remove effect from path 0155 if( m_path.effects().indexOf( m_equalizer.data() ) != -1 ) 0156 m_path.removeEffect( m_equalizer.data() ); 0157 } 0158 else 0159 { 0160 // Set equalizer parameter according to the gains from settings 0161 QList<Phonon::EffectParameter> equalizerParameters = m_equalizer->parameters(); 0162 equalizerParametersCfg = AmarokConfig::equalizerGains(); 0163 0164 QListIterator<int> equalizerParametersIt( equalizerParametersCfg ); 0165 double scaledVal; // Scaled value to set from universal -100 - 100 range to plugin scale 0166 // Checking if preamp is present in equalizer parameters 0167 if( equalizerParameters.size() == s_equalizerBandsNum ) 0168 { 0169 // If pre-amp is not present then skip the first element of equalizer gain 0170 if( equalizerParametersIt.hasNext() ) 0171 equalizerParametersIt.next(); 0172 } 0173 foreach( const Phonon::EffectParameter &mParam, equalizerParameters ) 0174 { 0175 scaledVal = equalizerParametersIt.hasNext() ? equalizerParametersIt.next() : 0; 0176 scaledVal *= qAbs(mParam.maximumValue().toDouble() ) 0177 + qAbs( mParam.minimumValue().toDouble() ); 0178 scaledVal /= 200.0; 0179 m_equalizer->setParameterValue( mParam, scaledVal ); 0180 } 0181 // Insert effect into path if needed 0182 if( m_path.effects().indexOf( m_equalizer.data() ) == -1 ) 0183 { 0184 if( !m_path.effects().isEmpty() ) 0185 { 0186 m_path.insertEffect( m_equalizer.data(), m_path.effects().first() ); 0187 } 0188 else 0189 { 0190 m_path.insertEffect( m_equalizer.data() ); 0191 } 0192 } 0193 } 0194 Q_EMIT gainsChanged( equalizerParametersCfg ); 0195 } 0196 0197 QString 0198 EqualizerController::equalizerPreset() const 0199 { 0200 int index = AmarokConfig::equalizerMode() - 1; 0201 if( index > 0 ) 0202 return EqualizerPresets::eqGlobalList()[index]; 0203 else 0204 return QString(); 0205 } 0206 0207 void 0208 EqualizerController::applyEqualizerPresetByIndex( int index ) 0209 { 0210 if( index > -1 ) 0211 { 0212 AmarokConfig::setEqualizerMode( index + 1 ); 0213 AmarokConfig::setEqualizerGains( EqualizerPresets::eqCfgGetPresetVal( EqualizerPresets::eqGlobalTranslatedList().value( index ) ) ); 0214 } 0215 else 0216 AmarokConfig::setEqualizerMode( 0 ); 0217 0218 eqUpdate(); 0219 Q_EMIT presetApplied( index ); 0220 } 0221 0222 void 0223 EqualizerController::applyEqualizerPresetByName( const QString &name ) 0224 { 0225 DEBUG_BLOCK 0226 const int index = EqualizerPresets::eqGlobalTranslatedList().indexOf( name ); 0227 applyEqualizerPresetByIndex( index > 0 ? index : 0 ); 0228 } 0229 0230 void 0231 EqualizerController::savePreset( const QString &name, const QList<int> &gains ) 0232 { 0233 EqualizerPresets::eqCfgSetPresetVal( name, gains ); 0234 Q_EMIT presetsChanged( name ); 0235 } 0236 0237 bool 0238 EqualizerController::deletePreset( const QString &name ) 0239 { 0240 if( !EqualizerPresets::eqCfgDeletePreset( name ) ) 0241 return false; 0242 0243 Q_EMIT presetsChanged( name ); 0244 return true; 0245 } 0246 0247 void 0248 EqualizerController::setGains( const QList<int> &gains ) 0249 { 0250 AmarokConfig::setEqualizerGains( gains ); 0251 eqUpdate(); 0252 } 0253 0254 QList<int> 0255 EqualizerController::gains() const 0256 { 0257 return AmarokConfig::equalizerGains(); 0258 } 0259 0260 bool 0261 EqualizerController::enabled() 0262 { 0263 return AmarokConfig::equalizerMode() > 0; 0264 }