1 
2 #include "musepackcodecglobal.h"
3 
4 #include "musepackcodecwidget.h"
5 #include "musepackconversionoptions.h"
6 
7 #include <math.h>
8 
9 #include <QApplication>
10 #include <KLocale>
11 #include <KComboBox>
12 #include <KLineEdit>
13 #include <QLayout>
14 #include <QLabel>
15 #include <QDoubleSpinBox>
16 #include <QGroupBox>
17 #include <QSlider>
18 #include <QCheckBox>
19 
20 
MusePackCodecWidget()21 MusePackCodecWidget::MusePackCodecWidget()
22     : CodecWidget(),
23     currentFormat( "musepack" )
24 {
25     const int fontHeight = QFontMetrics(QApplication::font()).boundingRect("M").size().height();
26 
27     QGridLayout *grid = new QGridLayout( this );
28     grid->setContentsMargins( 0, 0, 0, 0 );
29 
30     // set up preset selection
31 
32     QHBoxLayout *presetBox = new QHBoxLayout();
33     grid->addLayout( presetBox, 0, 0 );
34 
35     QLabel *lPreset = new QLabel( i18n("Preset:"), this );
36     presetBox->addWidget( lPreset );
37     cPreset = new KComboBox( this );
38     cPreset->addItem( i18nc("Backend profile","Telephone") );
39     cPreset->addItem( i18nc("Backend profile","Thumb") );
40     cPreset->addItem( i18nc("Backend profile","Radio") );
41     cPreset->addItem( i18nc("Backend profile","Standard") );
42     cPreset->addItem( i18nc("Backend profile","Extreme") );
43     cPreset->addItem( i18nc("Backend profile","Insane") );
44     cPreset->addItem( i18nc("Backend profile","Braindead") );
45     cPreset->addItem( i18n("User defined") );
46     cPreset->setCurrentIndex( 3 );
47     cPreset->setToolTip( i18n("Either use one of MusePacks's presets or your own settings.") );
48     connect( cPreset, SIGNAL(activated(const QString&)), this, SLOT(presetChanged(const QString&)) );
49     connect( cPreset, SIGNAL(activated(int)), SIGNAL(optionsChanged()) );
50     presetBox->addWidget( cPreset );
51 
52     presetBox->addStretch();
53 
54     // set up user defined options
55 
56     userdefinedBox = new QGroupBox( /*i18n("User defined"),*/ this );
57     grid->addWidget( userdefinedBox, 1, 0 );
58 
59     QVBoxLayout *userdefinedBoxLayout = new QVBoxLayout();
60     userdefinedBox->setLayout( userdefinedBoxLayout );
61 
62     // top box ----------------------------------------
63 
64     QHBoxLayout *userdefinedTopBox = new QHBoxLayout();
65     userdefinedBoxLayout->addLayout( userdefinedTopBox );
66 
67     QLabel *lQuality = new QLabel( i18n("Quality"), userdefinedBox );
68     userdefinedTopBox->addWidget( lQuality );
69 
70     userdefinedTopBox->addSpacing( 0.5*fontHeight );
71 
72     sQuality = new QSlider( Qt::Horizontal, userdefinedBox );
73     sQuality->setRange( 0, 1000 );
74     sQuality->setSingleStep( 100 );
75     sQuality->setValue( 500 );
76     connect( sQuality, SIGNAL(valueChanged(int)), this, SLOT(qualitySliderChanged(int)) );
77     connect( sQuality, SIGNAL(valueChanged(int)), SIGNAL(optionsChanged()) );
78     userdefinedTopBox->addWidget( sQuality );
79     sQuality->setToolTip( i18n("Quality level from %1 to %2 where %2 is the highest quality.\nThe higher the quality, the bigger the file size and vice versa.", 0, 10) );
80 
81     dQuality = new QDoubleSpinBox( userdefinedBox );
82     dQuality->setRange( 0, 10 );
83     dQuality->setSingleStep( 1 );
84     dQuality->setValue( 5 );
85     dQuality->setFixedWidth( dQuality->sizeHint().width() );
86     connect( dQuality, SIGNAL(valueChanged(double)), this, SLOT(qualitySpinBoxChanged(double)) );
87     connect( dQuality, SIGNAL(valueChanged(double)), SIGNAL(optionsChanged()) );
88     userdefinedTopBox->addWidget( dQuality );
89     dQuality->setToolTip( i18n("Quality level from %1 to %2 where %2 is the highest quality.\nThe higher the quality, the bigger the file size and vice versa.", 0, 10) );
90 
91     userdefinedTopBox->addStretch();
92 
93     // cmd arguments box
94 
95     QHBoxLayout *cmdArgumentsBox = new QHBoxLayout();
96     grid->addLayout( cmdArgumentsBox, 2, 0 );
97 
98     cCmdArguments = new QCheckBox( i18n("Additional encoder arguments:"), this );
99     cmdArgumentsBox->addWidget( cCmdArguments );
100     lCmdArguments = new KLineEdit( this );
101     lCmdArguments->setEnabled( false );
102     cmdArgumentsBox->addWidget( lCmdArguments );
103     connect( cCmdArguments, SIGNAL(toggled(bool)), lCmdArguments, SLOT(setEnabled(bool)) );
104 
105     grid->setRowStretch( 3, 1 );
106 
107     presetChanged( cPreset->currentText() );
108 }
109 
~MusePackCodecWidget()110 MusePackCodecWidget::~MusePackCodecWidget()
111 {}
112 
113 // TODO optimize
bitrateForQuality(double quality)114 int MusePackCodecWidget::bitrateForQuality( double quality )
115 {
116     return quality*100/3;
117 }
118 
119 // TODO optimize
qualityForBitrate(int bitrate)120 double MusePackCodecWidget::qualityForBitrate( int bitrate )
121 {
122     return (double)bitrate*3/100;
123 }
124 
currentConversionOptions()125 ConversionOptions *MusePackCodecWidget::currentConversionOptions()
126 {
127     MusePackConversionOptions *options = new MusePackConversionOptions();
128     options->data.preset = (MusePackConversionOptions::Data::Preset)cPreset->currentIndex();
129     options->qualityMode = ConversionOptions::Quality;
130     options->quality = dQuality->value();
131     options->bitrate = bitrateForQuality( options->quality );
132     options->bitrateMode = ConversionOptions::Vbr;
133 
134     return options;
135 }
136 
setCurrentConversionOptions(const ConversionOptions * _options)137 bool MusePackCodecWidget::setCurrentConversionOptions( const ConversionOptions *_options )
138 {
139     if( !_options || _options->pluginName != global_plugin_name ) return false;
140 
141     const MusePackConversionOptions *options = dynamic_cast<const MusePackConversionOptions*>(_options);
142     cPreset->setCurrentIndex( (int)options->data.preset );
143     presetChanged( cPreset->currentText() );
144     dQuality->setValue( options->quality );
145     cCmdArguments->setChecked( !options->cmdArguments.isEmpty() );
146     if( !options->cmdArguments.isEmpty() ) lCmdArguments->setText( options->cmdArguments );
147 
148     return true;
149 }
150 
setCurrentFormat(const QString & format)151 void MusePackCodecWidget::setCurrentFormat( const QString& format )
152 {
153     if( currentFormat == format ) return;
154     currentFormat = format;
155     setEnabled( currentFormat != "wav" );
156 }
157 
currentProfile()158 QString MusePackCodecWidget::currentProfile()
159 {
160     if( currentFormat == "wav" )
161     {
162         return i18n("Lossless");
163     }
164     else if( cPreset->currentIndex() == 7 && dQuality->value() == 3.0 )
165     {
166         return i18n("Very low");
167     }
168     else if( cPreset->currentIndex() == 7 && dQuality->value() == 4.0 )
169     {
170         return i18n("Low");
171     }
172     else if( cPreset->currentIndex() == 7 && dQuality->value() == 5.0 )
173     {
174         return i18n("Medium");
175     }
176     else if( cPreset->currentIndex() == 7 && dQuality->value() == 6.0 )
177     {
178         return i18n("High");
179     }
180     else if( cPreset->currentIndex() == 7 && dQuality->value() == 7.0 )
181     {
182         return i18n("Very high");
183     }
184 
185     return i18n("User defined");
186 }
187 
setCurrentProfile(const QString & profile)188 bool MusePackCodecWidget::setCurrentProfile( const QString& profile )
189 {
190     if( profile == i18n("Very low") )
191     {
192         cPreset->setCurrentIndex( 7 );
193         presetChanged( cPreset->currentText() );
194         sQuality->setValue( 300 );
195         dQuality->setValue( 3.0 );
196         cCmdArguments->setChecked( false );
197         return true;
198     }
199     else if( profile == i18n("Low") )
200     {
201         cPreset->setCurrentIndex( 7 );
202         presetChanged( cPreset->currentText() );
203         sQuality->setValue( 400 );
204         dQuality->setValue( 4.0 );
205         cCmdArguments->setChecked( false );
206         return true;
207     }
208     else if( profile == i18n("Medium") )
209     {
210         cPreset->setCurrentIndex( 7 );
211         presetChanged( cPreset->currentText() );
212         sQuality->setValue( 500 );
213         dQuality->setValue( 5.0 );
214         cCmdArguments->setChecked( false );
215         return true;
216     }
217     else if( profile == i18n("High") )
218     {
219         cPreset->setCurrentIndex( 7 );
220         presetChanged( cPreset->currentText() );
221         sQuality->setValue( 600 );
222         dQuality->setValue( 6.0 );
223         cCmdArguments->setChecked( false );
224         return true;
225     }
226     else if( profile == i18n("Very high") )
227     {
228         cPreset->setCurrentIndex( 7 );
229         presetChanged( cPreset->currentText() );
230         sQuality->setValue( 700 );
231         dQuality->setValue( 7.0 );
232         cCmdArguments->setChecked( false );
233         return true;
234     }
235 
236     return false;
237 }
238 
currentDataRate()239 int MusePackCodecWidget::currentDataRate()
240 {
241     int dataRate;
242 
243     if( currentFormat == "wav" )
244     {
245         dataRate = 10590000;
246     }
247     else
248     {
249 //         dataRate = 500000 + dQuality->value()*150000;
250 //         if( dQuality->value() > 7 ) dataRate += (dQuality->value()-7)*250000;
251 //         if( dQuality->value() > 9 ) dataRate += (dQuality->value()-9)*800000;
252         dataRate = 0;
253     }
254 
255     return dataRate;
256 }
257 
presetChanged(const QString & preset)258 void MusePackCodecWidget::presetChanged( const QString& preset )
259 {
260     cPreset->setToolTip( "" );
261 
262     if( preset == i18nc("Backend profile","Telephone") )
263     {
264         userdefinedBox->setEnabled( false );
265         cPreset->setToolTip( i18n("low quality (~60 kbps abr).") );
266     }
267     else if( preset == i18nc("Backend profile","Thumb") )
268     {
269         userdefinedBox->setEnabled( false );
270         cPreset->setToolTip( i18n("low/medium quality (~90 kbps abr).") );
271     }
272     else if( preset == i18nc("Backend profile","Radio") )
273     {
274         userdefinedBox->setEnabled( false );
275         cPreset->setToolTip( i18n("medium quality (~130 kbps abr).") );
276     }
277     else if( preset == i18nc("Backend profile","Standard") )
278     {
279         userdefinedBox->setEnabled( false );
280         cPreset->setToolTip( i18n("high quality (~180 kbps abr).") );
281     }
282     else if( preset == i18nc("Backend profile","Extreme") )
283     {
284         userdefinedBox->setEnabled( false );
285         cPreset->setToolTip( i18n("excellent quality (~210 kbps abr).") );
286     }
287     else if( preset == i18nc("Backend profile","Insane") )
288     {
289         userdefinedBox->setEnabled( false );
290         cPreset->setToolTip( i18n("excellent quality (~240 kbps abr).") );
291     }
292     else if( preset == i18nc("Backend profile","Braindead") )
293     {
294         userdefinedBox->setEnabled( false );
295         cPreset->setToolTip( i18n("excellent quality (~270 kbps abr).") );
296     }
297     else // "User defined"
298     {
299         userdefinedBox->setEnabled( true );
300     }
301 }
302 
qualitySliderChanged(int quality)303 void MusePackCodecWidget::qualitySliderChanged( int quality )
304 {
305     dQuality->setValue( double(quality)/100.0 );
306 }
307 
qualitySpinBoxChanged(double quality)308 void MusePackCodecWidget::qualitySpinBoxChanged( double quality )
309 {
310     sQuality->setValue( round(quality*100.0) );
311 }
312 
313 
314